{"record":{"id":"810a99361478c561","repo":"can1357/oh-my-pi","slug":"bundled-silver-ttf-must-parse","errorCode":null,"errorMessage":"bundled Silver.ttf must parse","messagePattern":"bundled Silver\\.ttf must parse","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pi-natives/src/snapcompact.rs","lineNumber":196,"sourceCode":"\t\t};\n\t\tlet Ok(enc) = u32::from_str_radix(cp.trim(), 16) else {\n\t\t\tcontinue;\n\t\t};\n\t\tlet bits = bits.trim();\n\t\tif bits.len() != 16 {\n\t\t\tcontinue;\n\t\t}\n\t\tlet rows: Vec<u8> = (0..8)\n\t\t\t.map(|i| u8::from_str_radix(&bits[i * 2..i * 2 + 2], 16).unwrap_or(0))\n\t\t\t.collect();\n\t\tglyphs.insert(enc, Glyph { w: 8, h: 8, xoff: 0, yoff: -1, rows });\n\t}\n\tFont { glyphs, ascent: 7, cell_w: 8, cell_h: 8 }\n}\n\nfn parse_ttf(data: &'static [u8], px: f32, cell_w: usize, cell_h: usize) -> TtfFont {\n\tlet face =\n\t\tTtfFace::from_bytes(data, FontSettings::default()).expect(\"bundled Silver.ttf must parse\");\n\tlet supported = face.chars().keys().copied().collect();\n\tlet ascent = face\n\t\t.horizontal_line_metrics(px)\n\t\t.map_or(px * 0.8, |metrics| metrics.ascent);\n\tTtfFont { face, supported, px, ascent, cell_w, cell_h }\n}\n\nenum RenderFont<'a> {\n\tBitmap(&'a Font),\n\tTtf(&'a TtfFont),\n}\n\nimpl RenderFont<'_> {\n\tconst fn cell_w(&self) -> usize {\n\t\tmatch self {\n\t\t\tSelf::Bitmap(font) => font.cell_w,\n\t\t\tSelf::Ttf(font) => font.cell_w,\n\t\t}","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-natives/src/snapcompact.rs#L178-L214","documentation":"The snapcompact renderer uses a TTF font (Silver.ttf) embedded in the binary at compile time. parse_ttf calls .expect() on font parsing, so if the embedded bytes fail to parse as a valid TTF face the process panics with this message. Per the module's contract, the blob is compile-time embedded, so this indicates build/packaging corruption rather than bad user input.","triggerScenarios":"Calling any snapcompact rendering API that lazily initializes the font when the embedded Silver.ttf bytes fail to parse — broken build, bad bundling/embedding step, or binary corruption in transit.","commonSituations":"Custom/patched builds where the font asset was swapped or truncated; binary post-processing (strip/packers) corrupting embedded data; running a binary from a failed or divergent build pipeline.","solutions":["Rebuild the native module from a clean checkout (the embedded font is parsed at first use, validated by the build)","Verify the binary's integrity (checksum) — re-download or reinstall if corrupted","If you replaced the bundled font, ensure it is a valid TTF parseable with default FontSettings","Report to maintainers if a stock build panics — this is a build/packaging bug"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  render();\n} catch (err) {\n  if (String(err?.message).includes('bundled Silver.ttf must parse')) {\n    // fall back to a non-native/ASCII renderer\n  } else { throw err; }\n}","preventionTips":["Install binaries from official channels and verify checksums","Never patch/replace embedded font assets in distributed binaries","Rebuild cleanly if you build from source"],"tags":["native","font","panic","build"],"backgroundTag":"embedded-asset-corrupt","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}