jw-search / backend /scene_processing /path_safety.py
jw-tools's picture
deploy: latest main (lazy-ML cold start, durable launcher, web-image search, scene search) + full-app data refresh
7ea1851 verified
Raw
History Blame Contribute Delete
1.46 kB
"""
ID validators for path-building in the scene pipeline.
Lives in its own leaf module so the validators can be imported (and
tested) without dragging in the rest of the pipeline (which pulls in
ffmpeg helpers, imagehash, transformers, etc.).
"""
from __future__ import annotations
import re
# JW.org natural keys are letters/digits/underscore/hyphen/period; language
# codes are letters only. Anything outside these regexes is rejected before
# os.path.join sees it, blocking traversal via ``..`` or absolute paths.
#
# The ID pattern additionally requires the first character to be alphanumeric
# or underscore so a sneaky ``..`` or ``-foo`` is rejected even though dot
# and hyphen are allowed mid-identifier.
_SAFE_ID_PATTERN = re.compile(r"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$")
_SAFE_LANG_PATTERN = re.compile(r"^[A-Za-z]{1,8}$")
def require_safe_id(name: str, value: str) -> str:
if (
not isinstance(value, str)
or not _SAFE_ID_PATTERN.match(value)
or ".." in value
):
raise ValueError(
f"Refusing unsafe {name}={value!r}: must match {_SAFE_ID_PATTERN.pattern} "
f"and contain no '..'"
)
return value
def require_safe_language(value: str) -> str:
if not isinstance(value, str) or not _SAFE_LANG_PATTERN.match(value):
raise ValueError(
f"Refusing unsafe language={value!r}: must match {_SAFE_LANG_PATTERN.pattern}"
)
return value