Skip to content

Commit b75f399

Browse files
committed
Add XBM decoder
1 parent 62a9bd0 commit b75f399

File tree

14 files changed

+757
-4
lines changed

14 files changed

+757
-4
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ publish = false
88
include = ["src", "tests/reference.rs"]
99

1010
[features]
11-
default = ["pcx"]
11+
default = ["pcx", "xbm"]
1212
pcx = ["dep:pcx"]
13+
xbm = []
1314

1415
[dependencies]
1516
image = { version = "0.25.8", default-features = false }

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Decoding support for additional image formats beyond those provided by the [`ima
66
| Extension | File Format Description |
77
| --------- | -------------------- |
88
| PCX | [Wikipedia](https://en.wikipedia.org/wiki/PCX#PCX_file_format) |
9+
| XBM | [Wikipedia](https://en.wikipedia.org/wiki/X_BitMap) |
910

1011
## New Formats
1112

fuzz/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ image = { version = "0.25.8", default-features = false }
1414

1515
[dependencies.image-extras]
1616
path = ".."
17-
features = []
17+
features = ["xbm"]
1818
[dependencies.libfuzzer-sys]
1919
version = "0.4"
2020

@@ -25,3 +25,7 @@ members = ["."]
2525
[[bin]]
2626
name = "fuzzer_script_pcx"
2727
path = "fuzzers/fuzzer_script_pcx.rs"
28+
29+
[[bin]]
30+
name = "fuzzer_script_xbm"
31+
path = "fuzzers/fuzzer_script_xbm.rs"

fuzz/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ For the possibly more up-to-date guide see <https://fuzz.rs/book/cargo-fuzz/setu
55
> $ cargo install cargo-fuzz
66
> $ cargo +nightly fuzz run fuzzer_script_<format>
77
8+
Fuzzing may progress faster for certain formats if seeded with a dictionary:
9+
10+
> $ cargo +nightly fuzz run fuzzer_script_xbm -- -dict=fuzz/dictionaries/xbm.dict
11+
812
# Bug reports
913

1014
As explained in the project [README](../README.md), fuzzing is not a priority for

fuzz/dictionaries/xbm.dict

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"#define"
2+
"_width"
3+
"_height"
4+
"_x_hot"
5+
"_y_hot"
6+
"static"
7+
"unsigned"
8+
"char"
9+
"_bits[]"
10+
"="
11+
"{"
12+
"0x"
13+
"0X"
14+
","
15+
"}"
16+
";"

fuzz/fuzzers/fuzzer_script_xbm.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![no_main]
2+
#[macro_use]
3+
extern crate libfuzzer_sys;
4+
5+
use image::ImageDecoder;
6+
use std::io::Cursor;
7+
8+
fuzz_target!(|data: &[u8]| {
9+
let reader = Cursor::new(data);
10+
let Ok(mut decoder) = image_extras::xbm::XbmDecoder::new(reader) else {
11+
return;
12+
};
13+
let mut limits = image::Limits::default();
14+
limits.max_alloc = Some(1024 * 1024); // 1 MiB
15+
if limits.reserve(decoder.total_bytes()).is_err() {
16+
return;
17+
}
18+
if decoder.set_limits(limits).is_err() {
19+
return;
20+
}
21+
let _ = std::hint::black_box(image::DynamicImage::from_decoder(decoder));
22+
});

src/lib.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,26 @@
1818
#[cfg(feature = "pcx")]
1919
pub mod pcx;
2020

21+
#[cfg(feature = "xbm")]
22+
pub mod xbm;
23+
2124
/// Register all enabled extra formats with the image crate.
2225
pub fn register() {
23-
let just_registered = image::hooks::register_decoding_hook(
26+
let just_registered_pcx = image::hooks::register_decoding_hook(
2427
"pcx".into(),
2528
Box::new(|r| Ok(Box::new(pcx::PCXDecoder::new(r)?))),
2629
);
27-
if just_registered {
30+
if just_registered_pcx {
2831
image::hooks::register_format_detection_hook("pcx".into(), &[0x0a, 0x0], Some(b"\xFF\xF8"));
2932
}
33+
34+
// XBM images are often valid C code and have no simple and reliably distinguishing file signature
35+
image::hooks::register_decoding_hook(
36+
"xbm".into(),
37+
Box::new(|r| Ok(Box::new(xbm::XbmDecoder::new(r)?))),
38+
);
39+
image::hooks::register_decoding_hook(
40+
"bm".into(),
41+
Box::new(|r| Ok(Box::new(xbm::XbmDecoder::new(r)?))),
42+
);
3043
}

0 commit comments

Comments
 (0)