Repository navigation
fix(fields): raise ProtocolError for a NumberField negative resolved length (#828) - #829
Conversation
…length (#828) `NumberField.__call__` cached `self._bit_length = self._length * 8` and then computed `1 << self._bit_length` whenever `bit_length` was not supplied. A `length` callback resolving below zero -- the real shape at `pcapkit/protocols/schema/internet/hip.py:734`, `NumberField(length=lambda pkt: pkt['len'] - 4, signed=False)` against a wire `len` under 4 -- raised a bare `ValueError: negative shift count`: not one of `pcapkit.utilities.exceptions`, and raised before `FieldBase.length`'s own `ProtocolError` guard (#805/#811/#827) or `build_template` ever saw the value, since the shift happens several lines earlier. Guard the resolved length in `__call__` itself, right before the shift, and raise `ProtocolError` naming the field and the resolved value, worded as a sibling of `FieldBase.length`'s own message. No sibling field type (`strings`, `misc`, `collections`) performs this eager shift, so the guard stays local to `NumberField` rather than moving into a shared helper. A resolved length of exactly 0 remains legal and is left untouched. Adds `tests/corekit/test_fields_numbers_negative_length.py`: a literal negative length, the real `lambda pkt: pkt['len'] - 4` callable shape, the zero-length boundary, and a positive-length control. `coverage run -m pytest` on `numbers.py` stays at 100% (140->142 statements, 40->42 branches). Closes #828
|
Cross-review verdict: GOOD TO GO (haiku; author was sonnet). The guard is sound, and the review refutes the author's supporting argument — which I reproduced. There is a second, unguarded shift in the same file. The author argued That is exactly the #828 defect shape surviving this PR. Not a blocker: Also latent, and I confirmed the surprising half — a field supplying The guard itself cannot be bypassed for the shift it protects. The reviewer enumerated the whole condition space, and I confirmed no A reason for Two corrections to the record: the stock crash is at On over-pinning, contra my own worry: the tests are if anything too loose. They pin only the substring Coverage independently confirmed at 142 statements / 42 branches / 0 missed / 100%, measured with a distinct |
Please follow the guide below
make pylint,make mypy,make isort)make testpasses, and a test case covers the change — did not run the full suite (it OOMs on this host); ran the scopedtests/corekit/+ HIP protocol unit tests instead (see below), and a new test case covers the changedocs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A, changelog centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingchore— anything elseDescription of your pull request and other information
Closes #828
NumberField.__call__cachedbit_length = length * 8and shifted1 << bit_lengthbeforeFieldBase.length's own negative-length guard (#805/#811/#827) orbuild_templateever saw the value. Alengthcallback resolving below zero — e.g.NumberField(length=lambda pkt: pkt['len'] - 4, signed=False)athip.py:734, against a truncated wirelen— raised a bare, uncatchableValueError: negative shift count.Guards the resolved length in
__call__, before the shift, raisingProtocolErrorworded as a sibling ofFieldBase.length's message. No sibling field type (strings/misc/collections) does this eager shift, so the guard stays local toNumberField. A resolved length of exactly0is untouched and still succeeds.Adds
tests/corekit/test_fields_numbers_negative_length.py, verified failing on stockmainwith the reportedValueErrorand passing after the fix. Rantests/corekit/(226 tests) and the HIP protocol unit tests (44 tests) via plainunittest, all passing.coverage run -m pytestonnumbers.pystays at 100% (140→142 stmts, 40→42 branches).