Coverage Report

Created: 2024-02-11 06:25

/src/moddable/xs/tools/yaml/loader.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2006-2016 Kirill Simonov
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
5
 * this software and associated documentation files (the "Software"), to deal in
6
 * the Software without restriction, including without limitation the rights to
7
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
 * of the Software, and to permit persons to whom the Software is furnished to do
9
 * so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all
12
 * copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
 * SOFTWARE.
21
 *
22
 */
23
24
#include "yaml_private.h"
25
26
/*
27
 * API functions.
28
 */
29
30
YAML_DECLARE(int)
31
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
32
33
/*
34
 * Error handling.
35
 */
36
37
static int
38
yaml_parser_set_composer_error(yaml_parser_t *parser,
39
        const char *problem, yaml_mark_t problem_mark);
40
41
static int
42
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
43
        const char *context, yaml_mark_t context_mark,
44
        const char *problem, yaml_mark_t problem_mark);
45
46
47
/*
48
 * Alias handling.
49
 */
50
51
static int
52
yaml_parser_register_anchor(yaml_parser_t *parser,
53
        int index, yaml_char_t *anchor);
54
55
/*
56
 * Clean up functions.
57
 */
58
59
static void
60
yaml_parser_delete_aliases(yaml_parser_t *parser);
61
62
/*
63
 * Composer functions.
64
 */
65
66
static int
67
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
68
69
static int
70
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
71
72
static int
73
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
74
75
static int
76
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
77
78
static int
79
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
80
81
static int
82
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
83
84
/*
85
 * Load the next document of the stream.
86
 */
87
88
YAML_DECLARE(int)
89
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
90
0
{
91
0
    yaml_event_t event;
92
93
0
    assert(parser);     /* Non-NULL parser object is expected. */
94
0
    assert(document);   /* Non-NULL document object is expected. */
95
96
0
    memset(document, 0, sizeof(yaml_document_t));
97
0
    if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
98
0
        goto error;
99
100
0
    if (!parser->stream_start_produced) {
101
0
        if (!yaml_parser_parse(parser, &event)) goto error;
102
0
        assert(event.type == YAML_STREAM_START_EVENT);
103
                        /* STREAM-START is expected. */
104
0
    }
105
106
0
    if (parser->stream_end_produced) {
107
0
        return 1;
108
0
    }
109
110
0
    if (!yaml_parser_parse(parser, &event)) goto error;
111
0
    if (event.type == YAML_STREAM_END_EVENT) {
112
0
        return 1;
113
0
    }
114
115
0
    if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
116
0
        goto error;
117
118
0
    parser->document = document;
119
120
0
    if (!yaml_parser_load_document(parser, &event)) goto error;
121
122
0
    yaml_parser_delete_aliases(parser);
123
0
    parser->document = NULL;
124
125
0
    return 1;
126
127
0
error:
128
129
0
    yaml_parser_delete_aliases(parser);
130
0
    yaml_document_delete(document);
131
0
    parser->document = NULL;
132
133
0
    return 0;
134
0
}
135
136
/*
137
 * Set composer error.
138
 */
139
140
static int
141
yaml_parser_set_composer_error(yaml_parser_t *parser,
142
        const char *problem, yaml_mark_t problem_mark)
143
0
{
144
0
    parser->error = YAML_COMPOSER_ERROR;
145
0
    parser->problem = problem;
146
0
    parser->problem_mark = problem_mark;
147
148
0
    return 0;
149
0
}
150
151
/*
152
 * Set composer error with context.
153
 */
154
155
static int
156
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
157
        const char *context, yaml_mark_t context_mark,
158
        const char *problem, yaml_mark_t problem_mark)
159
0
{
160
0
    parser->error = YAML_COMPOSER_ERROR;
161
0
    parser->context = context;
162
0
    parser->context_mark = context_mark;
163
0
    parser->problem = problem;
164
0
    parser->problem_mark = problem_mark;
165
166
0
    return 0;
167
0
}
168
169
/*
170
 * Delete the stack of aliases.
171
 */
172
173
static void
174
yaml_parser_delete_aliases(yaml_parser_t *parser)
175
0
{
176
0
    while (!STACK_EMPTY(parser, parser->aliases)) {
177
0
        yaml_free(POP(parser, parser->aliases).anchor);
178
0
    }
179
0
    STACK_DEL(parser, parser->aliases);
180
0
}
181
182
/*
183
 * Compose a document object.
184
 */
