{"record":{"id":"faf614778e7ee930","repo":"pydantic/monty","slug":"reduced-below-2-32","errorCode":null,"errorMessage":"reduced below 2**32","messagePattern":"reduced below 2\\*\\*32","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/monty/src/modules/binascii.rs","lineNumber":406,"sourceCode":"}\n\n/// Argument shape for `a2b_qp(data, header=False)`.\n#[derive(FromArgs)]\n#[from_args(name = \"a2b_qp\", style = c_named, at_most_total)]\nstruct A2bQpArgs {\n    data: Value,\n    #[from_args(default = Value::Bool(false))]\n    header: Value,\n}\n\n/// Reduces an `int` to the `unsigned int` CPython's `I` format takes, which\n/// wraps modulo 2**32 rather than rejecting a value out of range — so a\n/// negative or huge `crc` seed is accepted, as CPython accepts it.\nfn wrapping_u32(value: &Value, vm: &VM<'_>) -> RunResult<u32> {\n    const MODULUS: i64 = 1 << 32;\n\n    match value {\n        Value::Int(int) => Ok(u32::try_from(int.rem_euclid(MODULUS)).expect(\"reduced below 2**32\")),\n        Value::Bool(flag) => Ok(u32::from(*flag)),\n        Value::Ref(heap_id) => match vm.heap.get(*heap_id) {\n            HeapData::LongInt(long) => {\n                // `&` on a `BigInt` is two's-complement, so this is Python's\n                // own `value & 0xffffffff` for negatives as well.\n                Ok((&long.0 & BigInt::from(u32::MAX)).to_u32().expect(\"masked below 2**32\"))\n            }\n            _ => Err(ExcType::type_error_not_integer(&value.py_type_name(vm))),\n        },\n        _ => Err(ExcType::type_error_not_integer(&value.py_type_name(vm))),\n    }\n}\n\n/// Encodes bytes as lowercase hex, inserting `sep` every `bytes_per_sep` bytes.\n///\n/// A positive `bytes_per_sep` groups from the right, so any short group leads;\n/// a negative one groups from the left. Zero, or no separator, means none.\nfn hex_encode(data: &[u8], sep: Option<u8>, bytes_per_sep: i32) -> Vec<u8> {","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty/src/modules/binascii.rs#L388-L424","documentation":"Internal `expect` in `wrapping_u32`: for plain ints the seed is reduced with `rem_euclid(2**32)` before `u32::try_from`, so the conversion is guaranteed to succeed. This mirrors CPython's behaviour of accepting out-of-range CRC seeds by wrapping modulo 2**32 rather than raising. Users passing huge or negative seeds get correct wrapped results, never this panic.","triggerScenarios":"Unreachable from `binascii.crc32`/`crc_hqx` with any `int` input; would only fire if the `rem_euclid(MODULUS)` reduction were removed.","commonSituations":"Contributor-only; e.g. someone replacing `rem_euclid` with a direct `try_from`.","solutions":["No runtime mitigation; keep the modulo-2**32 reduction ahead of the conversion."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reduce with `rem_euclid(2**32)` (not `%`) so negative seeds map into range before `u32::try_from`."],"tags":["rust","internal-invariant","crc32"],"backgroundTag":"internal-invariant-violation","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}