fix(local): reject negative array indices in json path - #1340
fix(local): reject negative array indices in json path#1340shashvat-singham wants to merge 1 commit into
Conversation
qdrant core parses a bracket index with `digit1` mapped to `usize`, so `a[-1]` is a parse error. Local mode used `int()`, which accepts a sign, underscore separators and surrounding whitespace, and the downstream `index < len(data)` bounds checks then let the negative index through to Python's own wrap-around indexing. As a result `value_by_key` and `set_value_by_key` silently addressed elements from the end of the list, and a negative index past the start leaked a raw IndexError out of the filter. Validate the index against the same grammar as core instead. The existing "Negative indexation is not supported" test could not catch this: `assert False` raises AssertionError, which its own `except Exception` swallowed. Switch that region to `pytest.raises`.
✅ Deploy Preview for poetic-froyo-8baba7 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe JSON path parser now accepts only unsigned ASCII digits for array indices. It rejects signs, whitespace, underscores, non-ASCII digits, and malformed brackets with Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This localized change rejects invalid negative and non-core array indices while preserving valid JSON paths, with regression coverage added; no actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What & why
In local mode a json path like
a[-1]is accepted and silently resolves to the last element of the array, and a negative index past the start leaks a rawIndexErrorout of the filter.Qdrant core parses a bracket index with
digit1mapped tousize, so a negative index is a parse error there:Local mode used
int(), which additionally accepts a sign, underscore separators and surrounding whitespace. The downstream bounds checks are written ascurrent_key.index < len(data), which assume a non-negative index, so a negative one passes straight through to Python's own wrap-around indexing.Reproduction on
dev:So both the read path (
value_by_key, and therefore filters andcount) and the write path (set_value_by_key, and thereforeset_payload) are affected.The fix
Validate the bracket contents against the same grammar as core in
_match_brackets, rather than deferring toint(). That is a single-point fix: with the index guaranteed non-negative, the existingindex < len(data)checks become sound again, so no call site needed changing.isascii()is part of the check becausestr.isdigit()is also true for characters like²and٣, whichdigit1does not accept.A note on the existing test
test_set_value_by_keyalready asserted this behaviour:It could never fail:
assert FalseraisesAssertionError, which its ownexcept Exceptionthen swallowed. Meanwhile the payload was being mutated. I switched that whole# region exceptionsblock topytest.raises(ValueError)so the intent is actually enforced — happy to split that into its own PR if you would rather keep this one to the parser change.Tests
Added regression coverage to
test_parse_json_path,test_value_by_keyandtest_set_value_by_key. All three fail ondevwithout the parser change and pass with it.ruff-format --line-length=99andmypyare clean on the changed files.tests/test_local_persistence.pyhas 4 failures on my machine both with and without this change (WindowsPermissionErroron tempfile cleanup), so they are unrelated.All Submissions:
devbranch. Did you create your branch fromdev?Changes to Core Features: