fix(downloads): cap the media filename by BYTES, not characters
/code-review (S1, finding 1): sanitize truncated the title at 120 CHARACTERS, but a
path component's hard limit is 255 BYTES and rel_path packs channel + date + id + ext
into that same component — so a long accented/multi-byte title (Hungarian titles are
common here) could already overflow to ENAMETOOLONG, and the new _a{id} suffix shrank
the margin further. sanitize now truncates on a UTF-8 boundary by byte length, so the
title (≤120B) + channel (≤80B) + fixed parts stay comfortably under 255B. Two tests:
byte-cap on accented input, and every rel_path component ≤255B for a pathological
long-accented channel+title+asset_id.
This commit is contained in:
@@ -58,8 +58,12 @@ def sanitize(name: str, limit: int = _MAX_TITLE) -> str:
|
||||
text = re.sub(r"\s+", "_", text.strip())
|
||||
# Tidy separator pile-ups and trim junk from the ends.
|
||||
text = re.sub(r"_{2,}", "_", text).strip("_.-·—–|,;:!?ّ ")
|
||||
if len(text) > limit:
|
||||
text = text[:limit].rstrip("_.-")
|
||||
# Cap by BYTES, not characters: a path component's hard limit is 255 BYTES, and rel_path packs
|
||||
# the (byte-capped) channel + date + id + ext into that same component — so an accented/multi-byte
|
||||
# title capped only by char count could still overflow to ENAMETOOLONG. Truncate on a UTF-8
|
||||
# boundary (decode(..., "ignore") drops a trailing partial char) so we never split a character.
|
||||
if len(text.encode("utf-8")) > limit:
|
||||
text = text.encode("utf-8")[:limit].decode("utf-8", "ignore").rstrip("_.-")
|
||||
return text or "untitled"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user