fix(advice): make the id helper unusable rather than merely rejected

_as_doc_id returned None for a hostile id.  That was guarded at the one
call site, but the helper could still be misused into "$in needs an
array" - and a caller who forgot the guard would have got an error
rather than a safe no-op.

It now returns an EMPTY LIST for anything that is not a reading id.  An
empty list is a valid $in argument that matches nothing, so the helper
cannot produce a query error, cannot match every document, and cannot be
interpreted as a query operator.

Verified against the live database: a hostile id matches 0 documents and
updates 0 documents.

164 tests.
This commit is contained in:
2026-11-09 16:31:05 +10:00
parent 6dd0b7b046
commit 21fa0d9a12
2 changed files with 14 additions and 2 deletions
+8
View File
@@ -414,6 +414,14 @@ def test_the_reading_id_cannot_be_used_to_inject_a_query(repo):
modified = repo.set_reading_advice(hostile, "INJECTED", True)
assert modified == 0, f"{hostile!r} matched something"
# The helper itself must return something that is safe to put in a
# query - an empty list matches nothing. Returning None would raise
# "$in needs an array" if it were ever used without a guard.
from mongo.repository import _as_doc_id
for hostile in [{"$ne": None}, {"$gt": ""}, ["a"], 123, None, ""]:
assert _as_doc_id(hostile) == [], f"{hostile!r} produced a usable id"
# And no document was touched.
for doc in repo.readings.find({}):
assert doc.get("advice") is None