Skip to content

Commit 5907e83

Browse files
committed
suite: add more auto-generated crash patches
1 parent 5d4c06a commit 5907e83

30 files changed

Lines changed: 1979 additions & 19 deletions

harness-suite/crashes/rustc-demangle-native_c.bin

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
diff --git a/src/lib/openjp2/cio.c b/src/lib/openjp2/cio.c
2+
index 4fde9fe..435948a 100644
3+
--- a/src/lib/openjp2/cio.c
4+
+++ b/src/lib/openjp2/cio.c
5+
@@ -499,7 +499,7 @@ OPJ_OFF_T opj_stream_read_skip(opj_stream_private_t * p_stream,
6+
/* Check if we are going beyond the end of file. Most skip_fn do not */
7+
/* check that, but we must be careful not to advance m_byte_offset */
8+
/* beyond m_user_data_length, otherwise */
9+
- /* opj_stream_get_number_byte_left() will assert. */
10+
+ /* opj_stream_get_number_byte_left() will return -1. */
11+
if ((OPJ_UINT64)(p_stream->m_byte_offset + l_skip_nb_bytes + p_size) >
12+
p_stream->m_user_data_length) {
13+
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
14+
@@ -583,8 +583,10 @@ OPJ_OFF_T opj_stream_tell(const opj_stream_private_t * p_stream)
15+
16+
OPJ_OFF_T opj_stream_get_number_byte_left(const opj_stream_private_t * p_stream)
17+
{
18+
- assert(p_stream->m_byte_offset >= 0);
19+
- assert(p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset);
20+
+ if (p_stream->m_byte_offset < 0 ||
21+
+ p_stream->m_user_data_length < (OPJ_UINT64)p_stream->m_byte_offset) {
22+
+ return (OPJ_OFF_T) - 1;
23+
+ }
24+
return p_stream->m_user_data_length ?
25+
(OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset :
26+
0;
27+
diff --git a/src/lib/openjp2/cio.h b/src/lib/openjp2/cio.h
28+
index 7caee30..94e4d97 100644
29+
--- a/src/lib/openjp2/cio.h
30+
+++ b/src/lib/openjp2/cio.h
31+
@@ -320,7 +320,8 @@ OPJ_OFF_T opj_stream_tell(const opj_stream_private_t * p_stream);
32+
*
33+
* @param p_stream the stream to get the information from.
34+
*
35+
- * @return Number of bytes left before the end of the stream.
36+
+ * @return Number of bytes left before the end of the stream, or -1 if the
37+
+ * stream position is inconsistent (e.g. read past end).
38+
*/
39+
OPJ_OFF_T opj_stream_get_number_byte_left(const opj_stream_private_t *
40+
p_stream);
41+
diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c
42+
index ad76aca..38231f6 100644
43+
--- a/src/lib/openjp2/j2k.c
44+
+++ b/src/lib/openjp2/j2k.c
45+
@@ -4995,12 +4995,18 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
46+
l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
47+
48+
if (p_j2k->m_specific_param.m_decoder.m_last_tile_part) {
49+
+ OPJ_OFF_T l_bytes_left = opj_stream_get_number_byte_left(p_stream);
50+
+ if (l_bytes_left < 2) {
51+
+ opj_event_msg(p_manager, EVT_ERROR,
52+
+ "Not enough bytes left in stream for tile part\n");
53+
+ return OPJ_FALSE;
54+
+ }
55+
/* opj_stream_get_number_byte_left returns OPJ_OFF_T
56+
// but we are in the last tile part,
57+
// so its result will fit on OPJ_UINT32 unless we find
58+
// a file with a single tile part of more than 4 GB...*/
59+
p_j2k->m_specific_param.m_decoder.m_sot_length = (OPJ_UINT32)(
60+
- opj_stream_get_number_byte_left(p_stream) - 2);
61+
+ l_bytes_left - 2);
62+
} else {
63+
/* Check to avoid pass the limit of OPJ_UINT32 */
64+
if (p_j2k->m_specific_param.m_decoder.m_sot_length >= 2) {
65+
@@ -9768,7 +9774,7 @@ OPJ_BOOL opj_j2k_read_tile_header(opj_j2k_t * p_j2k,
66+
/* Try to read until the Start Of Data is detected */
67+
while (l_current_marker != J2K_MS_SOD) {
68+
69+
- if (opj_stream_get_number_byte_left(p_stream) == 0) {
70+
+ if (opj_stream_get_number_byte_left(p_stream) <= 0) {
71+
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
72+
break;
73+
}
74+
@@ -9792,7 +9798,7 @@ OPJ_BOOL opj_j2k_read_tile_header(opj_j2k_t * p_j2k,
75+
76+
/* cf. https://code.google.com/p/openjpeg/issues/detail?id=226 */
77+
if (l_current_marker == 0x8080 &&
78+
- opj_stream_get_number_byte_left(p_stream) == 0) {
79+
+ opj_stream_get_number_byte_left(p_stream) <= 0) {
80+
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
81+
break;
82+
}
83+
@@ -9903,7 +9909,7 @@ OPJ_BOOL opj_j2k_read_tile_header(opj_j2k_t * p_j2k,
84+
&l_current_marker, 2);
85+
}
86+
}
87+
- if (opj_stream_get_number_byte_left(p_stream) == 0
88+
+ if (opj_stream_get_number_byte_left(p_stream) <= 0
89+
&& p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) {
90+
break;
91+
}
92+
@@ -10180,7 +10186,7 @@ OPJ_BOOL opj_j2k_decode_tile(opj_j2k_t * p_j2k,
93+
p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
94+
p_j2k->m_specific_param.m_decoder.m_state &= (~(OPJ_UINT32)J2K_STATE_DATA);
95+
96+
- if (opj_stream_get_number_byte_left(p_stream) == 0
97+
+ if (opj_stream_get_number_byte_left(p_stream) <= 0
98+
&& p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) {
99+
return OPJ_TRUE;
100+
}
101+
@@ -10197,7 +10203,7 @@ OPJ_BOOL opj_j2k_decode_tile(opj_j2k_t * p_j2k,
102+
p_j2k->m_current_tile_number = 0;
103+
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_EOC;
104+
} else if (l_current_marker != J2K_MS_SOT) {
105+
- if (opj_stream_get_number_byte_left(p_stream) == 0) {
106+
+ if (opj_stream_get_number_byte_left(p_stream) <= 0) {
107+
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
108+
opj_event_msg(p_manager, EVT_WARNING, "Stream does not end with EOC\n");
109+
return OPJ_TRUE;
110+
@@ -12123,7 +12129,7 @@ static OPJ_BOOL opj_j2k_decode_tiles(opj_j2k_t *p_j2k,
111+
opj_event_msg(p_manager, EVT_INFO,
112+
"Image data has been updated with tile %d.\n\n", l_current_tile_no + 1);
113+
114+
- if (opj_stream_get_number_byte_left(p_stream) == 0
115+
+ if (opj_stream_get_number_byte_left(p_stream) <= 0
116+
&& p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) {
117+
break;
118+
}
119+
diff --git a/src/lib/openjp2/jp2.c b/src/lib/openjp2/jp2.c
120+
index 3d16d10..83405a4 100644
121+
--- a/src/lib/openjp2/jp2.c
122+
+++ b/src/lib/openjp2/jp2.c
123+
@@ -496,6 +496,11 @@ static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
124+
125+
if (box->length == 0) { /* last box */
126+
const OPJ_OFF_T bleft = opj_stream_get_number_byte_left(cio);
127+
+ if (bleft < 0) {
128+
+ opj_event_msg(p_manager, EVT_ERROR,
129+
+ "Stream position inconsistent while reading JP2 box\n");
130+
+ return OPJ_FALSE;
131+
+ }
132+
if (bleft > (OPJ_OFF_T)(0xFFFFFFFFU - 8U)) {
133+
opj_event_msg(p_manager, EVT_ERROR,
134+
"Cannot handle box sizes higher than 2^32\n");

harness-suite/projects-clike/openjpeg/prepare.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ set -e
22
git clone-rev.sh https://github.com/uclouvain/openjpeg "$PROJECT/repo" 21b70b0d62807e270994f94302e323da4f0d776b
33
git -C "$PROJECT/repo" apply ../stub_clocks.patch
44
git -C "$PROJECT/repo" apply ../fix-pi-decode-alloc.patch
5+
git -C "$PROJECT/repo" apply ../fix-stream-byte-left.patch

harness-suite/projects-rust/image/fix-jpeg-webp-image.patch

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ index bd1b20cc..3fcc63b9 100644
1010
+[patch.crates-io]
1111
+zune-jpeg = { path = "../zune-jpeg" }
1212
+image-webp = { path = "../image-webp" }
13+
+png = { path = "../png" }
1314
diff --git a/fuzz/fuzzers/fuzzer_script_webp.rs b/fuzz/fuzzers/fuzzer_script_webp.rs
1415
index 4ba62ba0..7470f6f9 100644
1516
--- a/fuzz/fuzzers/fuzzer_script_webp.rs
@@ -33,6 +34,56 @@ index 4ba62ba0..7470f6f9 100644
3334
+ }
3435
+
3536
+ let mut buf = vec![0; decoder.total_bytes() as usize];
37+
+ let _ = decoder.read_image(&mut buf);
38+
});
39+
diff --git a/fuzz/fuzzers/fuzzer_script_png.rs b/fuzz/fuzzers/fuzzer_script_png.rs
40+
index 4d93609f..9f7ee515 100644
41+
--- a/fuzz/fuzzers/fuzzer_script_png.rs
42+
+++ b/fuzz/fuzzers/fuzzer_script_png.rs
43+
@@ -1,7 +1,19 @@
44+
#![no_main]
45+
#[macro_use] extern crate libfuzzer_sys;
46+
extern crate image;
47+
+use image::ImageDecoder;
48+
+use std::io::Cursor;
49+
50+
fuzz_target!(|data: &[u8]| {
51+
- let _ = image::load_from_memory_with_format(data, image::ImageFormat::Png);
52+
+ let decoder = match image::codecs::png::PngDecoder::new(Cursor::new(data)) {
53+
+ Ok(decoder) => decoder,
54+
+ Err(_) => return,
55+
+ };
56+
+
57+
+ if decoder.total_bytes() > 256 * 1024 * 1024 {
58+
+ return;
59+
+ }
60+
+
61+
+ let mut buf = vec![0; decoder.total_bytes() as usize];
62+
+ let _ = decoder.read_image(&mut buf);
63+
});
64+
diff --git a/fuzz/fuzzers/fuzzer_script_jpeg.rs b/fuzz/fuzzers/fuzzer_script_jpeg.rs
65+
index 600f9a1..73449a1 100644
66+
--- a/fuzz/fuzzers/fuzzer_script_jpeg.rs
67+
+++ b/fuzz/fuzzers/fuzzer_script_jpeg.rs
68+
@@ -1,7 +1,19 @@
69+
#![no_main]
70+
#[macro_use] extern crate libfuzzer_sys;
71+
extern crate image;
72+
+use image::ImageDecoder;
73+
+use std::io::Cursor;
74+
75+
fuzz_target!(|data: &[u8]| {
76+
- let _ = image::load_from_memory_with_format(data, image::ImageFormat::Jpeg);
77+
+ let decoder = match image::codecs::jpeg::JpegDecoder::new(Cursor::new(data)) {
78+
+ Ok(decoder) => decoder,
79+
+ Err(_) => return,
80+
+ };
81+
+
82+
+ if decoder.total_bytes() > 32 * 1024 * 1024 {
83+
+ return;
84+
+ }
85+
+
86+
+ let mut buf = vec![0; decoder.total_bytes() as usize];
3687
+ let _ = decoder.read_image(&mut buf);
3788
});
3889
diff --git a/src/codecs/webp/decoder.rs b/src/codecs/webp/decoder.rs
@@ -82,14 +133,39 @@ diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
82133
index d31ed4a5..72d8f937 100644
83134
--- a/fuzz/Cargo.toml
84135
+++ b/fuzz/Cargo.toml
85-
@@ -17,6 +17,10 @@ version = "0.4"
136+
@@ -17,6 +17,11 @@ version = "0.4"
86137
# Prevent this from interfering with workspaces
87138
[workspace]
88139
members = ["."]
89140
+
90141
+[patch.crates-io]
91142
+zune-jpeg = { path = "../../zune-jpeg" }
92143
+image-webp = { path = "../../image-webp" }
144+
+png = { path = "../../png" }
93145

94146
[[bin]]
95147
name = "fuzzer_script_guess"
148+
diff --git a/fuzz/fuzzers/fuzzer_script_guess.rs b/fuzz/fuzzers/fuzzer_script_guess.rs
149+
index 7f8fbf5..72c7291 100644
150+
--- a/fuzz/fuzzers/fuzzer_script_guess.rs
151+
+++ b/fuzz/fuzzers/fuzzer_script_guess.rs
152+
@@ -2,6 +2,18 @@
153+
#[macro_use] extern crate libfuzzer_sys;
154+
extern crate image;
155+
156+
+use image::{ImageReader, Limits};
157+
+use std::io::Cursor;
158+
+
159+
fuzz_target!(|data: &[u8]| {
160+
- let _ = image::load_from_memory(data);
161+
+ let mut reader = match ImageReader::new(Cursor::new(data)).with_guessed_format() {
162+
+ Ok(r) => r,
163+
+ Err(_) => return,
164+
+ };
165+
+ let mut limits = Limits::default();
166+
+ limits.max_alloc = Some(16 * 1024 * 1024);
167+
+ limits.max_image_width = Some(8192);
168+
+ limits.max_image_height = Some(8192);
169+
+ reader.limits(limits);
170+
+ let _ = reader.decode();
171+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- a/src/decoder/transform/palette.rs
2+
+++ b/src/decoder/transform/palette.rs
3+
@@ -70,8 +70,8 @@ fn create_rgba_palette(info: &Info) -> [[u8; 4]; 256] {
4+
palette_iter = &palette_iter[3..];
5+
rgba_iter = &mut rgba_iter[1..];
6+
}
7+
- if !palette_iter.is_empty() {
8+
+ if palette_iter.len() >= 3 {
9+
rgba_iter[0][0..3].copy_from_slice(&palette_iter[0..3]);
10+
}
11+
}

harness-suite/projects-rust/image/image-webp-lossless-temp-limit.patch

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,27 @@
1919
decoder.decode_frame(self.width, self.height, false, &mut data)?;
2020
for (rgba_val, chunk) in data.chunks_exact(4).zip(buf.chunks_exact_mut(3)) {
2121
chunk.copy_from_slice(&rgba_val[..3]);
22+
@@ -836,6 +846,11 @@
23+
}
24+
25+
let frame = Vp8Decoder::decode_frame((&mut self.r).take(next_chunk_size))?;
26+
+ if u32::from(frame.width) != frame_width
27+
+ || u32::from(frame.height) != frame_height
28+
+ {
29+
+ return Err(DecodingError::InconsistentImageSizes);
30+
+ }
31+
32+
let mut rgba_frame = vec![0; frame_width as usize * frame_height as usize * 4];
33+
frame.fill_rgba(&mut rgba_frame, self.webp_decode_options.lossy_upsampling);
34+
--- a/src/huffman.rs
35+
+++ b/src/huffman.rs
36+
@@ -113,6 +113,9 @@
37+
};
38+
39+
let code = usize::from(code);
40+
+ if node_index >= tree.len() {
41+
+ return Err(DecodingError::HuffmanError);
42+
+ }
43+
for depth in (0..length - table_bits).rev() {
44+
let node = tree[node_index];
45+

harness-suite/projects-rust/image/prepare.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,10 @@ patch -d "$PROJECT/zune-jpeg" -p1 <"$PROJECT/zune-jpeg-mcu-scratch.patch"
1212
patch -d "$PROJECT/image-webp" -p1 <"$PROJECT/image-webp-lossless-temp-limit.patch"
1313
rm -f "$PROJECT/zune-jpeg.crate" "$PROJECT/image-webp.crate"
1414

15+
curl -fsSL -o "$PROJECT/png.crate" https://static.crates.io/crates/png/0.18.1/download
16+
mkdir -p "$PROJECT/png"
17+
tar -xzf "$PROJECT/png.crate" -C "$PROJECT/png" --strip-components=1
18+
patch -d "$PROJECT/png" -p1 <"$PROJECT/fix-png-palette-partial.patch"
19+
rm -f "$PROJECT/png.crate"
20+
1521
git -C "$PROJECT/repo" apply "$PROJECT/fix-jpeg-webp-image.patch"

0 commit comments

Comments
 (0)