Coverage Report

Created: 2024-02-11 06:15

/src/h2o/deps/yaml/src/loader.c
Line
Count
Source (jump to first uncovered line)
1
2
#include "yaml_private.h"
3
4
/*
5
 * API functions.
6
 */
7
8
YAML_DECLARE(int)
9
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
10
11
/*
12
 * Error handling.
13
 */
14
15
static int
16
yaml_parser_set_composer_error(yaml_parser_t *parser,
17
        const char *problem, yaml_mark_t problem_mark);
18
19
static int
20
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
21
        const char *context, yaml_mark_t context_mark,
22
        const char *problem, yaml_mark_t problem_mark);
23
24
25
/*
26
 * Alias handling.
27
 */
28
29
static int
30
yaml_parser_register_anchor(yaml_parser_t *parser,
31
        int index, yaml_char_t *anchor);
32
33
/*
34
 * Clean up functions.
35
 */
36
37
static void
38
yaml_parser_delete_aliases(yaml_parser_t *parser);
39
40
/*
41
 * Document loading context.
42
 */
43
struct loader_ctx {
44
    int *start;
45
    int *end;
46
    int *top;
47
};
48
49
/*
50
 * Composer functions.
51
 */
52
static int
53
yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx);
54
55
static int
56
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event);
57
58
static int
59
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
60
        struct loader_ctx *ctx);
61
62
static int
63
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
64
        struct loader_ctx *ctx);
65
66
static int
67
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
68
        struct loader_ctx *ctx);
69
70
static int
71
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
72
        struct loader_ctx *ctx);
73
74
static int
75
yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
76
        struct loader_ctx *ctx);
77
78
static int
79
yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
80
        struct loader_ctx *ctx);
81
82
/*
83
 * Load the next document of the stream.
84
 */
85
86
YAML_DECLARE(int)
87
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
88
0
{
89
0
    yaml_event_t event;
90
91
0
    assert(parser);     /* Non-NULL parser object is expected. */
92
0
    assert(document);   /* Non-NULL document object is expected. */
93
94
0
    memset(document, 0, sizeof(yaml_document_t));
95
0
    if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
96
0
        goto error;
97
98
0
    if (!parser->stream_start_produced) {
99
0
        if (!yaml_parser_parse(parser, &event)) goto error;
100
0
        assert(event.type == YAML_STREAM_START_EVENT);
101
                        /* STREAM-START is expected. */
102
0
    }
103
104
0
    if (parser->stream_end_produced) {
105
0
        return 1;
106
0
    }
107
108
0
    if (!yaml_parser_parse(parser, &event)) goto error;
109
0
    if (event.type == YAML_STREAM_END_EVENT) {
110
0
        return 1;
111
0
    }
112
113
0
    if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
114
0
        goto error;
115
116
0
    parser->document = document;
117
118
0
    if (!yaml_parser_load_document(parser, &event)) goto error;
119
120
0
    yaml_parser_delete_aliases(parser);
121
0
    parser->document = NULL;
122
123
0
    return 1;
124
125
0
error:
126
127
0
    yaml_parser_delete_aliases(parser);
128
0
    yaml_document_delete(document);
129
0
    parser->document = NULL;
130
131
0
    return 0;
132
0
}
133
134
/*
135
 * Set composer error.
136
 */
137
138
static int
139
yaml_parser_set_composer_error(yaml_parser_t *parser,
140
        const char *problem, yaml_mark_t problem_mark)
141
0
{
142
0
    parser->error = YAML_COMPOSER_ERROR;
143
0
    parser->problem = problem;
144
0
    parser->problem_mark = problem_mark;
145
146
0
    return 0;
147
0
}
148
149
/*
150
 * Set composer error with context.
151
 */
152
153
static int
154
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
155
        const char *context, yaml_mark_t context_mark,
156
        const char *problem, yaml_mark_t problem_mark)
