Skip to content

Commit 48ff6c6

Browse files
dloeblkleisauke
andauthored
Add buffer with args fuzzer (#4103)
* add generic buffer with args fuzzer * Simplify * fuzz seed corpus: add webpsave leak * add more test cases to the seed corpus * add vips_init call --------- Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl>
1 parent cdea0dd commit 48ff6c6

10 files changed

+127
-0
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
[n=-1,page=0,dpi=72,scale=0.1,password=secret]
2+
.png[filter=none]
3+
%PDF-1.1
4+
%����
5+
1 0 obj
6+
<<
7+
/Pages 2 0 R
8+
/Type /Catalog
9+
>>
10+
endobj
11+
2 0 obj
12+
<<
13+
/MediaBox [0 0 595 842]
14+
/Kids [3 0 R]
15+
/Count 1
16+
/Type /Pages
17+
>>
18+
endobj
19+
3 0 obj
20+
<<
21+
/Parent 2 0 R
22+
/MediaBox [0 0 595 842]
23+
/Type /Page
24+
>>
25+
endobj xref
26+
0 4
27+
0000000000 65535 f
28+
0000000015 00000 n
29+
0000000066 00000 n
30+
0000000149 00000 n
31+
trailer
32+
33+
<<
34+
/Root 1 0 R
35+
/Size 4
36+
>>
37+
startxref
38+
221
39+
%%EOF
Binary file not shown.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include <vips/vips.h>
2+
3+
#define MAX_ARG_LEN 4096 // =VIPS_PATH_MAX
4+
5+
extern "C" int
6+
LLVMFuzzerInitialize(int *argc, char ***argv)
7+
{
8+
if (VIPS_INIT(*argv[0]))
9+
return -1;
10+
11+
vips_concurrency_set(1);
12+
return 0;
13+
}
14+
15+
static char *
16+
ExtractLine(const guint8 *data, size_t size, size_t *n)
17+
{
18+
const guint8 *end;
19+
20+
end = static_cast<const guint8 *>(
21+
memchr(data, '\n', VIPS_MIN(size, MAX_ARG_LEN)));
22+
if (end == nullptr)
23+
return nullptr;
24+
25+
*n = end - data;
26+
return g_strndup(reinterpret_cast<const char *>(data), *n);
27+
}
28+
29+
extern "C" int
30+
LLVMFuzzerTestOneInput(const guint8 *data, size_t size)
31+
{
32+
VipsImage *image;
33+
void *buf;
34+
char *option_string, *suffix;
35+
size_t len, n;
36+
37+
option_string = ExtractLine(data, size, &n);
38+
if (option_string == nullptr)
39+
return 0;
40+
41+
data += n + 1;
42+
size -= n + 1;
43+
44+
suffix = ExtractLine(data, size, &n);
45+
if (suffix == nullptr) {
46+
g_free(option_string);
47+
return 0;
48+
}
49+
50+
data += n + 1;
51+
size -= n + 1;
52+
53+
if (!(image = vips_image_new_from_buffer(data, size, option_string, nullptr))) {
54+
g_free(option_string);
55+
g_free(suffix);
56+
return 0;
57+
}
58+
59+
// We're done with option_string, free early.
60+
g_free(option_string);
61+
62+
if (image->Xsize > 100 ||
63+
image->Ysize > 100 ||
64+
image->Bands > 4) {
65+
g_object_unref(image);
66+
g_free(suffix);
67+
return 0;
68+
}
69+
70+
if (vips_image_write_to_buffer(image, suffix, &buf, &len, nullptr)) {
71+
g_object_unref(image);
72+
g_free(suffix);
73+
return 0;
74+
}
75+
76+
g_free(buf);
77+
g_free(suffix);
78+
g_object_unref(image);
79+
80+
return 0;
81+
}

fuzz/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ foreach fuzz_basename, fuzz_save_suffix : fuzz_save_buffer_progs
9797
)
9898
endforeach
9999

100+
101+
fuzz_execs += executable('generic_buffer_with_args_fuzzer',
102+
'generic_buffer_with_args_fuzzer.cc',
103+
dependencies: [libvips_dep, fuzz_deps],
104+
link_args: fuzz_ldflags,
105+
)
106+
100107
# If the fuzzing engine is not OSS-Fuzz, build the unit tests to be run on CI
101108
if fuzzing_engine != 'oss-fuzz'
102109
test_fuzz = configure_file(

0 commit comments

Comments
 (0)