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 { 89 yaml_event_t event; 90 91 assert(parser); /* Non-NULL parser object is expected. */ 92 assert(document); /* Non-NULL document object is expected. */ 93 94 memset(document, 0, sizeof(yaml_document_t)); 95 if (!STACK_INIT(parser, document->nodes, yaml_node_t*)) 96 goto error; 97 98 if (!parser->stream_start_produced) { 99 if (!yaml_parser_parse(parser, &event)) goto error; 100 assert(event.type == YAML_STREAM_START_EVENT); 101 /* STREAM-START is expected. */ 102 } 103 104 if (parser->stream_end_produced) { 105 return 1; 106 } 107 108 if (!yaml_parser_parse(parser, &event)) goto error; 109 if (event.type == YAML_STREAM_END_EVENT) { 110 return 1; 111 } 112 113 if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*)) 114 goto error; 115 116 parser->document = document; 117 118 if (!yaml_parser_load_document(parser, &event)) goto error; 119 120 yaml_parser_delete_aliases(parser); 121 parser->document = NULL; 122 123 return 1; 124 125 error: 126 127 yaml_parser_delete_aliases(parser); 128 yaml_document_delete(document); 129 parser->document = NULL; 130 131 return 0; 132 } 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 { 142 parser->error = YAML_COMPOSER_ERROR; 143 parser->problem = problem; 144 parser->problem_mark = problem_mark; 145 146 return 0; 147 } 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 { 158 parser->error = YAML_COMPOSER_ERROR; 159 parser->context = context; 160 parser->context_mark = context_mark; 161 parser->problem = problem; 162 parser->problem_mark = problem_mark; 163 164 return 0; 165 } 166 167 /* 168 * Delete the stack of aliases. 169 */ 170 171 static void 172 yaml_parser_delete_aliases(yaml_parser_t *parser) 173 { 174 while (!STACK_EMPTY(parser, parser->aliases)) { 175 yaml_free(POP(parser, parser->aliases).anchor); 176 } 177 STACK_DEL(parser, parser->aliases); 178 } 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 { 187 struct loader_ctx ctx = { NULL, NULL, NULL }; 188 189 assert(event->type == YAML_DOCUMENT_START_EVENT); 190 /* DOCUMENT-START is expected. */ 191 192 parser->document->version_directive 193 = event->data.document_start.version_directive; 194 parser->document->tag_directives.start 195 = event->data.document_start.tag_directives.start; 196 parser->document->tag_directives.end 197 = event->data.document_start.tag_directives.end; 198 parser->document->start_implicit 199 = event->data.document_start.implicit; 200 parser->document->start_mark = event->start_mark; 201 202 if (!STACK_INIT(parser, ctx, int*)) return 0; 203 if (!yaml_parser_load_nodes(parser, &ctx)) { 204 STACK_DEL(parser, ctx); 205 return 0; 206 } 207 STACK_DEL(parser, ctx); 208 209 return 1; 210 } 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 { 219 yaml_event_t event; 220 221 do { 222 if (!yaml_parser_parse(parser, &event)) return 0; 223 224 switch (event.type) { 225 case YAML_ALIAS_EVENT: 226 if (!yaml_parser_load_alias(parser, &event, ctx)) return 0; 227 break; 228 case YAML_SCALAR_EVENT: 229 if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0; 230 break; 231 case YAML_SEQUENCE_START_EVENT: 232 if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0; 233 break; 234 case YAML_SEQUENCE_END_EVENT: 235 if (!yaml_parser_load_sequence_end(parser, &event, ctx)) 236 return 0; 237 break; 238 case YAML_MAPPING_START_EVENT: 239 if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0; 240 break; 241 case YAML_MAPPING_END_EVENT: 242 if (!yaml_parser_load_mapping_end(parser, &event, ctx)) 243 return 0; 244 break; 245 default: 246 assert(0); /* Could not happen. */ 247 return 0; 248 case YAML_DOCUMENT_END_EVENT: 249 break; 250 } 251 } while (event.type != YAML_DOCUMENT_END_EVENT); 252 253 parser->document->end_implicit = event.data.document_end.implicit; 254 parser->document->end_mark = event.end_mark; 255 256 return 1; 257 } 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 { 267 yaml_alias_data_t data; 268 yaml_alias_data_t *alias_data; 269 270 if (!anchor) return 1; 271 272 data.anchor = anchor; 273 data.index = index; 274 data.mark = parser->document->nodes.start[index-1].start_mark; 275 276 for (alias_data = parser->aliases.start; 277 alias_data != parser->aliases.top; alias_data ++) { 278 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { 279 yaml_free(anchor); 280 return yaml_parser_set_composer_error_context(parser, 281 "found duplicate anchor; first occurrence", 282 alias_data->mark, "second occurrence", data.mark); 283 } 284 } 285 286 if (!PUSH(parser, parser->aliases, data)) { 287 yaml_free(anchor); 288 return 0; 289 } 290 291 return 1; 292 } 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 { 302 struct yaml_node_s *parent; 303 int parent_index; 304 305 if (STACK_EMPTY(parser, *ctx)) { 306 /* This is the root node, there's no tree to add it to. */ 307 return 1; 308 } 309 310 parent_index = *((*ctx).top - 1); 311 parent = &parser->document->nodes.start[parent_index-1]; 312 313 switch (parent->type) { 314 case YAML_SEQUENCE_NODE: 315 if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1)) 316 return 0; 317 if (!PUSH(parser, parent->data.sequence.items, index)) 318 return 0; 319 break; 320 case YAML_MAPPING_NODE: { 321 yaml_node_pair_t pair; 322 if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) { 323 yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1; 324 if (p->key != 0 && p->value == 0) { 325 p->value = index; 326 break; 327 } 328 } 329 330 pair.key = index; 331 pair.value = 0; 332 if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1)) 333 return 0; 334 if (!PUSH(parser, parent->data.mapping.pairs, pair)) 335 return 0; 336 337 break; 338 } 339 default: 340 assert(0); /* Could not happen. */ 341 return 0; 342 } 343 return 1; 344 } 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 { 354 yaml_char_t *anchor = event->data.alias.anchor; 355 yaml_alias_data_t *alias_data; 356 357 for (alias_data = parser->aliases.start; 358 alias_data != parser->aliases.top; alias_data ++) { 359 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { 360 yaml_free(anchor); 361 return yaml_parser_load_node_add(parser, ctx, alias_data->index); 362 } 363 } 364 365 yaml_free(anchor); 366 return yaml_parser_set_composer_error(parser, "found undefined alias", 367 event->start_mark); 368 } 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 { 378 yaml_node_t node; 379 int index; 380 yaml_char_t *tag = event->data.scalar.tag; 381 382 if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; 383 384 if (!tag || strcmp((char *)tag, "!") == 0) { 385 yaml_free(tag); 386 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG); 387 if (!tag) goto error; 388 } 389 390 SCALAR_NODE_INIT(node, tag, event->data.scalar.value, 391 event->data.scalar.length, event->data.scalar.style, 392 event->start_mark, event->end_mark); 393 394 if (!PUSH(parser, parser->document->nodes, node)) goto error; 395 396 index = parser->document->nodes.top - parser->document->nodes.start; 397 398 if (!yaml_parser_register_anchor(parser, index, 399 event->data.scalar.anchor)) return 0; 400 401 return yaml_parser_load_node_add(parser, ctx, index); 402 403 error: 404 yaml_free(tag); 405 yaml_free(event->data.scalar.anchor); 406 yaml_free(event->data.scalar.value); 407 return 0; 408 } 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 { 418 yaml_node_t node; 419 struct { 420 yaml_node_item_t *start; 421 yaml_node_item_t *end; 422 yaml_node_item_t *top; 423 } items = { NULL, NULL, NULL }; 424 int index; 425 yaml_char_t *tag = event->data.sequence_start.tag; 426 427 if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; 428 429 if (!tag || strcmp((char *)tag, "!") == 0) { 430 yaml_free(tag); 431 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG); 432 if (!tag) goto error; 433 } 434 435 if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error; 436 437 SEQUENCE_NODE_INIT(node, tag, items.start, items.end, 438 event->data.sequence_start.style, 439 event->start_mark, event->end_mark); 440 441 if (!PUSH(parser, parser->document->nodes, node)) goto error; 442 443 index = parser->document->nodes.top - parser->document->nodes.start; 444 445 if (!yaml_parser_register_anchor(parser, index, 446 event->data.sequence_start.anchor)) return 0; 447 448 if (!yaml_parser_load_node_add(parser, ctx, index)) return 0; 449 450 if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0; 451 if (!PUSH(parser, *ctx, index)) return 0; 452 453 return 1; 454 455 error: 456 yaml_free(tag); 457 yaml_free(event->data.sequence_start.anchor); 458 return 0; 459 } 460 461 static int 462 yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event, 463 struct loader_ctx *ctx) 464 { 465 int index; 466 467 assert(((*ctx).top - (*ctx).start) > 0); 468 469 index = *((*ctx).top - 1); 470 assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE); 471 parser->document->nodes.start[index-1].end_mark = event->end_mark; 472 473 (void)POP(parser, *ctx); 474 475 return 1; 476 } 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 { 486 yaml_node_t node; 487 struct { 488 yaml_node_pair_t *start; 489 yaml_node_pair_t *end; 490 yaml_node_pair_t *top; 491 } pairs = { NULL, NULL, NULL }; 492 int index; 493 yaml_char_t *tag = event->data.mapping_start.tag; 494 495 if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; 496 497 if (!tag || strcmp((char *)tag, "!") == 0) { 498 yaml_free(tag); 499 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG); 500 if (!tag) goto error; 501 } 502 503 if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error; 504 505 MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end, 506 event->data.mapping_start.style, 507 event->start_mark, event->end_mark); 508 509 if (!PUSH(parser, parser->document->nodes, node)) goto error; 510 511 index = parser->document->nodes.top - parser->document->nodes.start; 512 513 if (!yaml_parser_register_anchor(parser, index, 514 event->data.mapping_start.anchor)) return 0; 515 516 if (!yaml_parser_load_node_add(parser, ctx, index)) return 0; 517 518 if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0; 519 if (!PUSH(parser, *ctx, index)) return 0; 520 521 return 1; 522 523 error: 524 yaml_free(tag); 525 yaml_free(event->data.mapping_start.anchor); 526 return 0; 527 } 528 529 static int 530 yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event, 531 struct loader_ctx *ctx) 532 { 533 int index; 534 535 assert(((*ctx).top - (*ctx).start) > 0); 536 537 index = *((*ctx).top - 1); 538 assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE); 539 parser->document->nodes.start[index-1].end_mark = event->end_mark; 540 541 (void)POP(parser, *ctx); 542 543 return 1; 544 }