Commit 0b234df
Fix off-by-one in exception-table emit_item at bit-24 boundary (#124)
Summary:
`ExceptionTable.emit_item` in `compiler/pyassem.py` packs a value 6 bits at a time. The three lower group thresholds use `>=`, but the top group used `>`:
```python
if value > (1 << 24): # <- bug: should be >=
self.write_byte((value >> 24) | CONTINUATION_BIT | msb)
msb = 0
for i in (18, 12, 6):
if value >= (1 << i): # the other thresholds use >=
...
```
At exactly `value == 1 << 24` (16777216) the leading 6-bit group is skipped, so the value is emitted as `40 40 40 00` and decodes back to **0** — a corrupt exception-table entry. Values one below/above encode fine, so it is a precise boundary bug.
This mirrors CPythons `assemble_emit_exception_table_item` in `Python/assemble.c`, which uses `value >= 1 << 24`. The inconsistency within the same function (one `>`, three `>=`) is the tell.
### Impact
`emit_item` is fed block `start`/`size`/`target` byte-offsets and `depth_lasti` via `emit_entry`, so any of those equal to `16777216` yields a table entry that points at offset 0.
### Fix
Use `>=`, matching the other thresholds and CPython. One character.
### Tests
Added round-trip tests to `test_exception_table.py` over all four group boundaries `(1<<i)-1, 1<<i, (1<<i)+1` for `i in {6,12,18,24}` plus `0/1/(1<<30)-1`. Verified the suite fails only at `16777216` before the fix and passes after:
```
BUG(>): failing values = [16777216]
FIX(>=): failing values = []
```
Pull Request resolved: #124
Reviewed By: yoney
Differential Revision: D110795289
Pulled By: alexmalyshev
fbshipit-source-id: 4306347afe8dfcb6fca966cddb1918255146683e1 parent 52458db commit 0b234df
2 files changed
Lines changed: 33 additions & 1 deletion
File tree
- cinderx/PythonLib
- cinderx/compiler
- test_cinderx/test_compiler
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3661 | 3661 | | |
3662 | 3662 | | |
3663 | 3663 | | |
3664 | | - | |
| 3664 | + | |
3665 | 3665 | | |
3666 | 3666 | | |
3667 | 3667 | | |
| |||
Lines changed: 32 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
0 commit comments