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_event_t input_event;
41   yaml_event_t output_event;
42 
43   /* Initialize the parser and emitter objects. */
44 
45   if (!yaml_parser_initialize(&parser)) {
46     return 1;
47   }
48 
49   if (!yaml_emitter_initialize(&emitter)) {
50     yaml_parser_delete(&parser);
51     return 1;
52   }
53 
54   /* Set the parser parameters. */
55 
56   yaml_parser_set_input_string(&parser, data, size);
57 
58   /* Set the emitter parameters. */
59   yaml_output_buffer_t out = {/*buf=*/NULL, /*size=*/0};
60   yaml_emitter_set_output(&emitter, yaml_write_handler, &out);
61 
62   yaml_emitter_set_canonical(&emitter, is_canonical);
63   yaml_emitter_set_unicode(&emitter, is_unicode);
64 
65   /* Create and emit the STREAM-START event. */
66 
67   if (!yaml_stream_start_event_initialize(&output_event, YAML_UTF8_ENCODING))
68     goto error;
69   if (!yaml_emitter_emit(&emitter, &output_event))
70     goto error;
71 
72   /* Create and emit the DOCUMENT-START event. */
73 
74   if (!yaml_document_start_event_initialize(&output_event, NULL, NULL, NULL, 0))
75     goto error;
76   if (!yaml_emitter_emit(&emitter, &output_event))
77     goto error;
78 
79   /* Create and emit the SEQUENCE-START event. */
80 
81   if (!yaml_sequence_start_event_initialize(
82           &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:seq", 1,
83           YAML_BLOCK_SEQUENCE_STYLE))
84     goto error;
85   if (!yaml_emitter_emit(&emitter, &output_event))
86     goto error;
87 
88   /* Loop through the input events. */
89 
90   while (!done) {
91     /* Get the next event. */
92 
93     if (!yaml_parser_parse(&parser, &input_event))
94       goto error;
95 
96     /* Check if this is the stream end. */
97 
98     done = (input_event.type == YAML_STREAM_END_EVENT);
99 
100     /* Create and emit a MAPPING-START event. */
101 
102     if (!yaml_mapping_start_event_initialize(
103             &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:map", 1,
104             YAML_BLOCK_MAPPING_STYLE))
105       goto error;
106     if (!yaml_emitter_emit(&emitter, &output_event))
107       goto error;
108 
109     /* Analyze the event. */
110 
111     switch (input_event.type) {
112     case YAML_STREAM_START_EVENT:
113 
114       /* Write 'type'. */
115 
116       if (!yaml_scalar_event_initialize(
117               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
118               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
119         goto error;
120       if (!yaml_emitter_emit(&emitter, &output_event))
121         goto error;
122 
123       /* Write 'STREAM-START'. */
124 
125       if (!yaml_scalar_event_initialize(
126               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
127               (yaml_char_t *)"STREAM-START", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
128         goto error;
129       if (!yaml_emitter_emit(&emitter, &output_event))
130         goto error;
131 
132       /* Display encoding information. */
133 
134       if (input_event.data.stream_start.encoding) {
135         yaml_encoding_t encoding = input_event.data.stream_start.encoding;
136 
137         /* Write 'encoding'. */
138 
139         if (!yaml_scalar_event_initialize(
140                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
141                 (yaml_char_t *)"encoding", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
142           goto error;
143         if (!yaml_emitter_emit(&emitter, &output_event))
144           goto error;
145 
146         /* Write the stream encoding. */
147 
148         if (!yaml_scalar_event_initialize(
149                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
150                 (yaml_char_t *)(encoding == YAML_UTF8_ENCODING
151                                     ? "utf-8"
152                                     : encoding == YAML_UTF16LE_ENCODING
153                                           ? "utf-16-le"
154                                           : encoding == YAML_UTF16BE_ENCODING
155                                                 ? "utf-16-be"
156                                                 : "unknown"),
157                 -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
158           goto error;
159         if (!yaml_emitter_emit(&emitter, &output_event))
160           goto error;
161       }
162 
163       break;
164 
165     case YAML_STREAM_END_EVENT:
166 
167       /* Write 'type'. */
168 
169       if (!yaml_scalar_event_initialize(
170               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
171               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
172         goto error;
173       if (!yaml_emitter_emit(&emitter, &output_event))
174         goto error;
175 
176       /* Write 'STREAM-END'. */
177 
178       if (!yaml_scalar_event_initialize(
179               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
180               (yaml_char_t *)"STREAM-END", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
181         goto error;
182       if (!yaml_emitter_emit(&emitter, &output_event))
183         goto error;
184 
185       break;
186 
187     case YAML_DOCUMENT_START_EVENT:
188 
189       /* Write 'type'. */
190 
191       if (!yaml_scalar_event_initialize(
192               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
193               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
194         goto error;
195       if (!yaml_emitter_emit(&emitter, &output_event))
196         goto error;
197 
198       /* Write 'DOCUMENT-START'. */
199 
200       if (!yaml_scalar_event_initialize(&output_event, NULL,
201                                         (yaml_char_t *)"tag:yaml.org,2002:str",
202                                         (yaml_char_t *)"DOCUMENT-START", -1, 1,
203                                         1, YAML_PLAIN_SCALAR_STYLE))
204         goto error;
205       if (!yaml_emitter_emit(&emitter, &output_event))
206         goto error;
207 
208       /* Display the document version numbers. */
209 
210       if (input_event.data.document_start.version_directive) {
211         yaml_version_directive_t *version =
212             input_event.data.document_start.version_directive;
213         char number[64];
214 
215         /* Write 'version'. */
216         if (!yaml_scalar_event_initialize(
217                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
218                 (yaml_char_t *)"version", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
219           goto error;
220         if (!yaml_emitter_emit(&emitter, &output_event))
221           goto error;
222 
223         /* Write '{'. */
224 
225         if (!yaml_mapping_start_event_initialize(
226                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:map", 1,
227                 YAML_FLOW_MAPPING_STYLE))
228           goto error;
229         if (!yaml_emitter_emit(&emitter, &output_event))
230           goto error;
231 
232         /* Write 'major'. */
233 
234         if (!yaml_scalar_event_initialize(
235                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
236                 (yaml_char_t *)"major", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
237           goto error;
238         if (!yaml_emitter_emit(&emitter, &output_event))
239           goto error;
240 
241         /* Write a number. */
242 
243         sprintf(number, "%d", version->major);
244         if (!yaml_scalar_event_initialize(
245                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:int",
246                 (yaml_char_t *)number, -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
247           goto error;
248         if (!yaml_emitter_emit(&emitter, &output_event))
249           goto error;
250 
251         /* Write 'minor'. */
252 
253         if (!yaml_scalar_event_initialize(
254                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
255                 (yaml_char_t *)"minor", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
256           goto error;
257         if (!yaml_emitter_emit(&emitter, &output_event))
258           goto error;
259 
260         /* Write a number. */
261 
262         sprintf(number, "%d", version->minor);
263         if (!yaml_scalar_event_initialize(
264                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:int",
265                 (yaml_char_t *)number, -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
266           goto error;
267         if (!yaml_emitter_emit(&emitter, &output_event))
268           goto error;
269 
270         /* Write '}'. */
271 
272         if (!yaml_mapping_end_event_initialize(&output_event))
273           goto error;
274         if (!yaml_emitter_emit(&emitter, &output_event))
275           goto error;
276       }
277 
278       /* Display the document tag directives. */
279 
280       if (input_event.data.document_start.tag_directives.start !=
281           input_event.data.document_start.tag_directives.end) {
282         yaml_tag_directive_t *tag;
283 
284         /* Write 'tags'. */
285         if (!yaml_scalar_event_initialize(
286                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
287                 (yaml_char_t *)"tags", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
288           goto error;
289         if (!yaml_emitter_emit(&emitter, &output_event))
290           goto error;
291 
292         /* Start a block sequence. */
293 
294         if (!yaml_sequence_start_event_initialize(
295                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:seq", 1,
296                 YAML_BLOCK_SEQUENCE_STYLE))
297           goto error;
298         if (!yaml_emitter_emit(&emitter, &output_event))
299           goto error;
300 
301         for (tag = input_event.data.document_start.tag_directives.start;
302              tag != input_event.data.document_start.tag_directives.end; tag++) {
303           /* Write '{'. */
304 
305           if (!yaml_mapping_start_event_initialize(
306                   &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:map",
307                   1, YAML_FLOW_MAPPING_STYLE))
308             goto error;
309           if (!yaml_emitter_emit(&emitter, &output_event))
310             goto error;
311 
312           /* Write 'handle'. */
313 
314           if (!yaml_scalar_event_initialize(
315                   &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
316                   (yaml_char_t *)"handle", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
317             goto error;
318           if (!yaml_emitter_emit(&emitter, &output_event))
319             goto error;
320 
321           /* Write the tag directive handle. */
322 
323           if (!yaml_scalar_event_initialize(
324                   &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
325                   (yaml_char_t *)tag->handle, -1, 0, 1,
326                   YAML_DOUBLE_QUOTED_SCALAR_STYLE))
327             goto error;
328           if (!yaml_emitter_emit(&emitter, &output_event))
329             goto error;
330 
331           /* Write 'prefix'. */
332 
333           if (!yaml_scalar_event_initialize(
334                   &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
335                   (yaml_char_t *)"prefix", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
336             goto error;
337           if (!yaml_emitter_emit(&emitter, &output_event))
338             goto error;
339 
340           /* Write the tag directive prefix. */
341 
342           if (!yaml_scalar_event_initialize(
343                   &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
344                   (yaml_char_t *)tag->prefix, -1, 0, 1,
345                   YAML_DOUBLE_QUOTED_SCALAR_STYLE))
346             goto error;
347           if (!yaml_emitter_emit(&emitter, &output_event))
348             goto error;
349 
350           /* Write '}'. */
351 
352           if (!yaml_mapping_end_event_initialize(&output_event))
353             goto error;
354           if (!yaml_emitter_emit(&emitter, &output_event))
355             goto error;
356         }
357 
358         /* End a block sequence. */
359 
360         if (!yaml_sequence_end_event_initialize(&output_event))
361           goto error;
362         if (!yaml_emitter_emit(&emitter, &output_event))
363           goto error;
364       }
365 
366       /* Write 'implicit'. */
367 
368       if (!yaml_scalar_event_initialize(
369               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
370               (yaml_char_t *)"implicit", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
371         goto error;
372       if (!yaml_emitter_emit(&emitter, &output_event))
373         goto error;
374 
375       /* Write if the document is implicit. */
376 
377       if (!yaml_scalar_event_initialize(
378               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:bool",
379               (yaml_char_t *)(input_event.data.document_start.implicit
380                                   ? "true"
381                                   : "false"),
382               -1, 1, 0, YAML_PLAIN_SCALAR_STYLE))
383         goto error;
384       if (!yaml_emitter_emit(&emitter, &output_event))
385         goto error;
386 
387       break;
388 
389     case YAML_DOCUMENT_END_EVENT:
390 
391       /* Write 'type'. */
392 
393       if (!yaml_scalar_event_initialize(
394               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
395               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
396         goto error;
397       if (!yaml_emitter_emit(&emitter, &output_event))
398         goto error;
399 
400       /* Write 'DOCUMENT-END'. */
401 
402       if (!yaml_scalar_event_initialize(
403               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
404               (yaml_char_t *)"DOCUMENT-END", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
405         goto error;
406       if (!yaml_emitter_emit(&emitter, &output_event))
407         goto error;
408 
409       /* Write 'implicit'. */
410 
411       if (!yaml_scalar_event_initialize(
412               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
413               (yaml_char_t *)"implicit", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
414         goto error;
415       if (!yaml_emitter_emit(&emitter, &output_event))
416         goto error;
417 
418       /* Write if the document is implicit. */
419 
420       if (!yaml_scalar_event_initialize(
421               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:bool",
422               (yaml_char_t *)(input_event.data.document_end.implicit ? "true"
423                                                                      : "false"),
424               -1, 1, 0, YAML_PLAIN_SCALAR_STYLE))
425         goto error;
426       if (!yaml_emitter_emit(&emitter, &output_event))
427         goto error;
428 
429       break;
430 
431     case YAML_ALIAS_EVENT:
432 
433       /* Write 'type'. */
434 
435       if (!yaml_scalar_event_initialize(
436               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
437               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
438         goto error;
439       if (!yaml_emitter_emit(&emitter, &output_event))
440         goto error;
441 
442       /* Write 'ALIAS'. */
443 
444       if (!yaml_scalar_event_initialize(
445               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
446               (yaml_char_t *)"ALIAS", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
447         goto error;
448       if (!yaml_emitter_emit(&emitter, &output_event))
449         goto error;
450 
451       /* Write 'anchor'. */
452 
453       if (!yaml_scalar_event_initialize(
454               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
455               (yaml_char_t *)"anchor", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
456         goto error;
457       if (!yaml_emitter_emit(&emitter, &output_event))
458         goto error;
459 
460       /* Write the alias anchor. */
461 
462       if (!yaml_scalar_event_initialize(&output_event, NULL,
463                                         (yaml_char_t *)"tag:yaml.org,2002:str",
464                                         input_event.data.alias.anchor, -1, 0, 1,
465                                         YAML_DOUBLE_QUOTED_SCALAR_STYLE))
466         goto error;
467       if (!yaml_emitter_emit(&emitter, &output_event))
468         goto error;
469 
470       break;
471 
472     case YAML_SCALAR_EVENT:
473 
474       /* Write 'type'. */
475 
476       if (!yaml_scalar_event_initialize(
477               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
478               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
479         goto error;
480       if (!yaml_emitter_emit(&emitter, &output_event))
481         goto error;
482 
483       /* Write 'SCALAR'. */
484 
485       if (!yaml_scalar_event_initialize(
486               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
487               (yaml_char_t *)"SCALAR", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
488         goto error;
489       if (!yaml_emitter_emit(&emitter, &output_event))
490         goto error;
491 
492       /* Display the scalar anchor. */
493 
494       if (input_event.data.scalar.anchor) {
495         /* Write 'anchor'. */
496 
497         if (!yaml_scalar_event_initialize(
498                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
499                 (yaml_char_t *)"anchor", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
500           goto error;
501         if (!yaml_emitter_emit(&emitter, &output_event))
502           goto error;
503 
504         /* Write the scalar anchor. */
505 
506         if (!yaml_scalar_event_initialize(
507                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
508                 input_event.data.scalar.anchor, -1, 0, 1,
509                 YAML_DOUBLE_QUOTED_SCALAR_STYLE))
510           goto error;
511         if (!yaml_emitter_emit(&emitter, &output_event))
512           goto error;
513       }
514 
515       /* Display the scalar tag. */
516 
517       if (input_event.data.scalar.tag) {
518         /* Write 'tag'. */
519 
520         if (!yaml_scalar_event_initialize(
521                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
522                 (yaml_char_t *)"tag", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
523           goto error;
524         if (!yaml_emitter_emit(&emitter, &output_event))
525           goto error;
526 
527         /* Write the scalar tag. */
528 
529         if (!yaml_scalar_event_initialize(
530                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
531                 input_event.data.scalar.tag, -1, 0, 1,
532                 YAML_DOUBLE_QUOTED_SCALAR_STYLE))
533           goto error;
534         if (!yaml_emitter_emit(&emitter, &output_event))
535           goto error;
536       }
537 
538       /* Display the scalar value. */
539 
540       /* Write 'value'. */
541 
542       if (!yaml_scalar_event_initialize(
543               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
544               (yaml_char_t *)"value", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
545         goto error;
546       if (!yaml_emitter_emit(&emitter, &output_event))
547         goto error;
548 
549       /* Write the scalar value. */
550 
551       if (!yaml_scalar_event_initialize(
552               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
553               input_event.data.scalar.value, input_event.data.scalar.length, 0,
554               1, YAML_DOUBLE_QUOTED_SCALAR_STYLE))
555         goto error;
556       if (!yaml_emitter_emit(&emitter, &output_event))
557         goto error;
558 
559       /* Display if the scalar tag is implicit. */
560 
561       /* Write 'implicit'. */
562 
563       if (!yaml_scalar_event_initialize(
564               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
565               (yaml_char_t *)"implicit", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
566         goto error;
567       if (!yaml_emitter_emit(&emitter, &output_event))
568         goto error;
569 
570       /* Write '{'. */
571 
572       if (!yaml_mapping_start_event_initialize(
573               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:map", 1,
574               YAML_FLOW_MAPPING_STYLE))
575         goto error;
576       if (!yaml_emitter_emit(&emitter, &output_event))
577         goto error;
578 
579       /* Write 'plain'. */
580 
581       if (!yaml_scalar_event_initialize(
582               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
583               (yaml_char_t *)"plain", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
584         goto error;
585       if (!yaml_emitter_emit(&emitter, &output_event))
586         goto error;
587 
588       /* Write if the scalar is implicit in the plain style. */
589 
590       if (!yaml_scalar_event_initialize(
591               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:bool",
592               (yaml_char_t *)(input_event.data.scalar.plain_implicit ? "true"
593                                                                      : "false"),
594               -1, 1, 0, YAML_PLAIN_SCALAR_STYLE))
595         goto error;
596       if (!yaml_emitter_emit(&emitter, &output_event))
597         goto error;
598 
599       /* Write 'quoted'. */
600 
601       if (!yaml_scalar_event_initialize(
602               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
603               (yaml_char_t *)"non-plain", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
604         goto error;
605       if (!yaml_emitter_emit(&emitter, &output_event))
606         goto error;
607 
608       /* Write if the scalar is implicit in a non-plain style. */
609 
610       if (!yaml_scalar_event_initialize(
611               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:bool",
612               (yaml_char_t *)(input_event.data.scalar.quoted_implicit
613                                   ? "true"
614                                   : "false"),
615               -1, 1, 0, YAML_PLAIN_SCALAR_STYLE))
616         goto error;
617       if (!yaml_emitter_emit(&emitter, &output_event))
618         goto error;
619 
620       /* Write '}'. */
621 
622       if (!yaml_mapping_end_event_initialize(&output_event))
623         goto error;
624       if (!yaml_emitter_emit(&emitter, &output_event))
625         goto error;
626 
627       /* Display the style information. */
628 
629       if (input_event.data.scalar.style) {
630         yaml_scalar_style_t style = input_event.data.scalar.style;
631 
632         /* Write 'style'. */
633 
634         if (!yaml_scalar_event_initialize(
635                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
636                 (yaml_char_t *)"style", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
637           goto error;
638         if (!yaml_emitter_emit(&emitter, &output_event))
639           goto error;
640 
641         /* Write the scalar style. */
642 
643         if (!yaml_scalar_event_initialize(
644                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
645                 (yaml_char_t
646                      *)(style == YAML_PLAIN_SCALAR_STYLE
647                             ? "plain"
648                             : style == YAML_SINGLE_QUOTED_SCALAR_STYLE
649                                   ? "single-quoted"
650                                   : style == YAML_DOUBLE_QUOTED_SCALAR_STYLE
651                                         ? "double-quoted"
652                                         : style == YAML_LITERAL_SCALAR_STYLE
653                                               ? "literal"
654                                               : style ==
655                                                         YAML_FOLDED_SCALAR_STYLE
656                                                     ? "folded"
657                                                     : "unknown"),
658                 -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
659           goto error;
660         if (!yaml_emitter_emit(&emitter, &output_event))
661           goto error;
662       }
663 
664       break;
665 
666     case YAML_SEQUENCE_START_EVENT:
667 
668       /* Write 'type'. */
669 
670       if (!yaml_scalar_event_initialize(
671               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
672               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
673         goto error;
674       if (!yaml_emitter_emit(&emitter, &output_event))
675         goto error;
676 
677       /* Write 'SEQUENCE-START'. */
678 
679       if (!yaml_scalar_event_initialize(&output_event, NULL,
680                                         (yaml_char_t *)"tag:yaml.org,2002:str",
681                                         (yaml_char_t *)"SEQUENCE-START", -1, 1,
682                                         1, YAML_PLAIN_SCALAR_STYLE))
683         goto error;
684       if (!yaml_emitter_emit(&emitter, &output_event))
685         goto error;
686 
687       /* Display the sequence anchor. */
688 
689       if (input_event.data.sequence_start.anchor) {
690         /* Write 'anchor'. */
691 
692         if (!yaml_scalar_event_initialize(
693                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
694                 (yaml_char_t *)"anchor", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
695           goto error;
696         if (!yaml_emitter_emit(&emitter, &output_event))
697           goto error;
698 
699         /* Write the sequence anchor. */
700 
701         if (!yaml_scalar_event_initialize(
702                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
703                 input_event.data.sequence_start.anchor, -1, 0, 1,
704                 YAML_DOUBLE_QUOTED_SCALAR_STYLE))
705           goto error;
706         if (!yaml_emitter_emit(&emitter, &output_event))
707           goto error;
708       }
709 
710       /* Display the sequence tag. */
711 
712       if (input_event.data.sequence_start.tag) {
713         /* Write 'tag'. */
714 
715         if (!yaml_scalar_event_initialize(
716                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
717                 (yaml_char_t *)"tag", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
718           goto error;
719         if (!yaml_emitter_emit(&emitter, &output_event))
720           goto error;
721 
722         /* Write the sequence tag. */
723 
724         if (!yaml_scalar_event_initialize(
725                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
726                 input_event.data.sequence_start.tag, -1, 0, 1,
727                 YAML_DOUBLE_QUOTED_SCALAR_STYLE))
728           goto error;
729         if (!yaml_emitter_emit(&emitter, &output_event))
730           goto error;
731       }
732 
733       /* Write 'implicit'. */
734 
735       if (!yaml_scalar_event_initialize(
736               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
737               (yaml_char_t *)"implicit", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
738         goto error;
739       if (!yaml_emitter_emit(&emitter, &output_event))
740         goto error;
741 
742       /* Write if the sequence tag is implicit. */
743 
744       if (!yaml_scalar_event_initialize(
745               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:bool",
746               (yaml_char_t *)(input_event.data.sequence_start.implicit
747                                   ? "true"
748                                   : "false"),
749               -1, 1, 0, YAML_PLAIN_SCALAR_STYLE))
750         goto error;
751       if (!yaml_emitter_emit(&emitter, &output_event))
752         goto error;
753 
754       /* Display the style information. */
755 
756       if (input_event.data.sequence_start.style) {
757         yaml_sequence_style_t style = input_event.data.sequence_start.style;
758 
759         /* Write 'style'. */
760 
761         if (!yaml_scalar_event_initialize(
762                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
763                 (yaml_char_t *)"style", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
764           goto error;
765         if (!yaml_emitter_emit(&emitter, &output_event))
766           goto error;
767 
768         /* Write the scalar style. */
769 
770         if (!yaml_scalar_event_initialize(
771                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
772                 (yaml_char_t *)(style == YAML_BLOCK_SEQUENCE_STYLE
773                                     ? "block"
774                                     : style == YAML_FLOW_SEQUENCE_STYLE
775                                           ? "flow"
776                                           : "unknown"),
777                 -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
778           goto error;
779         if (!yaml_emitter_emit(&emitter, &output_event))
780           goto error;
781       }
782 
783       break;
784 
785     case YAML_SEQUENCE_END_EVENT:
786 
787       /* Write 'type'. */
788 
789       if (!yaml_scalar_event_initialize(
790               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
791               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
792         goto error;
793       if (!yaml_emitter_emit(&emitter, &output_event))
794         goto error;
795 
796       /* Write 'SEQUENCE-END'. */
797 
798       if (!yaml_scalar_event_initialize(
799               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
800               (yaml_char_t *)"SEQUENCE-END", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
801         goto error;
802       if (!yaml_emitter_emit(&emitter, &output_event))
803         goto error;
804 
805       break;
806 
807     case YAML_MAPPING_START_EVENT:
808 
809       /* Write 'type'. */
810 
811       if (!yaml_scalar_event_initialize(
812               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
813               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
814         goto error;
815       if (!yaml_emitter_emit(&emitter, &output_event))
816         goto error;
817 
818       /* Write 'MAPPING-START'. */
819 
820       if (!yaml_scalar_event_initialize(&output_event, NULL,
821                                         (yaml_char_t *)"tag:yaml.org,2002:str",
822                                         (yaml_char_t *)"MAPPING-START", -1, 1,
823                                         1, YAML_PLAIN_SCALAR_STYLE))
824         goto error;
825       if (!yaml_emitter_emit(&emitter, &output_event))
826         goto error;
827 
828       /* Display the mapping anchor. */
829 
830       if (input_event.data.mapping_start.anchor) {
831         /* Write 'anchor'. */
832 
833         if (!yaml_scalar_event_initialize(
834                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
835                 (yaml_char_t *)"anchor", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
836           goto error;
837         if (!yaml_emitter_emit(&emitter, &output_event))
838           goto error;
839 
840         /* Write the mapping anchor. */
841 
842         if (!yaml_scalar_event_initialize(
843                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
844                 input_event.data.mapping_start.anchor, -1, 0, 1,
845                 YAML_DOUBLE_QUOTED_SCALAR_STYLE))
846           goto error;
847         if (!yaml_emitter_emit(&emitter, &output_event))
848           goto error;
849       }
850 
851       /* Display the mapping tag. */
852 
853       if (input_event.data.mapping_start.tag) {
854         /* Write 'tag'. */
855 
856         if (!yaml_scalar_event_initialize(
857                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
858                 (yaml_char_t *)"tag", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
859           goto error;
860         if (!yaml_emitter_emit(&emitter, &output_event))
861           goto error;
862 
863         /* Write the mapping tag. */
864 
865         if (!yaml_scalar_event_initialize(
866                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
867                 input_event.data.mapping_start.tag, -1, 0, 1,
868                 YAML_DOUBLE_QUOTED_SCALAR_STYLE))
869           goto error;
870         if (!yaml_emitter_emit(&emitter, &output_event))
871           goto error;
872       }
873 
874       /* Write 'implicit'. */
875 
876       if (!yaml_scalar_event_initialize(
877               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
878               (yaml_char_t *)"implicit", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
879         goto error;
880       if (!yaml_emitter_emit(&emitter, &output_event))
881         goto error;
882 
883       /* Write if the mapping tag is implicit. */
884 
885       if (!yaml_scalar_event_initialize(
886               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:bool",
887               (yaml_char_t *)(input_event.data.mapping_start.implicit
888                                   ? "true"
889                                   : "false"),
890               -1, 1, 0, YAML_PLAIN_SCALAR_STYLE))
891         goto error;
892       if (!yaml_emitter_emit(&emitter, &output_event))
893         goto error;
894 
895       /* Display the style information. */
896 
897       if (input_event.data.mapping_start.style) {
898         yaml_mapping_style_t style = input_event.data.mapping_start.style;
899 
900         /* Write 'style'. */
901 
902         if (!yaml_scalar_event_initialize(
903                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
904                 (yaml_char_t *)"style", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
905           goto error;
906         if (!yaml_emitter_emit(&emitter, &output_event))
907           goto error;
908 
909         /* Write the scalar style. */
910 
911         if (!yaml_scalar_event_initialize(
912                 &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
913                 (yaml_char_t *)(style == YAML_BLOCK_MAPPING_STYLE
914                                     ? "block"
915                                     : style == YAML_FLOW_MAPPING_STYLE
916                                           ? "flow"
917                                           : "unknown"),
918                 -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
919           goto error;
920         if (!yaml_emitter_emit(&emitter, &output_event))
921           goto error;
922       }
923 
924       break;
925 
926     case YAML_MAPPING_END_EVENT:
927 
928       /* Write 'type'. */
929 
930       if (!yaml_scalar_event_initialize(
931               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
932               (yaml_char_t *)"type", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
933         goto error;
934       if (!yaml_emitter_emit(&emitter, &output_event))
935         goto error;
936 
937       /* Write 'MAPPING-END'. */
938 
939       if (!yaml_scalar_event_initialize(
940               &output_event, NULL, (yaml_char_t *)"tag:yaml.org,2002:str",
941               (yaml_char_t *)"MAPPING-END", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE))
942         goto error;
943       if (!yaml_emitter_emit(&emitter, &output_event))
944         goto error;
945 
946       break;
947 
948     default:
949       /* It couldn't really happen. */
950       break;
951     }
952 
953     /* Delete the event object. */
954 
955     yaml_event_delete(&input_event);
956 
957     /* Create and emit a MAPPING-END event. */
958 
959     if (!yaml_mapping_end_event_initialize(&output_event))
960       goto error;
961     if (!yaml_emitter_emit(&emitter, &output_event))
962       goto error;
963   }
964 
965   /* Create and emit the SEQUENCE-END event. */
966 
967   if (!yaml_sequence_end_event_initialize(&output_event))
968     goto error;
969   if (!yaml_emitter_emit(&emitter, &output_event))
970     goto error;
971 
972   /* Create and emit the DOCUMENT-END event. */
973 
974   if (!yaml_document_end_event_initialize(&output_event, 0))
975     goto error;
976   if (!yaml_emitter_emit(&emitter, &output_event))
977     goto error;
978 
979   /* Create and emit the STREAM-END event. */
980 
981   if (!yaml_stream_end_event_initialize(&output_event))
982     goto error;
983   yaml_emitter_emit(&emitter, &output_event);
984 
985 error:
986 
987   free(out.buf);
988 
989   yaml_event_delete(&input_event);
990   yaml_parser_delete(&parser);
991   yaml_emitter_delete(&emitter);
992 
993   return 0;
994 }
995