157
0
{
158
0
    parser->error = YAML_COMPOSER_ERROR;
159
0
    parser->context = context;
160
0
    parser->context_mark = context_mark;
161
0
    parser->problem = problem;
162
0
    parser->problem_mark = problem_mark;
163
164
0
    return 0;
165
0
}
166
167
/*
168
 * Delete the stack of aliases.
169
 */
170
171
static void
172
yaml_parser_delete_aliases(yaml_parser_t *parser)
173
0
{
174
0
    while (!STACK_EMPTY(parser, parser->aliases)) {
175
0
        yaml_free(POP(parser, parser->aliases).anchor);
176
0
    }
177
0
    STACK_DEL(parser, parser->aliases);
178
0
}
179
180
/*
181
 * Compose a document object.
182
 */
183
184
static int
185
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event)
186
0
{
187
0
    struct loader_ctx ctx = { NULL, NULL, NULL };
188
189
0
    assert(event->type == YAML_DOCUMENT_START_EVENT);
190
                        /* DOCUMENT-START is expected. */
191
192
0
    parser->document->version_directive
193
0
        = event->data.document_start.version_directive;
194
0
    parser->document->tag_directives.start
195
0
        = event->data.document_start.tag_directives.start;
196
0
    parser->document->tag_directives.end
197
0
        = event->data.document_start.tag_directives.end;
198
0
    parser->document->start_implicit
199
0
        = event->data.document_start.implicit;
200
0
    parser->document->start_mark = event->start_mark;
201
202
0
    if (!STACK_INIT(parser, ctx, int*)) return 0;
203
0
    if (!yaml_parser_load_nodes(parser, &ctx)) {
204
0
        STACK_DEL(parser, ctx);
205
0
        return 0;
206
0
    }
207
0
    STACK_DEL(parser, ctx);
208
209
0
    return 1;
210
0
}
211
212
/*
213
 * Compose a node tree.
214
 */
215
216
static int
217
yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx)
218
0
{
219
0
    yaml_event_t event;
220
221
0
    do {
222
0
        if (!yaml_parser_parse(parser, &event)) return 0;
223
224
0
        switch (event.type) {
225
0
            case YAML_ALIAS_EVENT:
226
0
                if (!yaml_parser_load_alias(parser, &event, ctx)) return 0;
227
0
                break;
228
0
            case YAML_SCALAR_EVENT:
229
0
                if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0;
230
0
                break;
231
0
            case YAML_SEQUENCE_START_EVENT:
232
0
                if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0;
233
0
                break;
234
0
            case YAML_SEQUENCE_END_EVENT:
235
0
                if (!yaml_parser_load_sequence_end(parser, &event, ctx))
236
0
                    return 0;
237
0
                break;
238
0
            case YAML_MAPPING_START_EVENT:
239
0
                if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0;
240
0
                break;
241
0
            case YAML_MAPPING_END_EVENT:
242
0
                if (!yaml_parser_load_mapping_end(parser, &event, ctx))
243
0
                    return 0;
244
0
                break;
245
0
            default:
246
0
                assert(0);  /* Could not happen. */
247
0
                return 0;
248
0
            case YAML_DOCUMENT_END_EVENT:
249
0
                break;
250
0
        }
251
0
    } while (event.type != YAML_DOCUMENT_END_EVENT);
252
253
0
    parser->document->end_implicit = event.data.document_end.implicit;
254
0
    parser->document->end_mark = event.end_mark;
255
256
0
    return 1;
257
0
}
258
259
/*
260
 * Add an anchor.
261
 */
262
263
static int
264
yaml_parser_register_anchor(yaml_parser_t *parser,
265
        int index, yaml_char_t *anchor)
266
0
{
267
0
    yaml_alias_data_t data;
268
0
    yaml_alias_data_t *alias_data;
269
270
0
    if (!anchor) return 1;
271
272
0
    data.anchor = anchor;
273
0
    data.index = index;
274
0
    data.mark = parser->document->nodes.start[index-1].start_mark;
275
276
0
    for (alias_data = parser->aliases.start;
277
0
            alias_data != parser->aliases.top; alias_data ++) {
278
0
        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
279
0
            yaml_free(anchor);
280
0
            return yaml_parser_set_composer_error_context(parser,
281
0
                    "found duplicate anchor; first occurrence",
282
0
                    alias_data->mark, "second occurrence", data.mark);
283
0
        }
284
0
    }
