Coverage Report

Created: 2026-04-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gs_xps_fuzzer.cc
Line
Count
Source
1
/* Copyright 2026 Google LLC
2
Licensed under the Apache License, Version 2.0 (the "License");
3
you may not use this file except in compliance with the License.
4
You may obtain a copy of the License at
5
      http://www.apache.org/licenses/LICENSE-2.0
6
Unless required by applicable law or agreed to in writing, software
7
distributed under the License is distributed on an "AS IS" BASIS,
8
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
See the License for the specific language governing permissions and
10
limitations under the License.
11
*/
12
13
/*
14
 * Fuzzer for Ghostscript's XPS (XML Paper Specification) interpreter.
15
 *
16
 * XPS documents are ZIP archives (identified by "PK" magic bytes).
17
 * The ZIP format requires seekable I/O, so we must write fuzz data to
18
 * a temp file. The ghostpdl auto-detection uses the "PK" prefix
19
 * (confidence 80 in xps_detect_language).
20
 *
21
 */
22
23
#include <base/gserrors.h>
24
#include <psi/iapi.h>
25
26
#include <stdint.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <string.h>
30
#include <unistd.h>
31
32
static int gs_stdnull(void *inst, const char *buf, int len)
33
749
{
34
749
  return len;
35
749
}
36
37
2.04k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
38
2.04k
  if (size < 4)
39
1
    return 0;
40
41
  /* Write fuzz data directly to temp file */
42
2.04k
  char infile[256];
43
2.04k
  sprintf(infile, "/tmp/fuzz_xps.%d", getpid());
44
2.04k
  FILE *f = fopen(infile, "wb");
45
2.04k
  if (!f)
46
0
    return 0;
47
2.04k
  fwrite(data, 1, size, f);
48
2.04k
  fclose(f);
49
50
2.04k
  void *gs = NULL;
51
2.04k
  int ret = gsapi_new_instance(&gs, NULL);
52
2.04k
  if (ret < 0) {
53
0
    unlink(infile);
54
0
    return 0;
55
0
  }
56
57
2.04k
  gsapi_set_stdio(gs, NULL, gs_stdnull, gs_stdnull);
58
2.04k
  gsapi_set_arg_encoding(gs, GS_ARG_ENCODING_UTF8);
59
60
2.04k
  char *args[] = {
61
2.04k
    (char *)"gpdl",
62
2.04k
    (char *)"-dNOPAUSE",
63
2.04k
    (char *)"-dBATCH",
64
2.04k
    (char *)"-dQUIET",
65
2.04k
    (char *)"-dSAFER",
66
2.04k
    (char *)"-sDEVICE=nullpage",
67
2.04k
    (char *)"-sOutputFile=/dev/null",
68
2.04k
    (char *)"-r72x72",
69
2.04k
    infile,
70
2.04k
  };
71
2.04k
  int argc = sizeof(args) / sizeof(args[0]);
72
73
2.04k
  ret = gsapi_init_with_args(gs, argc, args);
74
2.04k
  gsapi_exit(gs);
75
2.04k
  gsapi_delete_instance(gs);
76
77
2.04k
  unlink(infile);
78
2.04k
  return 0;
79
2.04k
}