{"record":{"id":"96d1ef5822c54862","repo":"FiloSottile/age","slug":"invalid-data-range-data-d-d-frombits-d","errorCode":null,"errorMessage":"invalid data range: data[%d]=%d (frombits=%d)","messagePattern":"invalid data range: data\\[(.+?)\\]=(.+?) \\(frombits=(.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/bech32/bech32.go","lineNumber":86,"sourceCode":"\tvalues := append(hrpExpand(hrp), data...)\n\tvalues = append(values, []byte{0, 0, 0, 0, 0, 0}...)\n\tmod := polymod(values) ^ 1\n\tret := make([]byte, 6)\n\tfor p := range ret {\n\t\tshift := 5 * (5 - p)\n\t\tret[p] = byte(mod>>shift) & 31\n\t}\n\treturn ret\n}\n\nfunc convertBits(data []byte, frombits, tobits byte, pad bool) ([]byte, error) {\n\tvar ret []byte\n\tacc := uint32(0)\n\tbits := byte(0)\n\tmaxv := byte(1<<tobits - 1)\n\tfor idx, value := range data {\n\t\tif value>>frombits != 0 {\n\t\t\treturn nil, fmt.Errorf(\"invalid data range: data[%d]=%d (frombits=%d)\", idx, value, frombits)\n\t\t}\n\t\tacc = acc<<frombits | uint32(value)\n\t\tbits += frombits\n\t\tfor bits >= tobits {\n\t\t\tbits -= tobits\n\t\t\tret = append(ret, byte(acc>>bits)&maxv)\n\t\t}\n\t}\n\tif pad {\n\t\tif bits > 0 {\n\t\t\tret = append(ret, byte(acc<<(tobits-bits))&maxv)\n\t\t}\n\t} else if bits >= frombits {\n\t\treturn nil, fmt.Errorf(\"illegal zero padding\")\n\t} else if byte(acc<<(tobits-bits))&maxv != 0 {\n\t\treturn nil, fmt.Errorf(\"non-zero padding\")\n\t}\n\treturn ret, nil","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/internal/bech32/bech32.go#L68-L104","documentation":"This error comes from the internal bech32 convertBits helper, which regroups data between bit widths (e.g. 8-bit bytes to 5-bit groups). Each input element must fit in frombits bits; if any value has bits set above that width, the conversion is invalid and this error is returned. It is used by Encode (bytes to 5-bit, always valid) and Decode (5-bit to bytes) paths.","triggerScenarios":"Calling Decode on a bech32 string whose data part contains 5-bit values >= 256 when regrouping to 8 bits (i.e. value>>8 != 0 with frombits=5 can't happen, so this triggers when convertBits is called with frombits < bit-width of supplied data) — practically, when internal code or tests invoke convertBits/Encode-Decode paths with out-of-range data, such as decoding a string whose checksum passed but data groups exceed the target range in the 5→8 direction.","commonSituations":"Corrupted bech32 strings that happen to pass checksum checks elsewhere; hand-rolled code calling the internal bech32 package directly with raw byte values wider than frombits; fuzz tests or property tests generating invalid 5-bit payloads.","solutions":["Since this is an internal package, do not call internal/bech32.convertBits directly with arbitrary-width data; always pass values that fit in frombits bits","If decoding, treat the input string as invalid — bech32.Decode surfaces this as a decode failure; verify the string against the original source","For Encode, 8→5 conversion cannot trigger this; if you see it, your data slice was corrupted before encoding — check the buffer source","Add a pre-check `for i, v := range data { if v >= 1<<frombits { ... } }` in any custom caller to reject bad input early"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func validateBech32Data(data []byte, frombits uint) bool {\n\tfor _, v := range data {\n\t\tif int(v) >= 1<<frombits {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not call internal/bech32 directly from application code; use the public age APIs","Always source 5-bit data from Decode output, never from hand-built slices","Fuzz/property-test any custom bech32 usage with bounded-value generators","Validate decoded strings end-to-end (checksum + padding) before trusting payloads"],"tags":["bech32","encoding","bit-manipulation","internal"],"backgroundTag":"bech32-invalid-data-range","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}