285
286
0
    if (!PUSH(parser, parser->aliases, data)) {
287
0
        yaml_free(anchor);
288
0
        return 0;
289
0
    }
290
291
0
    return 1;
292
0
}
293
294
/*
295
 * Compose node into its parent in the stree.
296
 */
297
298
static int
299
yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx,
300
        int index)
301
0
{
302
0
    struct yaml_node_s *parent;
303
0
    int parent_index;
304
305
0
    if (STACK_EMPTY(parser, *ctx)) {
306
        /* This is the root node, there's no tree to add it to. */
307
0
        return 1;
308
0
    }
309
310
0
    parent_index = *((*ctx).top - 1);
311
0
    parent = &parser->document->nodes.start[parent_index-1];
312
313
0
    switch (parent->type) {
314
0
        case YAML_SEQUENCE_NODE:
315
0
            if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1))
316
0
                return 0;
317
0
            if (!PUSH(parser, parent->data.sequence.items, index))
318
0
                return 0;
319
0
            break;
320
0
        case YAML_MAPPING_NODE: {
321
0
            yaml_node_pair_t pair;
322
0
            if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) {
323
0
                yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1;
324
0
                if (p->key != 0 && p->value == 0) {
325
0
                    p->value = index;
326
0
                    break;
327
0
                }
328
0
            }
329
330
0
            pair.key = index;
331
0
            pair.value = 0;
332
0
            if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1))
333
0
                return 0;
334
0
            if (!PUSH(parser, parent->data.mapping.pairs, pair))
335
0
                return 0;
336
337
0
            break;
338
0
        }
339
0
        default:
340
0
            assert(0); /* Could not happen. */
341
0
            return 0;
342
0
    }
343
0
    return 1;
344
0
}
345
346
/*
347
 * Compose a node corresponding to an alias.
348
 */
349
350
static int
351
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
352
        struct loader_ctx *ctx)
353
0
{
354
0
    yaml_char_t *anchor = event->data.alias.anchor;
355
0
    yaml_alias_data_t *alias_data;
356
357
0
    for (alias_data = parser->aliases.start;
358
0
            alias_data != parser->aliases.top; alias_data ++) {
359
0
        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
360
0
            yaml_free(anchor);
361
0
            return yaml_parser_load_node_add(parser, ctx, alias_data->index);
362
0
        }
363
0
    }
364
365
0
    yaml_free(anchor);
366
0
    return yaml_parser_set_composer_error(parser, "found undefined alias",
367
0
            event->start_mark);
368
0
}
369
370
/*
371
 * Compose a scalar node.
372
 */
373
374
static int
375
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
376
        struct loader_ctx *ctx)
377
0
{
378
0
    yaml_node_t node;
379
0
    int index;
380
0
    yaml_char_t *tag = event->data.scalar.tag;
381
382
0
    if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
383
384
0
    if (!tag || strcmp((char *)tag, "!") == 0) {
385
0
        yaml_free(tag);
386
0
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
387
0
        if (!tag) goto error;
388
0
    }
389
390
0
    SCALAR_NODE_INIT(node, tag, event->data.scalar.value,
391
0
            event->data.scalar.length, event->data.scalar.style,
392
0
            event->start_mark, event->end_mark);
393
394
0
    if (!PUSH(parser, parser->document->nodes, node)) goto error;
395
396
0
    index = parser->document->nodes.top - parser->document->nodes.start;
397
398
0
    if (!yaml_parser_register_anchor(parser, index,
399
0
                event->data.scalar.anchor)) return 0;
400
401
0
    return yaml_parser_load_node_add(parser, ctx, index);
402
403
0
error:
404
0
    yaml_free(tag);
405
0
    yaml_free(event->data.scalar.anchor);
406
0
    yaml_free(event->data.scalar.value);
407
0
    return 0;
408
0
}
409
410
/*
411
 * Compose a sequence node.
412
 */
