fix(r3): a NUL in the raw file path is a 404, not a 500
Compare's stages load their pictures through the catch-all file route, which
caught only OSError around resolve(); an embedded NUL raises ValueError. Same
class as resolve_booth's fix in f8d136a (heid bug hunt on the race fix,
hulda). The upload route's NUL-in-filename 500 is the same class and is left
to booth-dev: it is not on compare's path.
This commit is contained in:
+3
-1
@@ -2148,7 +2148,9 @@ def create_app(
|
|||||||
booth = resolve_booth(name)
|
booth = resolve_booth(name)
|
||||||
try:
|
try:
|
||||||
target = (booth / filepath).resolve()
|
target = (booth / filepath).resolve()
|
||||||
except OSError:
|
except (OSError, ValueError):
|
||||||
|
# ValueError: an embedded NUL (`/b/g/p%00.png`) is not an OSError,
|
||||||
|
# and hostile input is a 404, never a 500 (r3 heid bug hunt)
|
||||||
raise HTTPException(status_code=404, detail="no such file")
|
raise HTTPException(status_code=404, detail="no such file")
|
||||||
if not str(target).startswith(str(booth) + os.sep) or not target.is_file():
|
if not str(target).startswith(str(booth) + os.sep) or not target.is_file():
|
||||||
raise HTTPException(status_code=404, detail="no such file")
|
raise HTTPException(status_code=404, detail="no such file")
|
||||||
|
|||||||
@@ -567,6 +567,17 @@ new = '''
|
|||||||
if True:
|
if True:
|
||||||
partner'''
|
partner'''
|
||||||
|
|
||||||
|
[[mutation]]
|
||||||
|
label = "a NUL in the raw file path is a 500 (the stages load through this route)"
|
||||||
|
file = "booth/app.py"
|
||||||
|
test = "tests/test_compare.py::test_a_nul_in_a_file_path_is_404_not_500"
|
||||||
|
old = '''
|
||||||
|
target = (booth / filepath).resolve()
|
||||||
|
except (OSError, ValueError):'''
|
||||||
|
new = '''
|
||||||
|
target = (booth / filepath).resolve()
|
||||||
|
except OSError:'''
|
||||||
|
|
||||||
# Refuted, not rowed (bug hunt): "a right-click mid-drag ends the pan" — a
|
# Refuted, not rowed (bug hunt): "a right-click mid-drag ends the pan" — a
|
||||||
# second button pressed and released during a drag arrives as chorded
|
# second button pressed and released during a drag arrives as chorded
|
||||||
# `pointermove` events, never a `pointerup` (measured 3/3 in the test browser,
|
# `pointermove` events, never a `pointerup` (measured 3/3 in the test browser,
|
||||||
|
|||||||
@@ -150,6 +150,16 @@ def test_hostile_booth_names_are_404_not_500(tmp_path):
|
|||||||
assert c.get(path).status_code == 404, path
|
assert c.get(path).status_code == 404, path
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_nul_in_a_file_path_is_404_not_500(tmp_path):
|
||||||
|
"""Compare's stages load their pictures through the raw file route. A NUL
|
||||||
|
in that path segment raises ValueError from resolve(), which is not an
|
||||||
|
OSError: still a 404 (heid bug hunt on the race fix, hulda)."""
|
||||||
|
_four(tmp_path)
|
||||||
|
c = _client(tmp_path)
|
||||||
|
for path in ("/b/g/p%00.png", "/b/g/p.png%00?thumb=1", "/b/g/sub%00/p.png?dl=1"):
|
||||||
|
assert c.get(path).status_code == 404, path
|
||||||
|
|
||||||
|
|
||||||
def test_a_planted_fifo_marker_cannot_hang_a_look(tmp_path):
|
def test_a_planted_fifo_marker_cannot_hang_a_look(tmp_path):
|
||||||
"""Recording a look never costs the page: a FIFO planted at `.viewed` must
|
"""Recording a look never costs the page: a FIFO planted at `.viewed` must
|
||||||
not block the open that touches it (heid bug hunt, hulda)."""
|
not block the open that touches it (heid bug hunt, hulda)."""
|
||||||
|
|||||||
Reference in New Issue
Block a user