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