pydantic/monty · info
masked below 2**16
Error message
masked below 2**16
What it means
Internal `expect` in `binascii.crc_hqx` argument handling: the 32-bit seed is masked with `0xffff` before `u16::try_from`, so the conversion cannot fail — the mask guarantees the value is below 2**16. This documents the narrowing invariant; Python callers cannot cause it to panic regardless of the `crc` seed they pass.
Solutions
- No runtime action; if it fires, verify the `& 0xffff` mask was not dropped during a refactor.
Defensive patterns
Strategy: validation
Prevention
- Always mask seeds to the register width before narrowing conversions in checksum code.
When it happens
Trigger: Unreachable via `binascii.crc_hqx(data, crc)`; any int, bool, or arbitrary-precision int seed is reduced by `wrapping_u32` and masked first.
Common situations: Only a concern for contributors changing the seed handling order (e.g. removing the `& 0xffff` mask).
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot get identity of Dereferenced object
- Dereferenced found while converting to MontyObject
- dict_keys view must always reference a dict
- dict view must always reference a dict
- entry just allocated
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/cce380334edfb40d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/monty/src/modules/binascii.rs:227
// 2**32 rather than rejecting one out of range.
let seed = match crc {
None => 0,
Some(value) => wrapping_u32(value, vm)?,
};
let checksum = crc32(encode_input(data, vm)?.as_ref(), seed);
Ok(Value::Int(i64::from(checksum)))
}
/// `binascii.crc_hqx(data, crc)` — the CRC-16 the classic BinHex format used,
/// resumable through `crc` exactly as `crc32` is.
fn call_crc_hqx(vm: &mut VM<'_>, args: ArgValues) -> RunResult<Value> {
let CrcHqxArgs { data, crc } = CrcHqxArgs::from_args(args, vm)?;
defer_drop!(data, vm);
defer_drop!(crc, vm);
// The `I` format takes the seed modulo 2**32, then the body narrows it to
// the 16 bits the register holds — so `-1` and `0xffff` seed alike.
let seed = u16::try_from(wrapping_u32(crc, vm)? & 0xffff).expect("masked below 2**16");
let checksum = crc_hqx(encode_input(data, vm)?.as_ref(), seed);
Ok(Value::Int(i64::from(checksum)))
}
/// `binascii.b2a_uu(data, *, backtick=False)` — one uuencoded line, newline
/// included, for at most the 45 bytes the line-length byte can describe.
fn call_b2a_uu(vm: &mut VM<'_>, args: ArgValues) -> RunResult<Value> {
let B2aUuArgs { data, backtick } = B2aUuArgs::from_args(args, vm)?;
defer_drop!(data, vm);
defer_drop!(backtick, vm);
let backtick = backtick.py_bool(vm)?;
let encoded = uu_encode(encode_input(data, vm)?.as_ref(), backtick)?;
Ok(allocate_bytes(encoded, vm.heap))
}
/// `binascii.a2b_uu(data)` — the inverse, tolerant of either padding
/// convention and of a line truncated before its length byte promised.View on GitHub (pinned to adc986b362)