Coverage Report

Created: 2026-09-01 06:07

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