Skip to content

fix: reject out-of-range integers on write and search instead of silently truncating - #52

Merged
JeanExtreme002 merged 4 commits into
mainfrom
jeanextreme002/fix-silent-integer-overflow
Jun 5, 2026
Merged

JeanExtreme002 merged 4 commits into
mainfrom
jeanextreme002/fix-silent-integer-overflow

Conversation

@JeanExtreme002

Copy link
Copy Markdown
Owner

Summary

A fixed-width ctypes integer setter silently wraps an out-of-range value
(e.g. 2**40 into a 4-byte slot stores 0). As a result:

  • write_int(addr, 2**40) reported success while actually writing 0 —
    silent corruption of the target's memory.
  • search_by_value(int, value=2**40) encoded the target as 0 and quietly
    matched every zeroed slot in memory instead of erroring.
  • The unsigned write helpers (write_uint, …) raised, but with int.to_bytes'
    cryptic OverflowError ("int too big to convert") instead of a clear error.

This adds a single range check (_check_int_fits) applied at every numeric
coercion point
, so an out-of-range integer fails fast with an actionable
ValueError everywhere:

Coercion point Path
prepare_write signed / generic write (write_int, write_short, …)
AbstractProcess._write_unsigned unsigned helpers (write_uint, …)
value_to_bytes search-target encoder (search_by_value / _between)
RemotePointer.value setter inherited via write_process_memory

The accepted window is the union of the signed and unsigned ranges for the
requested width, so a value in either representation stays valid (0xFFFFFFFF
in a 4-byte field is the bit pattern of -1); only values that genuinely
cannot be encoded in that width are rejected.

Also included

  • Regression tests for every path above, plus a test pinning that a write
    to an unmapped address still raises OSError.
  • NOT_VALUE_BETWEEN scan coverage (typed-int fast path + bytewise
    fallback), which previously had implementations but no test.
  • Functional tests for the Qt app's value_types parse/format layer and
    the CheatEntry JSON round-trip (previously untested pure logic).
  • CONTRIBUTING: route the dev commands through the existing Makefile targets
    and fix the stale note claiming macOS is excluded from CI.

Testing

Full suite green, including the slow self-process integration tests:
428 passed, flake8 clean, mypy PyMemoryEditor clean.

A fixed-width ctypes integer setter silently wraps an out-of-range value
(e.g. 2**40 into a 4-byte slot stores 0), so write_int(addr, 2**40) used to
report success while writing 0, and search_by_value(int, value=2**40) used to
encode the target as 0 and quietly match every zeroed slot.

Add _check_int_fits() and apply it at every numeric coercion point:
  - prepare_write (signed/generic write path),
  - AbstractProcess._write_unsigned (unsigned helpers; replaces int.to_bytes'
    cryptic OverflowError with the same clear ValueError),
  - value_to_bytes (search-target encoder).

The accepted window is the union of the signed and unsigned ranges for the
requested width, so values in either representation (0xFFFFFFFF == -1 for a
4-byte field) stay valid; only values that genuinely cannot be encoded are
rejected. Also pins that a write to an unmapped address still raises OSError.
The NOT_VALUE_BETWEEN comparison had implementations on both the typed-int
fast path and the bytewise fallback but no test. Add cases for both, including
a signed negative endpoint, equivalent under the NumPy and pure-Python paths.
value_types (the scanner-panel parse/format layer) and CheatEntry's JSON
round-trip were untested pure logic. Cover parsing/length-inference for every
value type and the cheat-table serialization contract, without constructing
the polling-thread widgets that make UI teardown flaky.
Point setup/test/lint/type-check at the existing make targets (single source
of truth) and add a "before you push" note for `make pre-commit`. Also fix the
stale claim that macOS is excluded from CI — the matrix runs it.
@github-actions github-actions Bot added lib Library changes (PyMemoryEditor/) tests Test changes (tests/) labels Jun 5, 2026
@JeanExtreme002
JeanExtreme002 merged commit dc66d9f into main Jun 5, 2026
17 checks passed
@github-actions
github-actions Bot deleted the jeanextreme002/fix-silent-integer-overflow branch June 5, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lib Library changes (PyMemoryEditor/) tests Test changes (tests/)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant