1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "yaml.h"
16 #include "yaml_write_handler.h"
17 #include <assert.h>
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #ifdef NDEBUG
25 #undef NDEBUG
26 #endif
27 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)28 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
29   if (size < 2)
30     return 0;
31 
32   bool done = false;
33   bool is_canonical = data[0] & 1;
34   bool is_unicode = data[1] & 1;
35   data += 2;
36   size -= 2;
37 
38   yaml_parser_t parser;
39   yaml_emitter_t emitter;
40   yaml_document_t document;
41 
42   /* Initialize the parser and emitter objects. */
43 
44   if (!yaml_parser_initialize(&parser))
45     return 0;
46 
47   if (!yaml_emitter_initialize(&emitter))
48     goto cleanup_parser;
49 
50   /* Set the parser parameters. */
51 
52   yaml_parser_set_input_string(&parser, data, size);
53 
54   /* Set the emitter parameters. */
55   yaml_output_buffer_t out = {/*buf=*/NULL, /*size=*/0};
56   yaml_emitter_set_output(&emitter, yaml_write_handler, &out);
57 
58   yaml_emitter_set_canonical(&emitter, is_canonical);
59   yaml_emitter_set_unicode(&emitter, is_unicode);
60 
61   /* The main loop. */
62 
63   while (!done) {
64     /* Get the next event. */
65 
66     if (!yaml_parser_load(&parser, &document))
67       break;
68 
69     /* Check if this is the stream end. */
70 
71     done = (!yaml_document_get_root_node(&document));
72 
73     /* Emit the event. */
74 
75     if (!yaml_emitter_dump(&emitter, &document))
76       break;
77   }
78 
79   free(out.buf);
80   yaml_emitter_delete(&emitter);
81 
82 cleanup_parser:
83 
84   yaml_parser_delete(&parser);
85   return 0;
86 }
87