185
186
static int
187
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
188
0
{
189
0
    yaml_event_t event;
190
191
0
    assert(first_event->type == YAML_DOCUMENT_START_EVENT);
192
                        /* DOCUMENT-START is expected. */
193
194
0
    parser->document->version_directive
195
0
        = first_event->data.document_start.version_directive;
196
0
    parser->document->tag_directives.start
197
0
        = first_event->data.document_start.tag_directives.start;
198
0
    parser->document->tag_directives.end
199
0
        = first_event->data.document_start.tag_directives.end;
200
0
    parser->document->start_implicit
201
0
        = first_event->data.document_start.implicit;
202
0
    parser->document->start_mark = first_event->start_mark;
203
204
0
    if (!yaml_parser_parse(parser, &event)) return 0;
205
206
0
    if (!yaml_parser_load_node(parser, &event)) return 0;
207
208
0
    if (!yaml_parser_parse(parser, &event)) return 0;
209
0
    assert(event.type == YAML_DOCUMENT_END_EVENT);
210
                        /* DOCUMENT-END is expected. */
211
212
0
    parser->document->end_implicit = event.data.document_end.implicit;
213
0
    parser->document->end_mark = event.end_mark;
214
215
0
    return 1;
216
0
}
217
218
/*
219
 * Compose a node.
220
 */
221
222
static int
223
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
224
0
{
225
0
    switch (first_event->type) {
226
0
        case YAML_ALIAS_EVENT:
227
0
            return yaml_parser_load_alias(parser, first_event);
228
0
        case YAML_SCALAR_EVENT:
229
0
            return yaml_parser_load_scalar(parser, first_event);
230
0
        case YAML_SEQUENCE_START_EVENT:
231
0
            return yaml_parser_load_sequence(parser, first_event);
232
0
        case YAML_MAPPING_START_EVENT:
233
0
            return yaml_parser_load_mapping(parser, first_event);
234
0
        default:
235
0
            assert(0);  /* Could not happen. */
236
0
            return 0;
237
0
    }
238
239
0
    return 0;
240
0
}
241
242
/*
243
 * Add an anchor.
244
 */
245
246
static int
247
yaml_parser_register_anchor(yaml_parser_t *parser,
248
        int index, yaml_char_t *anchor)
249
0
{
250
0
    yaml_alias_data_t data;
251
0
    yaml_alias_data_t *alias_data;
252
253
0
    if (!anchor) return 1;
254
255
0
    data.anchor = anchor;
256
0
    data.index = index;
257
0
    data.mark = parser->document->nodes.start[index-1].start_mark;
258
259
0
    for (alias_data = parser->aliases.start;
260
0
            alias_data != parser->aliases.top; alias_data ++) {
261
0
        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
262
0
            yaml_free(anchor);
263
0
            return yaml_parser_set_composer_error_context(parser,
264
0
                    "found duplicate anchor; first occurence",
265
0
                    alias_data->mark, "second occurence", data.mark);
266
0
        }
267
0
    }
268
269
0
    if (!PUSH(parser, parser->aliases, data)) {
270
0
        yaml_free(anchor);
271
0
        return 0;
272
0
    }
273
274
0
    return 1;
275
0
}
276
277
/*
278
 * Compose a node corresponding to an alias.
279
 */
280
281
static int
282
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
283
0
{
284
0
    yaml_char_t *anchor = first_event->data.alias.anchor;
285
0
    yaml_alias_data_t *alias_data;
286
287
0
    for (alias_data = parser->aliases.start;
288
0
            alias_data != parser->aliases.top; alias_data ++) {
289
0
        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
290
0
            yaml_free(anchor);
291
0
            return alias_data->index;
292
0
        }
293
0
    }
294
295
0
    yaml_free(anchor);
296
0
    return yaml_parser_set_composer_error(parser, "found undefined alias",
297
0
            first_event->start_mark);
298
0
}
299
300
/*
301
 * Compose a scalar node.
302
 */
303
304
static int
305
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
306
0
{
307
0
    yaml_node_t node;
308
0
    int index;
309
0
    yaml_char_t *tag = first_event->data.scalar.tag;
310
311
0
    if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
312
313
0
    if (!tag || strcmp((char *)tag, "!") == 0) {
314
0
        yaml_free(tag);
315
0
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
316
0
        if (!tag) goto error;
317
0
    }
318
319
0
    SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
320
0
            first_event->data.scalar.length, first_event->data.scalar.style,
321
0
            first_event->start_mark, first_event->end_mark);
322
323
0
    if (!PUSH(parser, parser->document->nodes, node)) goto error;
324
325
0
    index = (int)(parser->document->nodes.top - parser->document->nodes.start);
326
327
0
    if (!yaml_parser_register_anchor(parser, index,
328
0
                first_event->data.scalar.anchor)) return 0;
329
330
0
    return index;
331
332
0
error:
333
0
    yaml_free(tag);
334
0
    yaml_free(first_event->data.scalar.anchor);
335
0
    yaml_free(first_event->data.scalar.value);
