Panic: unreachable!() in RealNumber::write when a CFF DICT real number overflows f32
まだ誰も着手していません。
評価
調査の方向性
src/cff/number.rsから始め、RealNumber::parseとRealNumber::writeを読みます。issueでは、オーバーフローするパース処理とpanicに至る経路が特定されています。提供されたフォントで再現し、変更していないフォントでは成功することを確認します。オーバーフローする実数がpanicを起こすのではなく、不正なフォントとして拒否され、その動作の回帰チェックが追加されていれば完了です。
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- Rust
- スター
- 61
- フォーク
- 16
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
typst/subsetter のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
head table bounding box is not recalculated for variable font instances対応中かも @khaledhosny が 16 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 56/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 45/100
-
難易度 3/5 半日 初心者へのやさしさ 67/100
typst/subsetter の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
pierreaubert/gpui-toolkit#114 ·
メンテナーはふだん 1 日以内に返信
-
BibLaTeX `type` keys like `phdthesis`, `mathesis`, `techreport` are printed raw instead of localizedオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
good first issue help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
メンテナーはふだん 1 日以内に返信
-
compiler
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
HerringtonDarkholme/hd-lang#1853 ·
メンテナーはふだん 1 日以内に返信