Panic: unreachable!() in RealNumber::write when a CFF DICT real number overflows f32
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 83/100
Research direction
Start in src/cff/number.rs, reading RealNumber::parse and RealNumber::write; the issue identifies the overflowing parse and the panic path. Reproduce with the supplied font and confirm the unmodified font succeeds. Done when the overflowing real is rejected as a malformed font instead of panicking, with a regression check for that behavior.
Written by the indexing model from the issue text.
Description
subset panics on a CFF font whose DICT holds a real number too large for f32, in debug and release builds alike:
thread 'main' panicked at subsetter-0.2.6/src/cff/number.rs:112:22:
internal error: entered unreachable code
RealNumber::parse parses the nibble string with str::parse::<f32>(), which returns inf for an exponent past the f32 range instead of failing. RealNumber::write then formats the value with format!("{}", self.0), gets "inf", and hits unreachable!() on the i. The backtrace goes through rewrite_top_dict_index (src/cff/dict/top_dict.rs:115), but any DICT that is written back with a real operand takes the same path.
To reproduce with subsetter 0.2.6 (default-features = false) and the font below (640 bytes, a minimal CFF OpenType font with two glyphs, where the first FontMatrix operand in the Top DICT is changed from 48828125E-11 to 48828125E99, i.e. the bytes 1e 48 82 81 25 c1 1f to 1e 48 82 81 25 b9 9f):
fn main() {
let data = std::fs::read("cff-real-inf.otf").unwrap();
let remapper = subsetter::GlyphRemapper::new();
println!("{:?}", subsetter::subset(&data, 0, &remapper).map(|font| font.len()));
}
cargo run and cargo run --release both panic as above. The unmodified font prints Ok(476).
cff-real-inf.otf, base64 (decode with base64 -d > cff-real-inf.otf)
T1RUTwAJAIAAAwAQQ0ZGID2FLQsAAAIQAAAAZU9TLzJBOEHdAAABAAAAAGBjbWFwAAwAlAAAAbwA
AAA0aGVhZC9WaxIAAACcAAAANmhoZWEImgEuAAAA1AAAACRobXR4ArwAZAAAAngAAAAGbWF4cAAC
UAAAAAD4AAAABm5hbWU6H0HRAAABYAAAAFpwb3N0AAMAAAAAAfAAAAAgAAEAAAABAAD/pwTcXw88
9QADCAAAAAAA5vQRrwAAAADm9BGvAGQAAAH0ArwAAAADAAIAAAAAAAAAAQAABkD+cAAAAlgAZABk
AfQAAQAAAAAAAAAAAAAAAAAAAAEAAFAAAAIAAAADAlgBkAAFAAQAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAA/Pz8/AAAAQQBBAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAACAAAAAAAAQANgABAAAAAAABAAUAAAABAAAAAAACAAcABQADAAEECQABAAoADAADAAEE
CQACAA4AFlJlcHJvUmVndWxhcgBSAGUAcAByAG8AUgBlAGcAdQBsAGEAcgAAAAAAAgAAAAMAAAAU
AAMAAQAAABQABAAgAAAABAAEAAEAAABB//8AAABB////wAABAAAAAAADAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAQAEAQABAQEGUmVwcm8AAQEBJvgbAh5IgoEluZ+Lix5IgoElwR+LiwwH
74v4iPlQBc8Pi/AS0hEAAQEBBlJlcHJvAAAAACIAAgEBDRn47O8W+CT5UPwkBg747O8W+CT5UPwk
Bg4AAAACWABkAGQAAA==
SHA-256: 5c4f925da37caa1009b87e42eaa5410b59a69f386b617825f77c0339adc7ed6f
Returning None from RealNumber::parse when the parsed value is not finite would make this a MalformedFont error; a finite f32 always formats with {} as digits, . and - only, so write would then be safe. Found by fuzzing subsetter through the font registration of inkoxide; until it is fixed we check the DICT reals ourselves before calling subset.
- Dominant language
- Rust
- Stars
- 61
- Forks
- 16
- PR merge metrics
- No merged PRs in 30d
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from typst/subsetter
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
head table bounding box is not recalculated for variable font instancesPossibly taken @khaledhosny claimed this 16 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 56/100
-
Difficulty 5/5 Over a week Newbie friendliness 45/100
-
Difficulty 3/5 Half a day Newbie friendliness 67/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
pierreaubert/gpui-toolkit#114 ·
Maintainers usually reply within 1 day
-
BibLaTeX `type` keys like `phdthesis`, `mathesis`, `techreport` are printed raw instead of localizedOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
Maintainers usually reply within 1 day
-
compiler
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
HerringtonDarkholme/hd-lang#1853 ·
Maintainers usually reply within 1 day
-
bug needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
pbakaus/impeccable#1462 ·
Maintainers usually reply within 1 day