336
0
    return 0;
337
0
}
338
339
/*
340
 * Compose a sequence node.
341
 */
342
343
static int
344
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
345
0
{
346
0
    yaml_event_t event;
347
0
    yaml_node_t node;
348
0
    struct {
349
0
        yaml_node_item_t *start;
350
0
        yaml_node_item_t *end;
351
0
        yaml_node_item_t *top;
352
0
    } items = { NULL, NULL, NULL };
353
0
    int index, item_index;
354
0
    yaml_char_t *tag = first_event->data.sequence_start.tag;
355
356
0
    if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
357
358
0
    if (!tag || strcmp((char *)tag, "!") == 0) {
359
0
        yaml_free(tag);
360
0
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
361
0
        if (!tag) goto error;
362
0
    }
363
364
0
    if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
365
366
0
    SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
367
0
            first_event->data.sequence_start.style,
368
0
            first_event->start_mark, first_event->end_mark);
369
370
0
    if (!PUSH(parser, parser->document->nodes, node)) goto error;
371
372
0
    index = (int)(parser->document->nodes.top - parser->document->nodes.start);
373
374
0
    if (!yaml_parser_register_anchor(parser, index,
375
0
                first_event->data.sequence_start.anchor)) return 0;
376
377
0
    if (!yaml_parser_parse(parser, &event)) return 0;
378
379
0
    while (event.type != YAML_SEQUENCE_END_EVENT) {
380
0
        if (!STACK_LIMIT(parser,
381
0
                    parser->document->nodes.start[index-1].data.sequence.items,
382
0
                    INT_MAX-1)) return 0;
383
0
        item_index = yaml_parser_load_node(parser, &event);
384
0
        if (!item_index) return 0;
385
0
        if (!PUSH(parser,
386
0
                    parser->document->nodes.start[index-1].data.sequence.items,
387
0
                    item_index)) return 0;
388
0
        if (!yaml_parser_parse(parser, &event)) return 0;
389
0
    }
390
391
0
    parser->document->nodes.start[index-1].end_mark = event.end_mark;
392
393
0
    return index;
394
395
0
error:
396
0
    yaml_free(tag);
397
0
    yaml_free(first_event->data.sequence_start.anchor);
398
0
    return 0;
399
0
}
400
401
/*
402
 * Compose a mapping node.
403
 */
404
405
static int
406
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
407
0
{
408
0
    yaml_event_t event;
409
0
    yaml_node_t node;
410
0
    struct {
411
0
        yaml_node_pair_t *start;
412
0
        yaml_node_pair_t *end;
413
0
        yaml_node_pair_t *top;
414
0
    } pairs = { NULL, NULL, NULL };
415
0
    int index;
416
0
    yaml_node_pair_t pair;
417
0
    yaml_char_t *tag = first_event->data.mapping_start.tag;
418
419
0
    if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
420
421
0
    if (!tag || strcmp((char *)tag, "!") == 0) {
422
0
        yaml_free(tag);
423
0
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
424
0
        if (!tag) goto error;
425
0
    }
426
427
0
    if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
428
429
0
    MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
430
0
            first_event->data.mapping_start.style,
431
0
            first_event->start_mark, first_event->end_mark);
432
433
0
    if (!PUSH(parser, parser->document->nodes, node)) goto error;
434
435
0
    index = (int)(parser->document->nodes.top - parser->document->nodes.start);
436
437
0
    if (!yaml_parser_register_anchor(parser, index,
438
0
                first_event->data.mapping_start.anchor)) return 0;
439
440
0
    if (!yaml_parser_parse(parser, &event)) return 0;
441
442
0
    while (event.type != YAML_MAPPING_END_EVENT) {
443
0
        if (!STACK_LIMIT(parser,
444
0
                    parser->document->nodes.start[index-1].data.mapping.pairs,
445
0
                    INT_MAX-1)) return 0;
446
0
        pair.key = yaml_parser_load_node(parser, &event);
447
0
        if (!pair.key) return 0;
448
0
        if (!yaml_parser_parse(parser, &event)) return 0;
449
0
        pair.value = yaml_parser_load_node(parser, &event);
450
0
        if (!pair.value) return 0;
451
0
        if (!PUSH(parser,
452
0
                    parser->document->nodes.start[index-1].data.mapping.pairs,
453
0
                    pair)) return 0;
454
0
        if (!yaml_parser_parse(parser, &event)) return 0;
455
0
    }
456
457
0
    parser->document->nodes.start[index-1].end_mark = event.end_mark;
458
459
0
    return index;
460
461
0
error:
462
0
    yaml_free(tag);
463
0
    yaml_free(first_event->data.mapping_start.anchor);
464
0
    return 0;
465
0
}
466