413
414
static int
415
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
416
        struct loader_ctx *ctx)
417
0
{
418
0
    yaml_node_t node;
419
0
    struct {
420
0
        yaml_node_item_t *start;
421
0
        yaml_node_item_t *end;
422
0
        yaml_node_item_t *top;
423
0
    } items = { NULL, NULL, NULL };
424
0
    int index;
425
0
    yaml_char_t *tag = event->data.sequence_start.tag;
426
427
0
    if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
428
429
0
    if (!tag || strcmp((char *)tag, "!") == 0) {
430
0
        yaml_free(tag);
431
0
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
432
0
        if (!tag) goto error;
433
0
    }
434
435
0
    if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
436
437
0
    SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
438
0
            event->data.sequence_start.style,
439
0
            event->start_mark, event->end_mark);
440
441
0
    if (!PUSH(parser, parser->document->nodes, node)) goto error;
442
443
0
    index = parser->document->nodes.top - parser->document->nodes.start;
444
445
0
    if (!yaml_parser_register_anchor(parser, index,
446
0
                event->data.sequence_start.anchor)) return 0;
447
448
0
    if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
449
450
0
    if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
451
0
    if (!PUSH(parser, *ctx, index)) return 0;
452
453
0
    return 1;
454
455
0
error:
456
0
    yaml_free(tag);
457
0
    yaml_free(event->data.sequence_start.anchor);
458
0
    return 0;
459
0
}
460
461
static int
462
yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
463
        struct loader_ctx *ctx)
464
0
{
465
0
    int index;
466
467
0
    assert(((*ctx).top - (*ctx).start) > 0);
468
469
0
    index = *((*ctx).top - 1);
470
0
    assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE);
471
0
    parser->document->nodes.start[index-1].end_mark = event->end_mark;
472
473
0
    (void)POP(parser, *ctx);
474
475
0
    return 1;
476
0
}
477
478
/*
479
 * Compose a mapping node.
480
 */
481
482
static int
483
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
484
        struct loader_ctx *ctx)
485
0
{
486
0
    yaml_node_t node;
487
0
    struct {
488
0
        yaml_node_pair_t *start;
489
0
        yaml_node_pair_t *end;
490
0
        yaml_node_pair_t *top;
491
0
    } pairs = { NULL, NULL, NULL };
492
0
    int index;
493
0
    yaml_char_t *tag = event->data.mapping_start.tag;
494
495
0
    if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
496
497
0
    if (!tag || strcmp((char *)tag, "!") == 0) {
498
0
        yaml_free(tag);
499
0
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
500
0
        if (!tag) goto error;
501
0
    }
502
503
0
    if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
504
505
0
    MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
506
0
            event->data.mapping_start.style,
507
0
            event->start_mark, event->end_mark);
508
509
0
    if (!PUSH(parser, parser->document->nodes, node)) goto error;
510
511
0
    index = parser->document->nodes.top - parser->document->nodes.start;
512
513
0
    if (!yaml_parser_register_anchor(parser, index,
514
0
                event->data.mapping_start.anchor)) return 0;
515
516
0
    if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
517
518
0
    if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
519
0
    if (!PUSH(parser, *ctx, index)) return 0;
520
521
0
    return 1;
522
523
0
error:
524
0
    yaml_free(tag);
525
0
    yaml_free(event->data.mapping_start.anchor);
526
0
    return 0;
527
0
}
528
529
static int
530
yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
531
        struct loader_ctx *ctx)
532
0
{
533
0
    int index;
534
535
0
    assert(((*ctx).top - (*ctx).start) > 0);
536
537
0
    index = *((*ctx).top - 1);
538
0
    assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE);
539
0
    parser->document->nodes.start[index-1].end_mark = event->end_mark;
540
541
0
    (void)POP(parser, *ctx);
542
543
0
    return 1;
544
0
}