Panic: u16 overflow of the stem-hint count in charstring.rs when a glyph declares more than 65535 hints

Đang mở
#33 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
67/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
rust
Lĩnh vực
backend

Hướng nghiên cứu

Start in subsetter-0.2.6/src/cff/charstring.rs, at Decompiler::count_hints and the reported hint_count addition. Read how its errors are returned, then add a regression test using the supplied CFF reproduction or a focused charstring test. Done means excessive stem hints return an error instead of panicking or wrapping; run cargo test.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

subset panics on a CFF glyph that declares more than 65535 stem hints, in any build with overflow checks (debug builds, cargo test, fuzzing):

thread 'main' panicked at subsetter-0.2.6/src/cff/charstring.rs:171:9:
attempt to add with overflow

Decompiler::count_hints adds the hints of each stem operator to hint_count, a u16 (self.hint_count += elements.len() as u16 / 2). A glyph whose charstring, through subroutines, runs hstem with 48 operands 2731 times or more overflows it. Without overflow checks the count wraps silently, and the size of a following hintmask would be computed from the wrapped count. This happens with 0.2.6 and with main (b0adcc1).

To reproduce with subsetter 0.2.6 (default-features = false). The font is built for this report:

fn main() {
    // A minimal OpenType CFF font, 355 bytes, whose one glyph declares 72,000 stem
    // hints: global subroutine 0 is 48 operands and hstem (24 hints), subroutine 1 calls
    // it 60 times, subroutine 2 calls subroutine 1 50 times, and the charstring calls
    // subroutine 2 once, then endchar.
    let hex = "4f54544f000100100000000043464620000000000000001c000001470100040100010101024100010101121d0000013d111d000000021d000001451200000003020001003300ac01118b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b010b201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d201d0b211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d211d0b0001010104221d0e8b14";
    let data: Vec<u8> = (0..hex.len())
        .step_by(2)
        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).unwrap())
        .collect();
    let remapper = subsetter::GlyphRemapper::new();
    println!("{:?}", subsetter::subset(&data, 0, &remapper).map(|font| font.len()));
}

cargo run panics as above; cargo run --release prints Ok(147168).

It was found while reviewing how officewright guards against subsetter panics; until it is fixed, our call to subset turns the panic into an error.

A possible fix: add with checked_add and return CFFError on overflow. The Type 2 charstring format also limits a glyph to 96 stem hints (Technical Note #5177, Appendix B), so refusing more than that would fix it too.

Ngôn ngữ chính
Rust
Star
61
Fork
16
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của typst/subsetter

Tất cả issue của typst/subsetter

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.