Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | # Copyright 2019 The Chromium OS Authors. |
3 | | # |
4 | | # Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | # you may not use this file except in compliance with the License. |
6 | | # You may obtain a copy of the License at |
7 | | # |
8 | | # http://www.apache.org/licenses/LICENSE-2.0 |
9 | | # |
10 | | # Unless required by applicable law or agreed to in writing, software |
11 | | # distributed under the License is distributed on an "AS IS" BASIS, |
12 | | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | # See the License for the specific language governing permissions and |
14 | | # limitations under the License. |
15 | | # |
16 | | ################################################################################ |
17 | | */ |
18 | | |
19 | | #include <base/gserrors.h> |
20 | | #include <psi/iapi.h> |
21 | | |
22 | | #include <limits.h> |
23 | | #include <stdio.h> |
24 | | #include <string.h> |
25 | | #include <stdint.h> |
26 | | |
27 | | static const unsigned char *g_data; |
28 | | static size_t g_size; |
29 | | |
30 | | int fuzz_gs_device( |
31 | | const unsigned char *buf, |
32 | | size_t size, |
33 | | int color_scheme, |
34 | | const char *device_target, |
35 | | const char *output_file, |
36 | | int do_interpolation |
37 | | ); |
38 | | |
39 | 2.84M | #define min(x, y) ((x) < (y) ? (x) : (y)) |
40 | | |
41 | | static int gs_stdin(void *inst, char *buf, int len) |
42 | 1.42M | { |
43 | 1.42M | size_t to_copy = min(len, g_size); |
44 | 1.42M | to_copy = min(INT_MAX, to_copy); |
45 | | |
46 | 1.42M | memcpy(buf, g_data, to_copy); |
47 | | |
48 | 1.42M | g_data += to_copy; |
49 | 1.42M | g_size -= to_copy; |
50 | | |
51 | 1.42M | return to_copy; |
52 | 1.42M | } gs_device_pdfwrite_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 6.25k | { | 43 | 6.25k | size_t to_copy = min(len, g_size); | 44 | 6.25k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 6.25k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 6.25k | g_data += to_copy; | 49 | 6.25k | g_size -= to_copy; | 50 | | | 51 | 6.25k | return to_copy; | 52 | 6.25k | } |
gs_device_pxlcolor_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 89.3k | { | 43 | 89.3k | size_t to_copy = min(len, g_size); | 44 | 89.3k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 89.3k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 89.3k | g_data += to_copy; | 49 | 89.3k | g_size -= to_copy; | 50 | | | 51 | 89.3k | return to_copy; | 52 | 89.3k | } |
gs_device_ps2write_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 118k | { | 43 | 118k | size_t to_copy = min(len, g_size); | 44 | 118k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 118k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 118k | g_data += to_copy; | 49 | 118k | g_size -= to_copy; | 50 | | | 51 | 118k | return to_copy; | 52 | 118k | } |
gs_device_png16m_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 54.0k | { | 43 | 54.0k | size_t to_copy = min(len, g_size); | 44 | 54.0k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 54.0k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 54.0k | g_data += to_copy; | 49 | 54.0k | g_size -= to_copy; | 50 | | | 51 | 54.0k | return to_copy; | 52 | 54.0k | } |
gs_device_pgmraw_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 79.3k | { | 43 | 79.3k | size_t to_copy = min(len, g_size); | 44 | 79.3k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 79.3k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 79.3k | g_data += to_copy; | 49 | 79.3k | g_size -= to_copy; | 50 | | | 51 | 79.3k | return to_copy; | 52 | 79.3k | } |
gs_device_tiffsep1_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 233k | { | 43 | 233k | size_t to_copy = min(len, g_size); | 44 | 233k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 233k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 233k | g_data += to_copy; | 49 | 233k | g_size -= to_copy; | 50 | | | 51 | 233k | return to_copy; | 52 | 233k | } |
gstoraster_fuzzer_all_colors.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 24.5k | { | 43 | 24.5k | size_t to_copy = min(len, g_size); | 44 | 24.5k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 24.5k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 24.5k | g_data += to_copy; | 49 | 24.5k | g_size -= to_copy; | 50 | | | 51 | 24.5k | return to_copy; | 52 | 24.5k | } |
gs_device_xpswrite_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 54.1k | { | 43 | 54.1k | size_t to_copy = min(len, g_size); | 44 | 54.1k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 54.1k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 54.1k | g_data += to_copy; | 49 | 54.1k | g_size -= to_copy; | 50 | | | 51 | 54.1k | return to_copy; | 52 | 54.1k | } |
gstoraster_ps_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 26.9k | { | 43 | 26.9k | size_t to_copy = min(len, g_size); | 44 | 26.9k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 26.9k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 26.9k | g_data += to_copy; | 49 | 26.9k | g_size -= to_copy; | 50 | | | 51 | 26.9k | return to_copy; | 52 | 26.9k | } |
gs_device_faxg3_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 146k | { | 43 | 146k | size_t to_copy = min(len, g_size); | 44 | 146k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 146k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 146k | g_data += to_copy; | 49 | 146k | g_size -= to_copy; | 50 | | | 51 | 146k | return to_copy; | 52 | 146k | } |
gs_device_psdcmyk_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 185k | { | 43 | 185k | size_t to_copy = min(len, g_size); | 44 | 185k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 185k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 185k | g_data += to_copy; | 49 | 185k | g_size -= to_copy; | 50 | | | 51 | 185k | return to_copy; | 52 | 185k | } |
gs_device_pdfwrite_opts_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 62.1k | { | 43 | 62.1k | size_t to_copy = min(len, g_size); | 44 | 62.1k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 62.1k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 62.1k | g_data += to_copy; | 49 | 62.1k | g_size -= to_copy; | 50 | | | 51 | 62.1k | return to_copy; | 52 | 62.1k | } |
gs_device_pxlmono_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 61.4k | { | 43 | 61.4k | size_t to_copy = min(len, g_size); | 44 | 61.4k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 61.4k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 61.4k | g_data += to_copy; | 49 | 61.4k | g_size -= to_copy; | 50 | | | 51 | 61.4k | return to_copy; | 52 | 61.4k | } |
gs_device_eps2write_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 100k | { | 43 | 100k | size_t to_copy = min(len, g_size); | 44 | 100k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 100k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 100k | g_data += to_copy; | 49 | 100k | g_size -= to_copy; | 50 | | | 51 | 100k | return to_copy; | 52 | 100k | } |
gstoraster_pdf_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 32.4k | { | 43 | 32.4k | size_t to_copy = min(len, g_size); | 44 | 32.4k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 32.4k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 32.4k | g_data += to_copy; | 49 | 32.4k | g_size -= to_copy; | 50 | | | 51 | 32.4k | return to_copy; | 52 | 32.4k | } |
gs_device_bmpmono_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 73.4k | { | 43 | 73.4k | size_t to_copy = min(len, g_size); | 44 | 73.4k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 73.4k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 73.4k | g_data += to_copy; | 49 | 73.4k | g_size -= to_copy; | 50 | | | 51 | 73.4k | return to_copy; | 52 | 73.4k | } |
gstoraster_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 73.3k | { | 43 | 73.3k | size_t to_copy = min(len, g_size); | 44 | 73.3k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 73.3k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 73.3k | g_data += to_copy; | 49 | 73.3k | g_size -= to_copy; | 50 | | | 51 | 73.3k | return to_copy; | 52 | 73.3k | } |
|
53 | | |
54 | | static int gs_stdnull(void *inst, const char *buf, int len) |
55 | 621k | { |
56 | | /* Just discard everything. */ |
57 | 621k | return len; |
58 | 621k | } gs_device_pdfwrite_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 838 | { | 56 | | /* Just discard everything. */ | 57 | 838 | return len; | 58 | 838 | } |
gs_device_pxlcolor_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 26.7k | { | 56 | | /* Just discard everything. */ | 57 | 26.7k | return len; | 58 | 26.7k | } |
gs_device_ps2write_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 52.0k | { | 56 | | /* Just discard everything. */ | 57 | 52.0k | return len; | 58 | 52.0k | } |
gs_device_png16m_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 16.4k | { | 56 | | /* Just discard everything. */ | 57 | 16.4k | return len; | 58 | 16.4k | } |
gs_device_pgmraw_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 20.1k | { | 56 | | /* Just discard everything. */ | 57 | 20.1k | return len; | 58 | 20.1k | } |
gs_device_tiffsep1_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 44.4k | { | 56 | | /* Just discard everything. */ | 57 | 44.4k | return len; | 58 | 44.4k | } |
gstoraster_fuzzer_all_colors.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 50.7k | { | 56 | | /* Just discard everything. */ | 57 | 50.7k | return len; | 58 | 50.7k | } |
gs_device_xpswrite_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 17.3k | { | 56 | | /* Just discard everything. */ | 57 | 17.3k | return len; | 58 | 17.3k | } |
gstoraster_ps_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 47.2k | { | 56 | | /* Just discard everything. */ | 57 | 47.2k | return len; | 58 | 47.2k | } |
gs_device_faxg3_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 19.8k | { | 56 | | /* Just discard everything. */ | 57 | 19.8k | return len; | 58 | 19.8k | } |
gs_device_psdcmyk_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 20.9k | { | 56 | | /* Just discard everything. */ | 57 | 20.9k | return len; | 58 | 20.9k | } |
gs_device_pdfwrite_opts_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 66.6k | { | 56 | | /* Just discard everything. */ | 57 | 66.6k | return len; | 58 | 66.6k | } |
gs_device_pxlmono_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 19.6k | { | 56 | | /* Just discard everything. */ | 57 | 19.6k | return len; | 58 | 19.6k | } |
gs_device_eps2write_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 71.7k | { | 56 | | /* Just discard everything. */ | 57 | 71.7k | return len; | 58 | 71.7k | } |
gstoraster_pdf_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 52.3k | { | 56 | | /* Just discard everything. */ | 57 | 52.3k | return len; | 58 | 52.3k | } |
gs_device_bmpmono_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 19.2k | { | 56 | | /* Just discard everything. */ | 57 | 19.2k | return len; | 58 | 19.2k | } |
gstoraster_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 74.8k | { | 56 | | /* Just discard everything. */ | 57 | 74.8k | return len; | 58 | 74.8k | } |
|
59 | | |
60 | | int gs_to_raster_fuzz( |
61 | | const unsigned char *buf, |
62 | | size_t size, |
63 | | int color_scheme |
64 | | ) |
65 | 39.2k | { |
66 | 39.2k | return fuzz_gs_device(buf, size, color_scheme, "cups", "/dev/null", 0); |
67 | 39.2k | } |
68 | | |
69 | | int fuzz_gs_device( |
70 | | const unsigned char *buf, |
71 | | size_t size, |
72 | | int color_scheme, |
73 | | const char *device_target, |
74 | | const char *output_file, |
75 | | int do_interpolation |
76 | | ) |
77 | 162k | { |
78 | 162k | int ret; |
79 | 162k | void *gs = NULL; |
80 | 162k | char color_space[50]; |
81 | 162k | char gs_device[50]; |
82 | 162k | char gs_o[100]; |
83 | 162k | char opt_interpolation[50]; |
84 | | /* |
85 | | * We are expecting color_scheme to be in the [0:62] interval. |
86 | | * This corresponds to the color schemes defined here: |
87 | | * https://github.com/ArtifexSoftware/ghostpdl/blob/8c97d5adce0040ac38a1fb4d7954499c65f582ff/cups/libs/cups/raster.h#L102 |
88 | | */ |
89 | 162k | sprintf(color_space, "-dcupsColorSpace=%d", color_scheme); |
90 | 162k | sprintf(gs_device, "-sDEVICE=%s", device_target); |
91 | 162k | sprintf(gs_o, "-sOutputFile=%s", output_file); |
92 | 162k | if (do_interpolation) { |
93 | 5.26k | sprintf(opt_interpolation, "-dDOINTERPOLATE"); |
94 | 5.26k | } |
95 | 157k | else { |
96 | 157k | sprintf(opt_interpolation, "-dNOINTERPOLATE"); |
97 | 157k | } |
98 | | /* Mostly stolen from cups-filters gstoraster. */ |
99 | 162k | char *args[] = { |
100 | 162k | "gs", |
101 | 162k | "-K1048576", |
102 | 162k | "-r200x200", |
103 | 162k | "-sBandListStorage=memory", |
104 | 162k | "-dMaxBitmap=0", |
105 | 162k | "-dBufferSpace=450k", |
106 | 162k | "-dMediaPosition=1", |
107 | 162k | color_space, |
108 | 162k | "-dQUIET", |
109 | 162k | "-dSAFER", |
110 | 162k | "-dNOPAUSE", |
111 | 162k | "-dBATCH", |
112 | 162k | opt_interpolation, |
113 | 162k | "-dNOMEDIAATTRS", |
114 | 162k | "-sstdout=%%stderr", |
115 | 162k | gs_o, |
116 | 162k | gs_device, |
117 | 162k | "-_", |
118 | 162k | }; |
119 | 162k | int argc = sizeof(args) / sizeof(args[0]); |
120 | | |
121 | | /* Stash buffers globally, for gs_stdin(). */ |
122 | 162k | g_data = buf; |
123 | 162k | g_size = size; |
124 | | |
125 | 162k | ret = gsapi_new_instance(&gs, NULL); |
126 | 162k | if (ret < 0) { |
127 | 0 | fprintf(stderr, "gsapi_new_instance: error %d\n", ret); |
128 | 0 | return ret; |
129 | 0 | } |
130 | | |
131 | 162k | gsapi_set_stdio(gs, gs_stdin, gs_stdnull, gs_stdnull); |
132 | 162k | ret = gsapi_set_arg_encoding(gs, GS_ARG_ENCODING_UTF8); |
133 | 162k | if (ret < 0) { |
134 | 0 | fprintf(stderr, "gsapi_set_arg_encoding: error %d\n", ret); |
135 | 0 | gsapi_delete_instance(gs); |
136 | 0 | return ret; |
137 | 0 | } |
138 | | |
139 | 162k | ret = gsapi_init_with_args(gs, argc, args); |
140 | 162k | if (ret && ret != gs_error_Quit) |
141 | | /* Just keep going, to cleanup. */ |
142 | 44.1k | fprintf(stderr, "gsapi_init_with_args: error %d\n", ret); |
143 | | |
144 | 162k | ret = gsapi_exit(gs); |
145 | 162k | if (ret < 0 && ret != gs_error_Quit) { |
146 | 1 | fprintf(stderr, "gsapi_exit: error %d\n", ret); |
147 | 1 | return ret; |
148 | 1 | } |
149 | | |
150 | 162k | gsapi_delete_instance(gs); |
151 | | |
152 | 162k | return 0; |
153 | 162k | } |