1 
2 /*
3  * The parser implements the following grammar:
4  *
5  * stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
6  * implicit_document    ::= block_node DOCUMENT-END*
7  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
8  * block_node_or_indentless_sequence    ::=
9  *                          ALIAS
10  *                          | properties (block_content | indentless_block_sequence)?
11  *                          | block_content
12  *                          | indentless_block_sequence
13  * block_node           ::= ALIAS
14  *                          | properties block_content?
15  *                          | block_content
16  * flow_node            ::= ALIAS
17  *                          | properties flow_content?
18  *                          | flow_content
19  * properties           ::= TAG ANCHOR? | ANCHOR TAG?
20  * block_content        ::= block_collection | flow_collection | SCALAR
21  * flow_content         ::= flow_collection | SCALAR
22  * block_collection     ::= block_sequence | block_mapping
23  * flow_collection      ::= flow_sequence | flow_mapping
24  * block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
25  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
26  * block_mapping        ::= BLOCK-MAPPING_START
27  *                          ((KEY block_node_or_indentless_sequence?)?
28  *                          (VALUE block_node_or_indentless_sequence?)?)*
29  *                          BLOCK-END
30  * flow_sequence        ::= FLOW-SEQUENCE-START
31  *                          (flow_sequence_entry FLOW-ENTRY)*
32  *                          flow_sequence_entry?
33  *                          FLOW-SEQUENCE-END
34  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
35  * flow_mapping         ::= FLOW-MAPPING-START
36  *                          (flow_mapping_entry FLOW-ENTRY)*
37  *                          flow_mapping_entry?
38  *                          FLOW-MAPPING-END
39  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
40  */
41 
42 #include "yaml_private.h"
43 
44 /*
45  * Peek the next token in the token queue.
46  */
47 
48 #define PEEK_TOKEN(parser)                                                      \
49     ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
50         parser->tokens.head : NULL)
51 
52 /*
53  * Remove the next token from the queue (must be called after PEEK_TOKEN).
54  */
55 
56 #define SKIP_TOKEN(parser)                                                      \
57     (parser->token_available = 0,                                               \
58      parser->tokens_parsed ++,                                                  \
59      parser->stream_end_produced =                                              \
60         (parser->tokens.head->type == YAML_STREAM_END_TOKEN),                   \
61      parser->tokens.head ++)
62 
63 /*
64  * Public API declarations.
65  */
66 
67 YAML_DECLARE(int)
68 yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
69 
70 /*
71  * Error handling.
72  */
73 
74 static int
75 yaml_parser_set_parser_error(yaml_parser_t *parser,
76         const char *problem, yaml_mark_t problem_mark);
77 
78 static int
79 yaml_parser_set_parser_error_context(yaml_parser_t *parser,
80         const char *context, yaml_mark_t context_mark,
81         const char *problem, yaml_mark_t problem_mark);
82 
83 /*
84  * State functions.
85  */
86 
87 static int
88 yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
89 
90 static int
91 yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
92 
93 static int
94 yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
95         int implicit);
96 
97 static int
98 yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
99 
100 static int
101 yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
102 
103 static int
104 yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
105         int block, int indentless_sequence);
106 
107 static int
108 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109         yaml_event_t *event, int first);
110 
111 static int
112 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113         yaml_event_t *event);
114 
115 static int
116 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117         yaml_event_t *event, int first);
118 
119 static int
120 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121         yaml_event_t *event);
122 
123 static int
124 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125         yaml_event_t *event, int first);
126 
127 static int
128 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129         yaml_event_t *event);
130 
131 static int
132 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133         yaml_event_t *event);
134 
135 static int
136 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137         yaml_event_t *event);
138 
139 static int
140 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141         yaml_event_t *event, int first);
142 
143 static int
144 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145         yaml_event_t *event, int empty);
146 
147 /*
148  * Utility functions.
149  */
150 
151 static int
152 yaml_parser_process_empty_scalar(yaml_parser_t *parser,
153         yaml_event_t *event, yaml_mark_t mark);
154 
155 static int
156 yaml_parser_process_directives(yaml_parser_t *parser,
157         yaml_version_directive_t **version_directive_ref,
158         yaml_tag_directive_t **tag_directives_start_ref,
159         yaml_tag_directive_t **tag_directives_end_ref);
160 
161 static int
162 yaml_parser_append_tag_directive(yaml_parser_t *parser,
163         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
164 
165 /*
166  * Get the next event.
167  */
168 
169 YAML_DECLARE(int)
yaml_parser_parse(yaml_parser_t * parser,yaml_event_t * event)170 yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
171 {
172     assert(parser);     /* Non-NULL parser object is expected. */
173     assert(event);      /* Non-NULL event object is expected. */
174 
175     /* Erase the event object. */
176 
177     memset(event, 0, sizeof(yaml_event_t));
178 
179     /* No events after the end of the stream or error. */
180 
181     if (parser->stream_end_produced || parser->error ||
182             parser->state == YAML_PARSE_END_STATE) {
183         return 1;
184     }
185 
186     /* Generate the next event. */
187 
188     return yaml_parser_state_machine(parser, event);
189 }
190 
191 /*
192  * Set parser error.
193  */
194 
195 static int
yaml_parser_set_parser_error(yaml_parser_t * parser,const char * problem,yaml_mark_t problem_mark)196 yaml_parser_set_parser_error(yaml_parser_t *parser,
197         const char *problem, yaml_mark_t problem_mark)
198 {
199     parser->error = YAML_PARSER_ERROR;
200     parser->problem = problem;
201     parser->problem_mark = problem_mark;
202 
203     return 0;
204 }
205 
206 static int
yaml_parser_set_parser_error_context(yaml_parser_t * parser,const char * context,yaml_mark_t context_mark,const char * problem,yaml_mark_t problem_mark)207 yaml_parser_set_parser_error_context(yaml_parser_t *parser,
208         const char *context, yaml_mark_t context_mark,
209         const char *problem, yaml_mark_t problem_mark)
210 {
211     parser->error = YAML_PARSER_ERROR;
212     parser->context = context;
213     parser->context_mark = context_mark;
214     parser->problem = problem;
215     parser->problem_mark = problem_mark;
216 
217     return 0;
218 }
219 
220 
221 /*
222  * State dispatcher.
223  */
224 
225 static int
yaml_parser_state_machine(yaml_parser_t * parser,yaml_event_t * event)226 yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
227 {
228     switch (parser->state)
229     {
230         case YAML_PARSE_STREAM_START_STATE:
231             return yaml_parser_parse_stream_start(parser, event);
232 
233         case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
234             return yaml_parser_parse_document_start(parser, event, 1);
235 
236         case YAML_PARSE_DOCUMENT_START_STATE:
237             return yaml_parser_parse_document_start(parser, event, 0);
238 
239         case YAML_PARSE_DOCUMENT_CONTENT_STATE:
240             return yaml_parser_parse_document_content(parser, event);
241 
242         case YAML_PARSE_DOCUMENT_END_STATE:
243             return yaml_parser_parse_document_end(parser, event);
244 
245         case YAML_PARSE_BLOCK_NODE_STATE:
246             return yaml_parser_parse_node(parser, event, 1, 0);
247 
248         case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
249             return yaml_parser_parse_node(parser, event, 1, 1);
250 
251         case YAML_PARSE_FLOW_NODE_STATE:
252             return yaml_parser_parse_node(parser, event, 0, 0);
253 
254         case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
255             return yaml_parser_parse_block_sequence_entry(parser, event, 1);
256 
257         case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
258             return yaml_parser_parse_block_sequence_entry(parser, event, 0);
259 
260         case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
261             return yaml_parser_parse_indentless_sequence_entry(parser, event);
262 
263         case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
264             return yaml_parser_parse_block_mapping_key(parser, event, 1);
265 
266         case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
267             return yaml_parser_parse_block_mapping_key(parser, event, 0);
268 
269         case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
270             return yaml_parser_parse_block_mapping_value(parser, event);
271 
272         case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
273             return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
274 
275         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
276             return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
277 
278         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
279             return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
280 
281         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
282             return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
283 
284         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
285             return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
286 
287         case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
288             return yaml_parser_parse_flow_mapping_key(parser, event, 1);
289 
290         case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
291             return yaml_parser_parse_flow_mapping_key(parser, event, 0);
292 
293         case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
294             return yaml_parser_parse_flow_mapping_value(parser, event, 0);
295 
296         case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
297             return yaml_parser_parse_flow_mapping_value(parser, event, 1);
298 
299         default:
300             assert(1);      /* Invalid state. */
301     }
302 
303     return 0;
304 }
305 
306 /*
307  * Parse the production:
308  * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
309  *              ************
310  */
311 
312 static int
yaml_parser_parse_stream_start(yaml_parser_t * parser,yaml_event_t * event)313 yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
314 {
315     yaml_token_t *token;
316 
317     token = PEEK_TOKEN(parser);
318     if (!token) return 0;
319 
320     if (token->type != YAML_STREAM_START_TOKEN) {
321         return yaml_parser_set_parser_error(parser,
322                 "did not find expected <stream-start>", token->start_mark);
323     }
324 
325     parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
326     STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
327             token->start_mark, token->start_mark);
328     SKIP_TOKEN(parser);
329 
330     return 1;
331 }
332 
333 /*
334  * Parse the productions:
335  * implicit_document    ::= block_node DOCUMENT-END*
336  *                          *
337  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
338  *                          *************************
339  */
340 
341 static int
yaml_parser_parse_document_start(yaml_parser_t * parser,yaml_event_t * event,int implicit)342 yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
343         int implicit)
344 {
345     yaml_token_t *token;
346     yaml_version_directive_t *version_directive = NULL;
347     struct {
348         yaml_tag_directive_t *start;
349         yaml_tag_directive_t *end;
350     } tag_directives = { NULL, NULL };
351 
352     token = PEEK_TOKEN(parser);
353     if (!token) return 0;
354 
355     /* Parse extra document end indicators. */
356 
357     if (!implicit)
358     {
359         while (token->type == YAML_DOCUMENT_END_TOKEN) {
360             SKIP_TOKEN(parser);
361             token = PEEK_TOKEN(parser);
362             if (!token) return 0;
363         }
364     }
365 
366     /* Parse an implicit document. */
367 
368     if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
369             token->type != YAML_TAG_DIRECTIVE_TOKEN &&
370             token->type != YAML_DOCUMENT_START_TOKEN &&
371             token->type != YAML_STREAM_END_TOKEN)
372     {
373         if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
374             return 0;
375         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
376             return 0;
377         parser->state = YAML_PARSE_BLOCK_NODE_STATE;
378         DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
379                 token->start_mark, token->start_mark);
380         return 1;
381     }
382 
383     /* Parse an explicit document. */
384 
385     else if (token->type != YAML_STREAM_END_TOKEN)
386     {
387         yaml_mark_t start_mark, end_mark;
388         start_mark = token->start_mark;
389         if (!yaml_parser_process_directives(parser, &version_directive,
390                     &tag_directives.start, &tag_directives.end))
391             return 0;
392         token = PEEK_TOKEN(parser);
393         if (!token) goto error;
394         if (token->type != YAML_DOCUMENT_START_TOKEN) {
395             yaml_parser_set_parser_error(parser,
396                     "did not find expected <document start>", token->start_mark);
397             goto error;
398         }
399         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
400             goto error;
401         parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
402         end_mark = token->end_mark;
403         DOCUMENT_START_EVENT_INIT(*event, version_directive,
404                 tag_directives.start, tag_directives.end, 0,
405                 start_mark, end_mark);
406         SKIP_TOKEN(parser);
407         version_directive = NULL;
408         tag_directives.start = tag_directives.end = NULL;
409         return 1;
410     }
411 
412     /* Parse the stream end. */
413 
414     else
415     {
416         parser->state = YAML_PARSE_END_STATE;
417         STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
418         SKIP_TOKEN(parser);
419         return 1;
420     }
421 
422 error:
423     yaml_free(version_directive);
424     while (tag_directives.start != tag_directives.end) {
425         yaml_free(tag_directives.end[-1].handle);
426         yaml_free(tag_directives.end[-1].prefix);
427         tag_directives.end --;
428     }
429     yaml_free(tag_directives.start);
430     return 0;
431 }
432 
433 /*
434  * Parse the productions:
435  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
436  *                                                    ***********
437  */
438 
439 static int
yaml_parser_parse_document_content(yaml_parser_t * parser,yaml_event_t * event)440 yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
441 {
442     yaml_token_t *token;
443 
444     token = PEEK_TOKEN(parser);
445     if (!token) return 0;
446 
447     if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
448             token->type == YAML_TAG_DIRECTIVE_TOKEN ||
449             token->type == YAML_DOCUMENT_START_TOKEN ||
450             token->type == YAML_DOCUMENT_END_TOKEN ||
451             token->type == YAML_STREAM_END_TOKEN) {
452         parser->state = POP(parser, parser->states);
453         return yaml_parser_process_empty_scalar(parser, event,
454                 token->start_mark);
455     }
456     else {
457         return yaml_parser_parse_node(parser, event, 1, 0);
458     }
459 }
460 
461 /*
462  * Parse the productions:
463  * implicit_document    ::= block_node DOCUMENT-END*
464  *                                     *************
465  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
466  *                                                                *************
467  */
468 
469 static int
yaml_parser_parse_document_end(yaml_parser_t * parser,yaml_event_t * event)470 yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
471 {
472     yaml_token_t *token;
473     yaml_mark_t start_mark, end_mark;
474     int implicit = 1;
475 
476     token = PEEK_TOKEN(parser);
477     if (!token) return 0;
478 
479     start_mark = end_mark = token->start_mark;
480 
481     if (token->type == YAML_DOCUMENT_END_TOKEN) {
482         end_mark = token->end_mark;
483         SKIP_TOKEN(parser);
484         implicit = 0;
485     }
486 
487     while (!STACK_EMPTY(parser, parser->tag_directives)) {
488         yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
489         yaml_free(tag_directive.handle);
490         yaml_free(tag_directive.prefix);
491     }
492 
493     parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494     DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
495 
496     return 1;
497 }
498 
499 /*
500  * Parse the productions:
501  * block_node_or_indentless_sequence    ::=
502  *                          ALIAS
503  *                          *****
504  *                          | properties (block_content | indentless_block_sequence)?
505  *                            **********  *
506  *                          | block_content | indentless_block_sequence
507  *                            *
508  * block_node           ::= ALIAS
509  *                          *****
510  *                          | properties block_content?
511  *                            ********** *
512  *                          | block_content
513  *                            *
514  * flow_node            ::= ALIAS
515  *                          *****
516  *                          | properties flow_content?
517  *                            ********** *
518  *                          | flow_content
519  *                            *
520  * properties           ::= TAG ANCHOR? | ANCHOR TAG?
521  *                          *************************
522  * block_content        ::= block_collection | flow_collection | SCALAR
523  *                                                               ******
524  * flow_content         ::= flow_collection | SCALAR
525  *                                            ******
526  */
527 
528 static int
yaml_parser_parse_node(yaml_parser_t * parser,yaml_event_t * event,int block,int indentless_sequence)529 yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
530         int block, int indentless_sequence)
531 {
532     yaml_token_t *token;
533     yaml_char_t *anchor = NULL;
534     yaml_char_t *tag_handle = NULL;
535     yaml_char_t *tag_suffix = NULL;
536     yaml_char_t *tag = NULL;
537     yaml_mark_t start_mark, end_mark, tag_mark;
538     int implicit;
539 
540     token = PEEK_TOKEN(parser);
541     if (!token) return 0;
542 
543     if (token->type == YAML_ALIAS_TOKEN)
544     {
545         parser->state = POP(parser, parser->states);
546         ALIAS_EVENT_INIT(*event, token->data.alias.value,
547                 token->start_mark, token->end_mark);
548         SKIP_TOKEN(parser);
549         return 1;
550     }
551 
552     else
553     {
554         start_mark = end_mark = token->start_mark;
555 
556         if (token->type == YAML_ANCHOR_TOKEN)
557         {
558             anchor = token->data.anchor.value;
559             start_mark = token->start_mark;
560             end_mark = token->end_mark;
561             SKIP_TOKEN(parser);
562             token = PEEK_TOKEN(parser);
563             if (!token) goto error;
564             if (token->type == YAML_TAG_TOKEN)
565             {
566                 tag_handle = token->data.tag.handle;
567                 tag_suffix = token->data.tag.suffix;
568                 tag_mark = token->start_mark;
569                 end_mark = token->end_mark;
570                 SKIP_TOKEN(parser);
571                 token = PEEK_TOKEN(parser);
572                 if (!token) goto error;
573             }
574         }
575         else if (token->type == YAML_TAG_TOKEN)
576         {
577             tag_handle = token->data.tag.handle;
578             tag_suffix = token->data.tag.suffix;
579             start_mark = tag_mark = token->start_mark;
580             end_mark = token->end_mark;
581             SKIP_TOKEN(parser);
582             token = PEEK_TOKEN(parser);
583             if (!token) goto error;
584             if (token->type == YAML_ANCHOR_TOKEN)
585             {
586                 anchor = token->data.anchor.value;
587                 end_mark = token->end_mark;
588                 SKIP_TOKEN(parser);
589                 token = PEEK_TOKEN(parser);
590                 if (!token) goto error;
591             }
592         }
593 
594         if (tag_handle) {
595             if (!*tag_handle) {
596                 tag = tag_suffix;
597                 yaml_free(tag_handle);
598                 tag_handle = tag_suffix = NULL;
599             }
600             else {
601                 yaml_tag_directive_t *tag_directive;
602                 for (tag_directive = parser->tag_directives.start;
603                         tag_directive != parser->tag_directives.top;
604                         tag_directive ++) {
605                     if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
606                         size_t prefix_len = strlen((char *)tag_directive->prefix);
607                         size_t suffix_len = strlen((char *)tag_suffix);
608                         tag = yaml_malloc(prefix_len+suffix_len+1);
609                         if (!tag) {
610                             parser->error = YAML_MEMORY_ERROR;
611                             goto error;
612                         }
613                         memcpy(tag, tag_directive->prefix, prefix_len);
614                         memcpy(tag+prefix_len, tag_suffix, suffix_len);
615                         tag[prefix_len+suffix_len] = '\0';
616                         yaml_free(tag_handle);
617                         yaml_free(tag_suffix);
618                         tag_handle = tag_suffix = NULL;
619                         break;
620                     }
621                 }
622                 if (!tag) {
623                     yaml_parser_set_parser_error_context(parser,
624                             "while parsing a node", start_mark,
625                             "found undefined tag handle", tag_mark);
626                     goto error;
627                 }
628             }
629         }
630 
631         implicit = (!tag || !*tag);
632         if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
633             end_mark = token->end_mark;
634             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
635             SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
636                     YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
637             return 1;
638         }
639         else {
640             if (token->type == YAML_SCALAR_TOKEN) {
641                 int plain_implicit = 0;
642                 int quoted_implicit = 0;
643                 end_mark = token->end_mark;
644                 if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
645                         || (tag && strcmp((char *)tag, "!") == 0)) {
646                     plain_implicit = 1;
647                 }
648                 else if (!tag) {
649                     quoted_implicit = 1;
650                 }
651                 parser->state = POP(parser, parser->states);
652                 SCALAR_EVENT_INIT(*event, anchor, tag,
653                         token->data.scalar.value, token->data.scalar.length,
654                         plain_implicit, quoted_implicit,
655                         token->data.scalar.style, start_mark, end_mark);
656                 SKIP_TOKEN(parser);
657                 return 1;
658             }
659             else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
660                 end_mark = token->end_mark;
661                 parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
662                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
663                         YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
664                 return 1;
665             }
666             else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
667                 end_mark = token->end_mark;
668                 parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
669                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
670                         YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
671                 return 1;
672             }
673             else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
674                 end_mark = token->end_mark;
675                 parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
676                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
677                         YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
678                 return 1;
679             }
680             else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
681                 end_mark = token->end_mark;
682                 parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
683                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
684                         YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
685                 return 1;
686             }
687             else if (anchor || tag) {
688                 yaml_char_t *value = yaml_malloc(1);
689                 if (!value) {
690                     parser->error = YAML_MEMORY_ERROR;
691                     goto error;
692                 }
693                 value[0] = '\0';
694                 parser->state = POP(parser, parser->states);
695                 SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
696                         implicit, 0, YAML_PLAIN_SCALAR_STYLE,
697                         start_mark, end_mark);
698                 return 1;
699             }
700             else {
701                 yaml_parser_set_parser_error_context(parser,
702                         (block ? "while parsing a block node"
703                          : "while parsing a flow node"), start_mark,
704                         "did not find expected node content", token->start_mark);
705                 goto error;
706             }
707         }
708     }
709 
710 error:
711     yaml_free(anchor);
712     yaml_free(tag_handle);
713     yaml_free(tag_suffix);
714     yaml_free(tag);
715 
716     return 0;
717 }
718 
719 /*
720  * Parse the productions:
721  * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722  *                    ********************  *********** *             *********
723  */
724 
725 static int
yaml_parser_parse_block_sequence_entry(yaml_parser_t * parser,yaml_event_t * event,int first)726 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
727         yaml_event_t *event, int first)
728 {
729     yaml_token_t *token;
730 
731     if (first) {
732         token = PEEK_TOKEN(parser);
733         if (!PUSH(parser, parser->marks, token->start_mark))
734             return 0;
735         SKIP_TOKEN(parser);
736     }
737 
738     token = PEEK_TOKEN(parser);
739     if (!token) return 0;
740 
741     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
742     {
743         yaml_mark_t mark = token->end_mark;
744         SKIP_TOKEN(parser);
745         token = PEEK_TOKEN(parser);
746         if (!token) return 0;
747         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
748                 token->type != YAML_BLOCK_END_TOKEN) {
749             if (!PUSH(parser, parser->states,
750                         YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
751                 return 0;
752             return yaml_parser_parse_node(parser, event, 1, 0);
753         }
754         else {
755             parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
756             return yaml_parser_process_empty_scalar(parser, event, mark);
757         }
758     }
759 
760     else if (token->type == YAML_BLOCK_END_TOKEN)
761     {
762         yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
763         parser->state = POP(parser, parser->states);
764         dummy_mark = POP(parser, parser->marks);
765         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
766         SKIP_TOKEN(parser);
767         return 1;
768     }
769 
770     else
771     {
772         return yaml_parser_set_parser_error_context(parser,
773                 "while parsing a block collection", POP(parser, parser->marks),
774                 "did not find expected '-' indicator", token->start_mark);
775     }
776 }
777 
778 /*
779  * Parse the productions:
780  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
781  *                           *********** *
782  */
783 
784 static int
yaml_parser_parse_indentless_sequence_entry(yaml_parser_t * parser,yaml_event_t * event)785 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
786         yaml_event_t *event)
787 {
788     yaml_token_t *token;
789 
790     token = PEEK_TOKEN(parser);
791     if (!token) return 0;
792 
793     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
794     {
795         yaml_mark_t mark = token->end_mark;
796         SKIP_TOKEN(parser);
797         token = PEEK_TOKEN(parser);
798         if (!token) return 0;
799         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
800                 token->type != YAML_KEY_TOKEN &&
801                 token->type != YAML_VALUE_TOKEN &&
802                 token->type != YAML_BLOCK_END_TOKEN) {
803             if (!PUSH(parser, parser->states,
804                         YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
805                 return 0;
806             return yaml_parser_parse_node(parser, event, 1, 0);
807         }
808         else {
809             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
810             return yaml_parser_process_empty_scalar(parser, event, mark);
811         }
812     }
813 
814     else
815     {
816         parser->state = POP(parser, parser->states);
817         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
818         return 1;
819     }
820 }
821 
822 /*
823  * Parse the productions:
824  * block_mapping        ::= BLOCK-MAPPING_START
825  *                          *******************
826  *                          ((KEY block_node_or_indentless_sequence?)?
827  *                            *** *
828  *                          (VALUE block_node_or_indentless_sequence?)?)*
829  *
830  *                          BLOCK-END
831  *                          *********
832  */
833 
834 static int
yaml_parser_parse_block_mapping_key(yaml_parser_t * parser,yaml_event_t * event,int first)835 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
836         yaml_event_t *event, int first)
837 {
838     yaml_token_t *token;
839 
840     if (first) {
841         token = PEEK_TOKEN(parser);
842         if (!PUSH(parser, parser->marks, token->start_mark))
843             return 0;
844         SKIP_TOKEN(parser);
845     }
846 
847     token = PEEK_TOKEN(parser);
848     if (!token) return 0;
849 
850     if (token->type == YAML_KEY_TOKEN)
851     {
852         yaml_mark_t mark = token->end_mark;
853         SKIP_TOKEN(parser);
854         token = PEEK_TOKEN(parser);
855         if (!token) return 0;
856         if (token->type != YAML_KEY_TOKEN &&
857                 token->type != YAML_VALUE_TOKEN &&
858                 token->type != YAML_BLOCK_END_TOKEN) {
859             if (!PUSH(parser, parser->states,
860                         YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
861                 return 0;
862             return yaml_parser_parse_node(parser, event, 1, 1);
863         }
864         else {
865             parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
866             return yaml_parser_process_empty_scalar(parser, event, mark);
867         }
868     }
869 
870     else if (token->type == YAML_BLOCK_END_TOKEN)
871     {
872         yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
873         parser->state = POP(parser, parser->states);
874         dummy_mark = POP(parser, parser->marks);
875         MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
876         SKIP_TOKEN(parser);
877         return 1;
878     }
879 
880     else
881     {
882         return yaml_parser_set_parser_error_context(parser,
883                 "while parsing a block mapping", POP(parser, parser->marks),
884                 "did not find expected key", token->start_mark);
885     }
886 }
887 
888 /*
889  * Parse the productions:
890  * block_mapping        ::= BLOCK-MAPPING_START
891  *
892  *                          ((KEY block_node_or_indentless_sequence?)?
893  *
894  *                          (VALUE block_node_or_indentless_sequence?)?)*
895  *                           ***** *
896  *                          BLOCK-END
897  *
898  */
899 
900 static int
yaml_parser_parse_block_mapping_value(yaml_parser_t * parser,yaml_event_t * event)901 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
902         yaml_event_t *event)
903 {
904     yaml_token_t *token;
905 
906     token = PEEK_TOKEN(parser);
907     if (!token) return 0;
908 
909     if (token->type == YAML_VALUE_TOKEN)
910     {
911         yaml_mark_t mark = token->end_mark;
912         SKIP_TOKEN(parser);
913         token = PEEK_TOKEN(parser);
914         if (!token) return 0;
915         if (token->type != YAML_KEY_TOKEN &&
916                 token->type != YAML_VALUE_TOKEN &&
917                 token->type != YAML_BLOCK_END_TOKEN) {
918             if (!PUSH(parser, parser->states,
919                         YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
920                 return 0;
921             return yaml_parser_parse_node(parser, event, 1, 1);
922         }
923         else {
924             parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
925             return yaml_parser_process_empty_scalar(parser, event, mark);
926         }
927     }
928 
929     else
930     {
931         parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
932         return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
933     }
934 }
935 
936 /*
937  * Parse the productions:
938  * flow_sequence        ::= FLOW-SEQUENCE-START
939  *                          *******************
940  *                          (flow_sequence_entry FLOW-ENTRY)*
941  *                           *                   **********
942  *                          flow_sequence_entry?
943  *                          *
944  *                          FLOW-SEQUENCE-END
945  *                          *****************
946  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
947  *                          *
948  */
949 
950 static int
yaml_parser_parse_flow_sequence_entry(yaml_parser_t * parser,yaml_event_t * event,int first)951 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
952         yaml_event_t *event, int first)
953 {
954     yaml_token_t *token;
955     yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
956 
957     if (first) {
958         token = PEEK_TOKEN(parser);
959         if (!PUSH(parser, parser->marks, token->start_mark))
960             return 0;
961         SKIP_TOKEN(parser);
962     }
963 
964     token = PEEK_TOKEN(parser);
965     if (!token) return 0;
966 
967     if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
968     {
969         if (!first) {
970             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
971                 SKIP_TOKEN(parser);
972                 token = PEEK_TOKEN(parser);
973                 if (!token) return 0;
974             }
975             else {
976                 return yaml_parser_set_parser_error_context(parser,
977                         "while parsing a flow sequence", POP(parser, parser->marks),
978                         "did not find expected ',' or ']'", token->start_mark);
979             }
980         }
981 
982         if (token->type == YAML_KEY_TOKEN) {
983             parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
984             MAPPING_START_EVENT_INIT(*event, NULL, NULL,
985                     1, YAML_FLOW_MAPPING_STYLE,
986                     token->start_mark, token->end_mark);
987             SKIP_TOKEN(parser);
988             return 1;
989         }
990 
991         else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
992             if (!PUSH(parser, parser->states,
993                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
994                 return 0;
995             return yaml_parser_parse_node(parser, event, 0, 0);
996         }
997     }
998 
999     parser->state = POP(parser, parser->states);
1000     dummy_mark = POP(parser, parser->marks);
1001     SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1002     SKIP_TOKEN(parser);
1003     return 1;
1004 }
1005 
1006 /*
1007  * Parse the productions:
1008  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1009  *                                      *** *
1010  */
1011 
1012 static int
yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t * parser,yaml_event_t * event)1013 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1014         yaml_event_t *event)
1015 {
1016     yaml_token_t *token;
1017 
1018     token = PEEK_TOKEN(parser);
1019     if (!token) return 0;
1020 
1021     if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1022             && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1023         if (!PUSH(parser, parser->states,
1024                     YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1025             return 0;
1026         return yaml_parser_parse_node(parser, event, 0, 0);
1027     }
1028     else {
1029         yaml_mark_t mark = token->end_mark;
1030         SKIP_TOKEN(parser);
1031         parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1032         return yaml_parser_process_empty_scalar(parser, event, mark);
1033     }
1034 }
1035 
1036 /*
1037  * Parse the productions:
1038  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1039  *                                                      ***** *
1040  */
1041 
1042 static int
yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t * parser,yaml_event_t * event)1043 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1044         yaml_event_t *event)
1045 {
1046     yaml_token_t *token;
1047 
1048     token = PEEK_TOKEN(parser);
1049     if (!token) return 0;
1050 
1051     if (token->type == YAML_VALUE_TOKEN) {
1052         SKIP_TOKEN(parser);
1053         token = PEEK_TOKEN(parser);
1054         if (!token) return 0;
1055         if (token->type != YAML_FLOW_ENTRY_TOKEN
1056                 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1057             if (!PUSH(parser, parser->states,
1058                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1059                 return 0;
1060             return yaml_parser_parse_node(parser, event, 0, 0);
1061         }
1062     }
1063     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1064     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1065 }
1066 
1067 /*
1068  * Parse the productions:
1069  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1070  *                                                                      *
1071  */
1072 
1073 static int
yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t * parser,yaml_event_t * event)1074 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1075         yaml_event_t *event)
1076 {
1077     yaml_token_t *token;
1078 
1079     token = PEEK_TOKEN(parser);
1080     if (!token) return 0;
1081 
1082     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1083 
1084     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1085     return 1;
1086 }
1087 
1088 /*
1089  * Parse the productions:
1090  * flow_mapping         ::= FLOW-MAPPING-START
1091  *                          ******************
1092  *                          (flow_mapping_entry FLOW-ENTRY)*
1093  *                           *                  **********
1094  *                          flow_mapping_entry?
1095  *                          ******************
1096  *                          FLOW-MAPPING-END
1097  *                          ****************
1098  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1099  *                          *           *** *
1100  */
1101 
1102 static int
yaml_parser_parse_flow_mapping_key(yaml_parser_t * parser,yaml_event_t * event,int first)1103 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1104         yaml_event_t *event, int first)
1105 {
1106     yaml_token_t *token;
1107     yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
1108 
1109     if (first) {
1110         token = PEEK_TOKEN(parser);
1111         if (!PUSH(parser, parser->marks, token->start_mark))
1112             return 0;
1113         SKIP_TOKEN(parser);
1114     }
1115 
1116     token = PEEK_TOKEN(parser);
1117     if (!token) return 0;
1118 
1119     if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1120     {
1121         if (!first) {
1122             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1123                 SKIP_TOKEN(parser);
1124                 token = PEEK_TOKEN(parser);
1125                 if (!token) return 0;
1126             }
1127             else {
1128                 return yaml_parser_set_parser_error_context(parser,
1129                         "while parsing a flow mapping", POP(parser, parser->marks),
1130                         "did not find expected ',' or '}'", token->start_mark);
1131             }
1132         }
1133 
1134         if (token->type == YAML_KEY_TOKEN) {
1135             SKIP_TOKEN(parser);
1136             token = PEEK_TOKEN(parser);
1137             if (!token) return 0;
1138             if (token->type != YAML_VALUE_TOKEN
1139                     && token->type != YAML_FLOW_ENTRY_TOKEN
1140                     && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1141                 if (!PUSH(parser, parser->states,
1142                             YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1143                     return 0;
1144                 return yaml_parser_parse_node(parser, event, 0, 0);
1145             }
1146             else {
1147                 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1148                 return yaml_parser_process_empty_scalar(parser, event,
1149                         token->start_mark);
1150             }
1151         }
1152         else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1153             if (!PUSH(parser, parser->states,
1154                         YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1155                 return 0;
1156             return yaml_parser_parse_node(parser, event, 0, 0);
1157         }
1158     }
1159 
1160     parser->state = POP(parser, parser->states);
1161     dummy_mark = POP(parser, parser->marks);
1162     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1163     SKIP_TOKEN(parser);
1164     return 1;
1165 }
1166 
1167 /*
1168  * Parse the productions:
1169  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1170  *                                   *                  ***** *
1171  */
1172 
1173 static int
yaml_parser_parse_flow_mapping_value(yaml_parser_t * parser,yaml_event_t * event,int empty)1174 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1175         yaml_event_t *event, int empty)
1176 {
1177     yaml_token_t *token;
1178 
1179     token = PEEK_TOKEN(parser);
1180     if (!token) return 0;
1181 
1182     if (empty) {
1183         parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1184         return yaml_parser_process_empty_scalar(parser, event,
1185                 token->start_mark);
1186     }
1187 
1188     if (token->type == YAML_VALUE_TOKEN) {
1189         SKIP_TOKEN(parser);
1190         token = PEEK_TOKEN(parser);
1191         if (!token) return 0;
1192         if (token->type != YAML_FLOW_ENTRY_TOKEN
1193                 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1194             if (!PUSH(parser, parser->states,
1195                         YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1196                 return 0;
1197             return yaml_parser_parse_node(parser, event, 0, 0);
1198         }
1199     }
1200 
1201     parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1202     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1203 }
1204 
1205 /*
1206  * Generate an empty scalar event.
1207  */
1208 
1209 static int
yaml_parser_process_empty_scalar(yaml_parser_t * parser,yaml_event_t * event,yaml_mark_t mark)1210 yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1211         yaml_mark_t mark)
1212 {
1213     yaml_char_t *value;
1214 
1215     value = yaml_malloc(1);
1216     if (!value) {
1217         parser->error = YAML_MEMORY_ERROR;
1218         return 0;
1219     }
1220     value[0] = '\0';
1221 
1222     SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1223             1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1224 
1225     return 1;
1226 }
1227 
1228 /*
1229  * Parse directives.
1230  */
1231 
1232 static int
yaml_parser_process_directives(yaml_parser_t * parser,yaml_version_directive_t ** version_directive_ref,yaml_tag_directive_t ** tag_directives_start_ref,yaml_tag_directive_t ** tag_directives_end_ref)1233 yaml_parser_process_directives(yaml_parser_t *parser,
1234         yaml_version_directive_t **version_directive_ref,
1235         yaml_tag_directive_t **tag_directives_start_ref,
1236         yaml_tag_directive_t **tag_directives_end_ref)
1237 {
1238     yaml_tag_directive_t default_tag_directives[] = {
1239         {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1240         {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1241         {NULL, NULL}
1242     };
1243     yaml_tag_directive_t *default_tag_directive;
1244     yaml_version_directive_t *version_directive = NULL;
1245     struct {
1246         yaml_tag_directive_t *start;
1247         yaml_tag_directive_t *end;
1248         yaml_tag_directive_t *top;
1249     } tag_directives = { NULL, NULL, NULL };
1250     yaml_token_t *token;
1251 
1252     if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1253         goto error;
1254 
1255     token = PEEK_TOKEN(parser);
1256     if (!token) goto error;
1257 
1258     while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1259             token->type == YAML_TAG_DIRECTIVE_TOKEN)
1260     {
1261         if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1262             if (version_directive) {
1263                 yaml_parser_set_parser_error(parser,
1264                         "found duplicate %YAML directive", token->start_mark);
1265                 goto error;
1266             }
1267             if (token->data.version_directive.major != 1
1268                     || token->data.version_directive.minor != 1) {
1269                 yaml_parser_set_parser_error(parser,
1270                         "found incompatible YAML document", token->start_mark);
1271                 goto error;
1272             }
1273             version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1274             if (!version_directive) {
1275                 parser->error = YAML_MEMORY_ERROR;
1276                 goto error;
1277             }
1278             version_directive->major = token->data.version_directive.major;
1279             version_directive->minor = token->data.version_directive.minor;
1280         }
1281 
1282         else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1283             yaml_tag_directive_t value;
1284             value.handle = token->data.tag_directive.handle;
1285             value.prefix = token->data.tag_directive.prefix;
1286 
1287             if (!yaml_parser_append_tag_directive(parser, value, 0,
1288                         token->start_mark))
1289                 goto error;
1290             if (!PUSH(parser, tag_directives, value))
1291                 goto error;
1292         }
1293 
1294         SKIP_TOKEN(parser);
1295         token = PEEK_TOKEN(parser);
1296         if (!token) goto error;
1297     }
1298 
1299     for (default_tag_directive = default_tag_directives;
1300             default_tag_directive->handle; default_tag_directive++) {
1301         if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1302                     token->start_mark))
1303             goto error;
1304     }
1305 
1306     if (version_directive_ref) {
1307         *version_directive_ref = version_directive;
1308     }
1309     if (tag_directives_start_ref) {
1310         if (STACK_EMPTY(parser, tag_directives)) {
1311             *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1312             STACK_DEL(parser, tag_directives);
1313         }
1314         else {
1315             *tag_directives_start_ref = tag_directives.start;
1316             *tag_directives_end_ref = tag_directives.top;
1317         }
1318     }
1319     else {
1320         STACK_DEL(parser, tag_directives);
1321     }
1322 
1323     return 1;
1324 
1325 error:
1326     yaml_free(version_directive);
1327     while (!STACK_EMPTY(parser, tag_directives)) {
1328         yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1329         yaml_free(tag_directive.handle);
1330         yaml_free(tag_directive.prefix);
1331     }
1332     STACK_DEL(parser, tag_directives);
1333     return 0;
1334 }
1335 
1336 /*
1337  * Append a tag directive to the directives stack.
1338  */
1339 
1340 static int
yaml_parser_append_tag_directive(yaml_parser_t * parser,yaml_tag_directive_t value,int allow_duplicates,yaml_mark_t mark)1341 yaml_parser_append_tag_directive(yaml_parser_t *parser,
1342         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1343 {
1344     yaml_tag_directive_t *tag_directive;
1345     yaml_tag_directive_t copy = { NULL, NULL };
1346 
1347     for (tag_directive = parser->tag_directives.start;
1348             tag_directive != parser->tag_directives.top; tag_directive ++) {
1349         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1350             if (allow_duplicates)
1351                 return 1;
1352             return yaml_parser_set_parser_error(parser,
1353                     "found duplicate %TAG directive", mark);
1354         }
1355     }
1356 
1357     copy.handle = yaml_strdup(value.handle);
1358     copy.prefix = yaml_strdup(value.prefix);
1359     if (!copy.handle || !copy.prefix) {
1360         parser->error = YAML_MEMORY_ERROR;
1361         goto error;
1362     }
1363 
1364     if (!PUSH(parser, parser->tag_directives, copy))
1365         goto error;
1366 
1367     return 1;
1368 
1369 error:
1370     yaml_free(copy.handle);
1371     yaml_free(copy.prefix);
1372     return 0;
1373 }
1374 
1375