Coverage Report

Created: 2023-12-08 07:02

/src/tidy_general_fuzzer.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2021 Google LLC
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
#include <sys/types.h>
17
#include <stdlib.h>
18
#include <stdio.h>
19
#include <stdint.h>
20
#include <unistd.h>
21
#include "tidybuffio.h"
22
#include "tidy.h"
23
24
// All boolean options. These will be set randomly
25
// based on the fuzzer data.
26
TidyOptionId bool_options[] = {
27
  TidyJoinClasses, 
28
  TidyJoinStyles, 
29
  TidyKeepFileTimes, 
30
  TidyKeepTabs, 
31
  TidyLiteralAttribs, 
32
  TidyLogicalEmphasis, 
33
  TidyLowerLiterals, 
34
  TidyMakeBare, 
35
  TidyFixUri, 
36
  TidyForceOutput, 
37
  TidyGDocClean, 
38
  TidyHideComments,
39
  TidyMark, 
40
  TidyXmlTags, 
41
  TidyMakeClean,
42
  TidyAnchorAsName, 
43
  TidyMergeEmphasis, 
44
  TidyMakeBare, 
45
  TidyMetaCharset, 
46
  TidyMuteShow, 
47
  TidyNCR, 
48
  TidyNumEntities, 
49
  TidyOmitOptionalTags, 
50
  TidyPunctWrap, 
51
  TidyQuiet,
52
  TidyQuoteAmpersand,  
53
  TidyQuoteMarks, 
54
  TidyQuoteNbsp, 
55
  TidyReplaceColor, 
56
  TidyShowFilename, 
57
  TidyShowInfo, 
58
  TidyShowMarkup, 
59
  TidyShowMetaChange, 
60
  TidyShowWarnings, 
61
  TidySkipNested, 
62
  TidyUpperCaseTags, 
63
  TidyWarnPropAttrs, 
64
  TidyWord2000, 
65
  TidyWrapAsp, 
66
  TidyWrapAttVals, 
67
  TidyWrapJste, 
68
  TidyWrapPhp, 
69
  TidyWrapScriptlets, 
70
  TidyWrapSection, 
71
  TidyWriteBack,
72
};
73
74
0
void set_option(const uint8_t** data, size_t *size, TidyDoc *tdoc, TidyOptionId tboolID) {
75
0
  uint8_t decider;
76
0
  decider = **data;
77
0
  *data += 1; 
78
0
  *size -= 1;
79
0
  if (decider % 2 == 0) tidyOptSetBool( *tdoc, tboolID, yes );
80
0
  else { tidyOptSetBool( *tdoc, tboolID, no ); }
81
0
}
82
83
0
int TidyXhtml(const uint8_t* data, size_t size, TidyBuffer* output, TidyBuffer* errbuf) {
84
0
  uint8_t decider;
85
86
  // We need enough data for picking all of the options. One byte per option.
87
0
  if (size < 5+(sizeof(bool_options)/sizeof(bool_options[0]))) {
88
0
    return 0;
89
0
  }
90
91
0
  TidyDoc tdoc = tidyCreate();
92
93
  // Decide output format
94
0
  decider = *data;
95
0
  data++; size--;
96
0
  if (decider % 3 == 0) tidyOptSetBool( tdoc, TidyXhtmlOut, yes );
97
0
  else { tidyOptSetBool( tdoc, TidyXhtmlOut, no ); }
98
99
0
  if (decider % 3 == 1) tidyOptSetBool( tdoc, TidyHtmlOut, yes );
100
0
  else { tidyOptSetBool( tdoc, TidyHtmlOut, no ); }
101
102
0
  if (decider % 3 == 2) tidyOptSetBool( tdoc, TidyXmlOut, yes );
103
0
  else { tidyOptSetBool( tdoc, TidyXmlOut, no ); }
104
105
  // Set options 
106
0
  for (int i=0; i < sizeof(bool_options)/sizeof(TidyOptionId); i++) {
107
0
    set_option(&data, &size, &tdoc, bool_options[i]);
108
0
  }
109
110
  // Set an error buffer.
111
0
  tidySetErrorBuffer(tdoc, errbuf);
112
113
  // Parse the data
114
0
  decider = *data;
115
0
  data++; size--;
116
0
  switch (decider % 2) {
117
0
    case 0: {
118
0
      char filename[256];
119
0
      sprintf(filename, "/tmp/libfuzzer.%d", getpid());
120
121
0
      FILE *fp = fopen(filename, "wb");
122
0
      if (!fp) {
123
0
          return 0;
124
0
      }
125
0
      fwrite(data, size, 1, fp);
126
0
      fclose(fp);
127
128
0
      tidyParseFile(tdoc, filename);
129
0
      unlink(filename);
130
0
    }
131
0
    break;
132
0
    case 1: {
133
0
      char *inp = malloc(size+1);
134
0
      inp[size] = '\0';
135
0
      memcpy(inp, data, size);
136
0
      tidyParseString(tdoc, inp);
137
0
      free(inp);
138
0
    }
139
0
  }
140
141
  // Cleanup
142
0
  tidyRelease( tdoc );
143
144
0
  return 0;
145
0
}
146
147
77
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
148
77
  TidyBuffer fuzz_toutput;
149
77
  TidyBuffer fuzz_terror;
150
151
77
  tidyBufInit(&fuzz_toutput);
152
77
  tidyBufInit(&fuzz_terror);
153
154
77
  TidyXhtml(data, size, &fuzz_toutput, &fuzz_terror);
155
156
77
  tidyBufFree(&fuzz_toutput);
157
77
  tidyBufFree(&fuzz_terror);
158
159
77
  return 0;
160
77
}