{"record":{"id":"0778498c0fd0900f","repo":"pydantic/monty","slug":"index-bounded-by-table-length","errorCode":null,"errorMessage":"index bounded by table length","messagePattern":"index bounded by table length","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/monty/src/modules/base64.rs","lineNumber":1148,"sourceCode":"            Self::Given(value) => value.py_contains(&Value::Int(i64::from(byte)), vm),\n        }\n    }\n}\n\n/// Builds the plain `ValueError` the ascii85 and base85 codecs raise — not\n/// `binascii.Error`, since none of them reaches `binascii`.\nfn codec_value_error(message: impl Into<String>) -> RunError {\n    SimpleException::new_msg(ExcType::ValueError, message.into()).into()\n}\n\n/// Rewrites `data` in place, mapping each byte of `from` to the byte at the\n/// same index of `to` — CPython's `bytes.translate(bytes.maketrans(...))`.\n///\n/// Later entries win, matching `maketrans` when `from` repeats a byte.\nfn translate(data: &mut [u8], from: &[u8], to: &[u8]) {\n    let mut table: [u8; 256] = [0; 256];\n    for (i, slot) in table.iter_mut().enumerate() {\n        *slot = u8::try_from(i).expect(\"index bounded by table length\");\n    }\n    for (src, dst) in from.iter().zip(to) {\n        table[usize::from(*src)] = *dst;\n    }\n    for byte in data {\n        *byte = table[usize::from(*byte)];\n    }\n}\n\n/// Borrows the bytes of an encoder input.\n///\n/// Encoders reach `binascii` without a coercion step, so a `str` fails the\n/// buffer protocol with CPython's `a bytes-like object is required` wording.\npub(super) fn encode_input<'a>(value: &'a Value, vm: &'a VM<'_>) -> RunResult<Cow<'a, [u8]>> {\n    encode_input_prefixed(value, vm, \"\")\n}\n\n/// Borrows the bytes of an encoder that coerces with `memoryview(s).tobytes()`","sourceCodeStart":1130,"sourceCodeEnd":1166,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty/src/modules/base64.rs#L1130-L1166","documentation":"Internal `expect` in `translate`, the helper implementing `bytes.translate`-style byte mapping for the base64 module. The identity table is built by enumerating 0..255, so `u8::try_from(i)` cannot fail — the message states the index is bounded by the table length. Not reachable from any public base64/b32 API call.","triggerScenarios":"Unreachable; would require the table array size to be reduced below 256 (or the loop range changed) in a code edit.","commonSituations":"Only relevant to contributors altering `translate` or adding new translation-based codec helpers.","solutions":["No runtime mitigation; keep the table at `[u8; 256]` and the enumerate loop over its full length.","If the signature changes to take arbitrary table sizes, replace the `expect` with real error handling."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep `translate`'s table at 256 entries; prefer deriving the identity table from `0..=u8::MAX` so sizes stay coupled."],"tags":["rust","internal-invariant","translate"],"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-23T08:17:48.524Z"}