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.87M | #define min(x, y) ((x) < (y) ? (x) : (y)) |
40 | | |
41 | | static int gs_stdin(void *inst, char *buf, int len) |
42 | 1.43M | { |
43 | 1.43M | size_t to_copy = min(len, g_size); |
44 | 1.43M | to_copy = min(INT_MAX, to_copy); |
45 | | |
46 | 1.43M | memcpy(buf, g_data, to_copy); |
47 | | |
48 | 1.43M | g_data += to_copy; |
49 | 1.43M | g_size -= to_copy; |
50 | | |
51 | 1.43M | return to_copy; |
52 | 1.43M | } gs_device_pdfwrite_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 150k | { | 43 | 150k | size_t to_copy = min(len, g_size); | 44 | 150k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 150k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 150k | g_data += to_copy; | 49 | 150k | g_size -= to_copy; | 50 | | | 51 | 150k | return to_copy; | 52 | 150k | } |
gs_device_pxlcolor_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 91.8k | { | 43 | 91.8k | size_t to_copy = min(len, g_size); | 44 | 91.8k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 91.8k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 91.8k | g_data += to_copy; | 49 | 91.8k | g_size -= to_copy; | 50 | | | 51 | 91.8k | return to_copy; | 52 | 91.8k | } |
gs_device_ps2write_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 119k | { | 43 | 119k | size_t to_copy = min(len, g_size); | 44 | 119k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 119k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 119k | g_data += to_copy; | 49 | 119k | g_size -= to_copy; | 50 | | | 51 | 119k | return to_copy; | 52 | 119k | } |
gs_device_png16m_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 53.2k | { | 43 | 53.2k | size_t to_copy = min(len, g_size); | 44 | 53.2k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 53.2k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 53.2k | g_data += to_copy; | 49 | 53.2k | g_size -= to_copy; | 50 | | | 51 | 53.2k | return to_copy; | 52 | 53.2k | } |
gs_device_pgmraw_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 79.5k | { | 43 | 79.5k | size_t to_copy = min(len, g_size); | 44 | 79.5k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 79.5k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 79.5k | g_data += to_copy; | 49 | 79.5k | g_size -= to_copy; | 50 | | | 51 | 79.5k | return to_copy; | 52 | 79.5k | } |
gs_device_tiffsep1_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 234k | { | 43 | 234k | size_t to_copy = min(len, g_size); | 44 | 234k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 234k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 234k | g_data += to_copy; | 49 | 234k | g_size -= to_copy; | 50 | | | 51 | 234k | return to_copy; | 52 | 234k | } |
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 | 51.8k | { | 43 | 51.8k | size_t to_copy = min(len, g_size); | 44 | 51.8k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 51.8k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 51.8k | g_data += to_copy; | 49 | 51.8k | g_size -= to_copy; | 50 | | | 51 | 51.8k | return to_copy; | 52 | 51.8k | } |
gstoraster_ps_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 27.1k | { | 43 | 27.1k | size_t to_copy = min(len, g_size); | 44 | 27.1k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 27.1k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 27.1k | g_data += to_copy; | 49 | 27.1k | g_size -= to_copy; | 50 | | | 51 | 27.1k | return to_copy; | 52 | 27.1k | } |
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 | 83.5k | { | 43 | 83.5k | size_t to_copy = min(len, g_size); | 44 | 83.5k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 83.5k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 83.5k | g_data += to_copy; | 49 | 83.5k | g_size -= to_copy; | 50 | | | 51 | 83.5k | return to_copy; | 52 | 83.5k | } |
gs_device_pdfwrite_opts_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 61.0k | { | 43 | 61.0k | size_t to_copy = min(len, g_size); | 44 | 61.0k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 61.0k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 61.0k | g_data += to_copy; | 49 | 61.0k | g_size -= to_copy; | 50 | | | 51 | 61.0k | return to_copy; | 52 | 61.0k | } |
gs_device_pxlmono_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 54.5k | { | 43 | 54.5k | size_t to_copy = min(len, g_size); | 44 | 54.5k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 54.5k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 54.5k | g_data += to_copy; | 49 | 54.5k | g_size -= to_copy; | 50 | | | 51 | 54.5k | return to_copy; | 52 | 54.5k | } |
gs_device_eps2write_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 89.7k | { | 43 | 89.7k | size_t to_copy = min(len, g_size); | 44 | 89.7k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 89.7k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 89.7k | g_data += to_copy; | 49 | 89.7k | g_size -= to_copy; | 50 | | | 51 | 89.7k | return to_copy; | 52 | 89.7k | } |
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 | 74.6k | { | 43 | 74.6k | size_t to_copy = min(len, g_size); | 44 | 74.6k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 74.6k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 74.6k | g_data += to_copy; | 49 | 74.6k | g_size -= to_copy; | 50 | | | 51 | 74.6k | return to_copy; | 52 | 74.6k | } |
gstoraster_fuzzer.cc:gs_stdin(void*, char*, int) Line | Count | Source | 42 | 60.2k | { | 43 | 60.2k | size_t to_copy = min(len, g_size); | 44 | 60.2k | to_copy = min(INT_MAX, to_copy); | 45 | | | 46 | 60.2k | memcpy(buf, g_data, to_copy); | 47 | | | 48 | 60.2k | g_data += to_copy; | 49 | 60.2k | g_size -= to_copy; | 50 | | | 51 | 60.2k | return to_copy; | 52 | 60.2k | } |
|
53 | | |
54 | | static int gs_stdnull(void *inst, const char *buf, int len) |
55 | 625k | { |
56 | | /* Just discard everything. */ |
57 | 625k | return len; |
58 | 625k | } gs_device_pdfwrite_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 49.6k | { | 56 | | /* Just discard everything. */ | 57 | 49.6k | return len; | 58 | 49.6k | } |
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.2k | { | 56 | | /* Just discard everything. */ | 57 | 52.2k | return len; | 58 | 52.2k | } |
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.2k | { | 56 | | /* Just discard everything. */ | 57 | 20.2k | return len; | 58 | 20.2k | } |
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.2k | { | 56 | | /* Just discard everything. */ | 57 | 17.2k | return len; | 58 | 17.2k | } |
gstoraster_ps_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 47.5k | { | 56 | | /* Just discard everything. */ | 57 | 47.5k | return len; | 58 | 47.5k | } |
gs_device_faxg3_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 20.0k | { | 56 | | /* Just discard everything. */ | 57 | 20.0k | return len; | 58 | 20.0k | } |
gs_device_psdcmyk_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 4.22k | { | 56 | | /* Just discard everything. */ | 57 | 4.22k | return len; | 58 | 4.22k | } |
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.0k | { | 56 | | /* Just discard everything. */ | 57 | 19.0k | return len; | 58 | 19.0k | } |
gs_device_eps2write_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 54.4k | { | 56 | | /* Just discard everything. */ | 57 | 54.4k | return len; | 58 | 54.4k | } |
gstoraster_pdf_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 52.4k | { | 56 | | /* Just discard everything. */ | 57 | 52.4k | return len; | 58 | 52.4k | } |
gs_device_bmpmono_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 19.3k | { | 56 | | /* Just discard everything. */ | 57 | 19.3k | return len; | 58 | 19.3k | } |
gstoraster_fuzzer.cc:gs_stdnull(void*, char const*, int) Line | Count | Source | 55 | 63.7k | { | 56 | | /* Just discard everything. */ | 57 | 63.7k | return len; | 58 | 63.7k | } |
|
59 | | |
60 | | int gs_to_raster_fuzz( |
61 | | const unsigned char *buf, |
62 | | size_t size, |
63 | | int color_scheme |
64 | | ) |
65 | 37.7k | { |
66 | 37.7k | return fuzz_gs_device(buf, size, color_scheme, "cups", "/dev/null", 0); |
67 | 37.7k | } |
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 | 159k | { |
78 | 159k | int ret; |
79 | 159k | void *gs = NULL; |
80 | 159k | char color_space[50]; |
81 | 159k | char gs_device[50]; |
82 | 159k | char gs_o[100]; |
83 | 159k | 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 | 159k | sprintf(color_space, "-dcupsColorSpace=%d", color_scheme); |
90 | 159k | sprintf(gs_device, "-sDEVICE=%s", device_target); |
91 | 159k | sprintf(gs_o, "-sOutputFile=%s", output_file); |
92 | 159k | if (do_interpolation) { |
93 | 5.28k | sprintf(opt_interpolation, "-dDOINTERPOLATE"); |
94 | 5.28k | } |
95 | 154k | else { |
96 | 154k | sprintf(opt_interpolation, "-dNOINTERPOLATE"); |
97 | 154k | } |
98 | | /* Mostly stolen from cups-filters gstoraster. */ |
99 | 159k | char *args[] = { |
100 | 159k | "gs", |
101 | 159k | "-K1048576", |
102 | 159k | "-r200x200", |
103 | 159k | "-sBandListStorage=memory", |
104 | 159k | "-dMaxBitmap=0", |
105 | 159k | "-dBufferSpace=450k", |
106 | 159k | "-dMediaPosition=1", |
107 | 159k | color_space, |
108 | 159k | "-dQUIET", |
109 | 159k | "-dSAFER", |
110 | 159k | "-dNOPAUSE", |
111 | 159k | "-dBATCH", |
112 | 159k | opt_interpolation, |
113 | 159k | "-dNOMEDIAATTRS", |
114 | 159k | "-sstdout=%%stderr", |
115 | 159k | gs_o, |
116 | 159k | gs_device, |
117 | 159k | "-_", |
118 | 159k | }; |
119 | 159k | int argc = sizeof(args) / sizeof(args[0]); |
120 | | |
121 | | /* Stash buffers globally, for gs_stdin(). */ |
122 | 159k | g_data = buf; |
123 | 159k | g_size = size; |
124 | | |
125 | 159k | ret = gsapi_new_instance(&gs, NULL); |
126 | 159k | if (ret < 0) { |
127 | 0 | fprintf(stderr, "gsapi_new_instance: error %d\n", ret); |
128 | 0 | return ret; |
129 | 0 | } |
130 | | |
131 | 159k | gsapi_set_stdio(gs, gs_stdin, gs_stdnull, gs_stdnull); |
132 | 159k | ret = gsapi_set_arg_encoding(gs, GS_ARG_ENCODING_UTF8); |
133 | 159k | 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 | 159k | ret = gsapi_init_with_args(gs, argc, args); |
140 | 159k | if (ret && ret != gs_error_Quit) |
141 | | /* Just keep going, to cleanup. */ |
142 | 43.7k | fprintf(stderr, "gsapi_init_with_args: error %d\n", ret); |
143 | | |
144 | 159k | ret = gsapi_exit(gs); |
145 | 159k | if (ret < 0 && ret != gs_error_Quit) { |
146 | 0 | fprintf(stderr, "gsapi_exit: error %d\n", ret); |
147 | 0 | return ret; |
148 | 0 | } |
149 | | |
150 | 159k | gsapi_delete_instance(gs); |
151 | | |
152 | 159k | return 0; |
153 | 159k | } |