Skip to content

check_in_media silently drops files whose names contain glob metacharacters ([ ] * ?) #286

Description

@OneSixForensics

check_in_media fails to resolve files whose names contain glob metacharacters ([, ], *, ?)

Summary

check_in_media() (in scripts/ilapfuncs.py) resolves the target file by glob-matching it against files_found:

extraction_path = next(
    (path for path in files_found if Path(path).match(file_path)), None)

pathlib.Path.match treats [, ], *, and ? as glob syntax. Real-world media filenames routinely contain these characters — e.g. browser/cloud downloads named IMG_0347[1].jpg, photo[2].png, [clips4sale.com]video.wmv. For such a file, Path(path).match("…IMG_0347[1].jpg") reads [1] as the character class “1”, so it never matches the literal …[1].jpg on disk. The lookup returns None, file_info is None, and the function logs:

No matching file found for "…/IMG_0347[1].jpg"

The media is then not registered at all — no media item, no reference, nothing inline in HTML or LAVA. A module that calls check_in_media for every file in, say, a device backup silently drops every file with a bracket in its name.

Impact

  • Silent media loss for any filename containing [ ] * ?. These are common (the [n] duplicate-download suffix alone is pervasive).
  • Performance: the next(... Path(path).match ...) scan is O(n) per call → O(n²) per artifact. On a large media artifact (tens of thousands of files) this also takes minutes.

Reproducer

from pathlib import Path
files_found = [r"C:\out\data\dev\IMG_0347[1].jpg"]
target      = r"C:\out\data\dev\IMG_0347[1].jpg"
print(next((p for p in files_found if Path(p).match(target)), None))
# -> None   (expected: the path itself)

Suggested fix

The caller already has the exact path, and the seeker indexes files by exact key in seeker.file_infos. Resolve by exact lookup instead of glob — correct for any filename and O(1):

file_info = seeker.file_infos.get(file_path)
if file_info is None:
    # optional: fall back to the existing glob behavior for callers that
    # genuinely pass a pattern rather than an exact files_found entry
    extraction_path = next(
        (p for p in files_found if Path(p).match(file_path)), None)
    file_info = seeker.file_infos.get(extraction_path)

If some callers rely on passing a partial/pattern path, glob.escape(file_path) before matching would at least stop literal [ ] * ? from being interpreted as glob.

Context

Hit while bringing a 17k-file Synchronoss VZMOBILE device-backup artifact into LAVA (parser PR #284); worked around in that parser with an exact-lookup helper, but the underlying issue affects any module using check_in_media.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions