#
unsafe_libyaml/
loader.rs

    1use crate::api::{yaml_free, yaml_malloc, yaml_stack_extend, yaml_strdup};
    2use crate::externs::{memset, strcmp};
    3use crate::success::{Success, FAIL, OK};
    4use crate::yaml::yaml_char_t;
    5use crate::{
    6    libc, yaml_alias_data_t, yaml_document_delete, yaml_document_t, yaml_event_t, yaml_mark_t,
    7    yaml_node_item_t, yaml_node_pair_t, yaml_node_t, yaml_parser_parse, yaml_parser_t, PointerExt,
    8    YAML_ALIAS_EVENT, YAML_COMPOSER_ERROR, YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT,
    9    YAML_MAPPING_END_EVENT, YAML_MAPPING_NODE, YAML_MAPPING_START_EVENT, YAML_MEMORY_ERROR,
    10    YAML_SCALAR_EVENT, YAML_SCALAR_NODE, YAML_SEQUENCE_END_EVENT, YAML_SEQUENCE_NODE,
    11    YAML_SEQUENCE_START_EVENT, YAML_STREAM_END_EVENT, YAML_STREAM_START_EVENT,
    12};
    13use core::mem::{size_of, MaybeUninit};
    14use core::ptr::{self, addr_of_mut};
    15
    16#[repr(C)]
    17struct loader_ctx {
    18    start: *mut libc::c_int,
    19    end: *mut libc::c_int,
    20    top: *mut libc::c_int,
    21}
    22
    23/// Parse the input stream and produce the next YAML document.
    24///
    25/// Call this function subsequently to produce a sequence of documents
    26/// constituting the input stream.
    27///
    28/// If the produced document has no root node, it means that the document end
    29/// has been reached.
    30///
    31/// An application is responsible for freeing any data associated with the
    32/// produced document object using the yaml_document_delete() function.
    33///
    34/// An application must not alternate the calls of yaml_parser_load() with the
    35/// calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break
    36/// the parser.
    37pub unsafe fn yaml_parser_load(
    38    parser: *mut yaml_parser_t,
    39    document: *mut yaml_document_t,
    40) -> Success {
    41    let current_block: u64;
    42    let mut event = MaybeUninit::<yaml_event_t>::uninit();
    43    let event = event.as_mut_ptr();
    44    __assert!(!parser.is_null());
    45    __assert!(!document.is_null());
    46    memset(
    47        document as *mut libc::c_void,
    48        0,
    49        size_of::<yaml_document_t>() as libc::c_ulong,
    50    );
    51    STACK_INIT!((*document).nodes, yaml_node_t);
    52    if !(*parser).stream_start_produced {
    53        if yaml_parser_parse(parser, event).fail {
    54            current_block = 6234624449317607669;
    55        } else {
    56            __assert!((*event).type_ == YAML_STREAM_START_EVENT);
    57            current_block = 7815301370352969686;
    58        }
    59    } else {
    60        current_block = 7815301370352969686;
    61    }
    62    if current_block != 6234624449317607669 {
    63        if (*parser).stream_end_produced {
    64            return OK;
    65        }
    66        if yaml_parser_parse(parser, event).ok {
    67            if (*event).type_ == YAML_STREAM_END_EVENT {
    68                return OK;
    69            }
    70            STACK_INIT!((*parser).aliases, yaml_alias_data_t);
    71            let fresh6 = addr_of_mut!((*parser).document);
    72            *fresh6 = document;
    73            if yaml_parser_load_document(parser, event).ok {
    74                yaml_parser_delete_aliases(parser);
    75                let fresh7 = addr_of_mut!((*parser).document);
    76                *fresh7 = ptr::null_mut::<yaml_document_t>();
    77                return OK;
    78            }
    79        }
    80    }
    81    yaml_parser_delete_aliases(parser);
    82    yaml_document_delete(document);
    83    let fresh8 = addr_of_mut!((*parser).document);
    84    *fresh8 = ptr::null_mut::<yaml_document_t>();
    85    FAIL
    86}
    87
    88unsafe fn yaml_parser_set_composer_error(
    89    parser: *mut yaml_parser_t,
    90    problem: *const libc::c_char,
    91    problem_mark: yaml_mark_t,
    92) -> Success {
    93    (*parser).error = YAML_COMPOSER_ERROR;
    94    let fresh9 = addr_of_mut!((*parser).problem);
    95    *fresh9 = problem;
    96    (*parser).problem_mark = problem_mark;
    97    FAIL
    98}
    99
    100unsafe fn yaml_parser_set_composer_error_context(
    101    parser: *mut yaml_parser_t,
    102    context: *const libc::c_char,
    103    context_mark: yaml_mark_t,
    104    problem: *const libc::c_char,
    105    problem_mark: yaml_mark_t,
    106) -> Success {
    107    (*parser).error = YAML_COMPOSER_ERROR;
    108    let fresh10 = addr_of_mut!((*parser).context);
    109    *fresh10 = context;
    110    (*parser).context_mark = context_mark;
    111    let fresh11 = addr_of_mut!((*parser).problem);
    112    *fresh11 = problem;
    113    (*parser).problem_mark = problem_mark;
    114    FAIL
    115}
    116
    117unsafe fn yaml_parser_delete_aliases(parser: *mut yaml_parser_t) {
    118    while !STACK_EMPTY!((*parser).aliases) {
    119        yaml_free(POP!((*parser).aliases).anchor as *mut libc::c_void);
    120    }
    121    STACK_DEL!((*parser).aliases);
    122}
    123
    124unsafe fn yaml_parser_load_document(
    125    parser: *mut yaml_parser_t,
    126    event: *mut yaml_event_t,
    127) -> Success {
    128    let mut ctx = loader_ctx {
    129        start: ptr::null_mut::<libc::c_int>(),
    130        end: ptr::null_mut::<libc::c_int>(),
    131        top: ptr::null_mut::<libc::c_int>(),
    132    };
    133    __assert!((*event).type_ == YAML_DOCUMENT_START_EVENT);
    134    let fresh16 = addr_of_mut!((*(*parser).document).version_directive);
    135    *fresh16 = (*event).data.document_start.version_directive;
    136    let fresh17 = addr_of_mut!((*(*parser).document).tag_directives.start);
    137    *fresh17 = (*event).data.document_start.tag_directives.start;
    138    let fresh18 = addr_of_mut!((*(*parser).document).tag_directives.end);
    139    *fresh18 = (*event).data.document_start.tag_directives.end;
    140    (*(*parser).document).start_implicit = (*event).data.document_start.implicit;
    141    (*(*parser).document).start_mark = (*event).start_mark;
    142    STACK_INIT!(ctx, libc::c_int);
    143    if yaml_parser_load_nodes(parser, addr_of_mut!(ctx)).fail {
    144        STACK_DEL!(ctx);
    145        return FAIL;
    146    }
    147    STACK_DEL!(ctx);
    148    OK
    149}
    150
    151unsafe fn yaml_parser_load_nodes(parser: *mut yaml_parser_t, ctx: *mut loader_ctx) -> Success {
    152    let mut event = MaybeUninit::<yaml_event_t>::uninit();
    153    let event = event.as_mut_ptr();
    154    loop {
    155        if yaml_parser_parse(parser, event).fail {
    156            return FAIL;
    157        }
    158        match (*event).type_ {
    159            YAML_ALIAS_EVENT => {
    160                if yaml_parser_load_alias(parser, event, ctx).fail {
    161                    return FAIL;
    162                }
    163            }
    164            YAML_SCALAR_EVENT => {
    165                if yaml_parser_load_scalar(parser, event, ctx).fail {
    166                    return FAIL;
    167                }
    168            }
    169            YAML_SEQUENCE_START_EVENT => {
    170                if yaml_parser_load_sequence(parser, event, ctx).fail {
    171                    return FAIL;
    172                }
    173            }
    174            YAML_SEQUENCE_END_EVENT => {
    175                if yaml_parser_load_sequence_end(parser, event, ctx).fail {
    176                    return FAIL;
    177                }
    178            }
    179            YAML_MAPPING_START_EVENT => {
    180                if yaml_parser_load_mapping(parser, event, ctx).fail {
    181                    return FAIL;
    182                }
    183            }
    184            YAML_MAPPING_END_EVENT => {
    185                if yaml_parser_load_mapping_end(parser, event, ctx).fail {
    186                    return FAIL;
    187                }
    188            }
    189            YAML_DOCUMENT_END_EVENT => {}
    190            _ => {
    191                __assert!(false);
    192            }
    193        }
    194        if (*event).type_ == YAML_DOCUMENT_END_EVENT {
    195            break;
    196        }
    197    }
    198    (*(*parser).document).end_implicit = (*event).data.document_end.implicit;
    199    (*(*parser).document).end_mark = (*event).end_mark;
    200    OK
    201}
    202
    203unsafe fn yaml_parser_register_anchor(
    204    parser: *mut yaml_parser_t,
    205    index: libc::c_int,
    206    anchor: *mut yaml_char_t,
    207) -> Success {
    208    let mut data = MaybeUninit::<yaml_alias_data_t>::uninit();
    209    let data = data.as_mut_ptr();
    210    let mut alias_data: *mut yaml_alias_data_t;
    211    if anchor.is_null() {
    212        return OK;
    213    }
    214    (*data).anchor = anchor;
    215    (*data).index = index;
    216    (*data).mark = (*(*(*parser).document)
    217        .nodes
    218        .start
    219        .wrapping_offset((index - 1) as isize))
    220    .start_mark;
    221    alias_data = (*parser).aliases.start;
    222    while alias_data != (*parser).aliases.top {
    223        if strcmp(
    224            (*alias_data).anchor as *mut libc::c_char,
    225            anchor as *mut libc::c_char,
    226        ) == 0
    227        {
    228            yaml_free(anchor as *mut libc::c_void);
    229            return yaml_parser_set_composer_error_context(
    230                parser,
    231                b"found duplicate anchor; first occurrence\0" as *const u8 as *const libc::c_char,
    232                (*alias_data).mark,
    233                b"second occurrence\0" as *const u8 as *const libc::c_char,
    234                (*data).mark,
    235            );
    236        }
    237        alias_data = alias_data.wrapping_offset(1);
    238    }
    239    PUSH!((*parser).aliases, *data);
    240    OK
    241}
    242
    243unsafe fn yaml_parser_load_node_add(
    244    parser: *mut yaml_parser_t,
    245    ctx: *mut loader_ctx,
    246    index: libc::c_int,
    247) -> Success {
    248    if STACK_EMPTY!(*ctx) {
    249        return OK;
    250    }
    251    let parent_index: libc::c_int = *(*ctx).top.wrapping_offset(-1_isize);
    252    let parent: *mut yaml_node_t = addr_of_mut!(
    253        *((*(*parser).document).nodes.start).wrapping_offset((parent_index - 1) as isize)
    254    );
    255    let current_block_17: u64;
    256    match (*parent).type_ {
    257        YAML_SEQUENCE_NODE => {
    258            if STACK_LIMIT!(parser, (*parent).data.sequence.items).fail {
    259                return FAIL;
    260            }
    261            PUSH!((*parent).data.sequence.items, index);
    262        }
    263        YAML_MAPPING_NODE => {
    264            let mut pair = MaybeUninit::<yaml_node_pair_t>::uninit();
    265            let pair = pair.as_mut_ptr();
    266            if !STACK_EMPTY!((*parent).data.mapping.pairs) {
    267                let p: *mut yaml_node_pair_t =
    268                    (*parent).data.mapping.pairs.top.wrapping_offset(-1_isize);
    269                if (*p).key != 0 && (*p).value == 0 {
    270                    (*p).value = index;
    271                    current_block_17 = 11307063007268554308;
    272                } else {
    273                    current_block_17 = 17407779659766490442;
    274                }
    275            } else {
    276                current_block_17 = 17407779659766490442;
    277            }
    278            match current_block_17 {
    279                11307063007268554308 => {}
    280                _ => {
    281                    (*pair).key = index;
    282                    (*pair).value = 0;
    283                    if STACK_LIMIT!(parser, (*parent).data.mapping.pairs).fail {
    284                        return FAIL;
    285                    }
    286                    PUSH!((*parent).data.mapping.pairs, *pair);
    287                }
    288            }
    289        }
    290        _ => {
    291            __assert!(false);
    292        }
    293    }
    294    OK
    295}
    296
    297unsafe fn yaml_parser_load_alias(
    298    parser: *mut yaml_parser_t,
    299    event: *mut yaml_event_t,
    300    ctx: *mut loader_ctx,
    301) -> Success {
    302    let anchor: *mut yaml_char_t = (*event).data.alias.anchor;
    303    let mut alias_data: *mut yaml_alias_data_t;
    304    alias_data = (*parser).aliases.start;
    305    while alias_data != (*parser).aliases.top {
    306        if strcmp(
    307            (*alias_data).anchor as *mut libc::c_char,
    308            anchor as *mut libc::c_char,
    309        ) == 0
    310        {
    311            yaml_free(anchor as *mut libc::c_void);
    312            return yaml_parser_load_node_add(parser, ctx, (*alias_data).index);
    313        }
    314        alias_data = alias_data.wrapping_offset(1);
    315    }
    316    yaml_free(anchor as *mut libc::c_void);
    317    yaml_parser_set_composer_error(
    318        parser,
    319        b"found undefined alias\0" as *const u8 as *const libc::c_char,
    320        (*event).start_mark,
    321    )
    322}
    323
    324unsafe fn yaml_parser_load_scalar(
    325    parser: *mut yaml_parser_t,
    326    event: *mut yaml_event_t,
    327    ctx: *mut loader_ctx,
    328) -> Success {
    329    let current_block: u64;
    330    let mut node = MaybeUninit::<yaml_node_t>::uninit();
    331    let node = node.as_mut_ptr();
    332    let index: libc::c_int;
    333    let mut tag: *mut yaml_char_t = (*event).data.scalar.tag;
    334    if STACK_LIMIT!(parser, (*(*parser).document).nodes).ok {
    335        if tag.is_null()
    336            || strcmp(
    337                tag as *mut libc::c_char,
    338                b"!\0" as *const u8 as *const libc::c_char,
    339            ) == 0
    340        {
    341            yaml_free(tag as *mut libc::c_void);
    342            tag = yaml_strdup(
    343                b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
    344            );
    345            if tag.is_null() {
    346                current_block = 10579931339944277179;
    347            } else {
    348                current_block = 11006700562992250127;
    349            }
    350        } else {
    351            current_block = 11006700562992250127;
    352        }
    353        if current_block != 10579931339944277179 {
    354            memset(
    355                node as *mut libc::c_void,
    356                0,
    357                size_of::<yaml_node_t>() as libc::c_ulong,
    358            );
    359            (*node).type_ = YAML_SCALAR_NODE;
    360            (*node).tag = tag;
    361            (*node).start_mark = (*event).start_mark;
    362            (*node).end_mark = (*event).end_mark;
    363            (*node).data.scalar.value = (*event).data.scalar.value;
    364            (*node).data.scalar.length = (*event).data.scalar.length;
    365            (*node).data.scalar.style = (*event).data.scalar.style;
    366            PUSH!((*(*parser).document).nodes, *node);
    367            index = (*(*parser).document)
    368                .nodes
    369                .top
    370                .c_offset_from((*(*parser).document).nodes.start)
    371                as libc::c_int;
    372            if yaml_parser_register_anchor(parser, index, (*event).data.scalar.anchor).fail {
    373                return FAIL;
    374            }
    375            return yaml_parser_load_node_add(parser, ctx, index);
    376        }
    377    }
    378    yaml_free(tag as *mut libc::c_void);
    379    yaml_free((*event).data.scalar.anchor as *mut libc::c_void);
    380    yaml_free((*event).data.scalar.value as *mut libc::c_void);
    381    FAIL
    382}
    383
    384unsafe fn yaml_parser_load_sequence(
    385    parser: *mut yaml_parser_t,
    386    event: *mut yaml_event_t,
    387    ctx: *mut loader_ctx,
    388) -> Success {
    389    let current_block: u64;
    390    let mut node = MaybeUninit::<yaml_node_t>::uninit();
    391    let node = node.as_mut_ptr();
    392    struct Items {
    393        start: *mut yaml_node_item_t,
    394        end: *mut yaml_node_item_t,
    395        top: *mut yaml_node_item_t,
    396    }
    397    let mut items = Items {
    398        start: ptr::null_mut::<yaml_node_item_t>(),
    399        end: ptr::null_mut::<yaml_node_item_t>(),
    400        top: ptr::null_mut::<yaml_node_item_t>(),
    401    };
    402    let index: libc::c_int;
    403    let mut tag: *mut yaml_char_t = (*event).data.sequence_start.tag;
    404    if STACK_LIMIT!(parser, (*(*parser).document).nodes).ok {
    405        if tag.is_null()
    406            || strcmp(
    407                tag as *mut libc::c_char,
    408                b"!\0" as *const u8 as *const libc::c_char,
    409            ) == 0
    410        {
    411            yaml_free(tag as *mut libc::c_void);
    412            tag = yaml_strdup(
    413                b"tag:yaml.org,2002:seq\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
    414            );
    415            if tag.is_null() {
    416                current_block = 13474536459355229096;
    417            } else {
    418                current_block = 6937071982253665452;
    419            }
    420        } else {
    421            current_block = 6937071982253665452;
    422        }
    423        if current_block != 13474536459355229096 {
    424            STACK_INIT!(items, yaml_node_item_t);
    425            memset(
    426                node as *mut libc::c_void,
    427                0,
    428                size_of::<yaml_node_t>() as libc::c_ulong,
    429            );
    430            (*node).type_ = YAML_SEQUENCE_NODE;
    431            (*node).tag = tag;
    432            (*node).start_mark = (*event).start_mark;
    433            (*node).end_mark = (*event).end_mark;
    434            (*node).data.sequence.items.start = items.start;
    435            (*node).data.sequence.items.end = items.end;
    436            (*node).data.sequence.items.top = items.start;
    437            (*node).data.sequence.style = (*event).data.sequence_start.style;
    438            PUSH!((*(*parser).document).nodes, *node);
    439            index = (*(*parser).document)
    440                .nodes
    441                .top
    442                .c_offset_from((*(*parser).document).nodes.start)
    443                as libc::c_int;
    444            if yaml_parser_register_anchor(parser, index, (*event).data.sequence_start.anchor).fail
    445            {
    446                return FAIL;
    447            }
    448            if yaml_parser_load_node_add(parser, ctx, index).fail {
    449                return FAIL;
    450            }
    451            if STACK_LIMIT!(parser, *ctx).fail {
    452                return FAIL;
    453            }
    454            PUSH!(*ctx, index);
    455            return OK;
    456        }
    457    }
    458    yaml_free(tag as *mut libc::c_void);
    459    yaml_free((*event).data.sequence_start.anchor as *mut libc::c_void);
    460    FAIL
    461}
    462
    463unsafe fn yaml_parser_load_sequence_end(
    464    parser: *mut yaml_parser_t,
    465    event: *mut yaml_event_t,
    466    ctx: *mut loader_ctx,
    467) -> Success {
    468    __assert!(((*ctx).top).c_offset_from((*ctx).start) as libc::c_long > 0_i64);
    469    let index: libc::c_int = *(*ctx).top.wrapping_offset(-1_isize);
    470    __assert!(
    471        (*((*(*parser).document).nodes.start).wrapping_offset((index - 1) as isize)).type_
    472            == YAML_SEQUENCE_NODE
    473    );
    474    (*(*(*parser).document)
    475        .nodes
    476        .start
    477        .wrapping_offset((index - 1) as isize))
    478    .end_mark = (*event).end_mark;
    479    let _ = POP!(*ctx);
    480    OK
    481}
    482
    483unsafe fn yaml_parser_load_mapping(
    484    parser: *mut yaml_parser_t,
    485    event: *mut yaml_event_t,
    486    ctx: *mut loader_ctx,
    487) -> Success {
    488    let current_block: u64;
    489    let mut node = MaybeUninit::<yaml_node_t>::uninit();
    490    let node = node.as_mut_ptr();
    491    struct Pairs {
    492        start: *mut yaml_node_pair_t,
    493        end: *mut yaml_node_pair_t,
    494        top: *mut yaml_node_pair_t,
    495    }
    496    let mut pairs = Pairs {
    497        start: ptr::null_mut::<yaml_node_pair_t>(),
    498        end: ptr::null_mut::<yaml_node_pair_t>(),
    499        top: ptr::null_mut::<yaml_node_pair_t>(),
    500    };
    501    let index: libc::c_int;
    502    let mut tag: *mut yaml_char_t = (*event).data.mapping_start.tag;
    503    if STACK_LIMIT!(parser, (*(*parser).document).nodes).ok {
    504        if tag.is_null()
    505            || strcmp(
    506                tag as *mut libc::c_char,
    507                b"!\0" as *const u8 as *const libc::c_char,
    508            ) == 0
    509        {
    510            yaml_free(tag as *mut libc::c_void);
    511            tag = yaml_strdup(
    512                b"tag:yaml.org,2002:map\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
    513            );
    514            if tag.is_null() {
    515                current_block = 13635467803606088781;
    516            } else {
    517                current_block = 6937071982253665452;
    518            }
    519        } else {
    520            current_block = 6937071982253665452;
    521        }
    522        if current_block != 13635467803606088781 {
    523            STACK_INIT!(pairs, yaml_node_pair_t);
    524            memset(
    525                node as *mut libc::c_void,
    526                0,
    527                size_of::<yaml_node_t>() as libc::c_ulong,
    528            );
    529            (*node).type_ = YAML_MAPPING_NODE;
    530            (*node).tag = tag;
    531            (*node).start_mark = (*event).start_mark;
    532            (*node).end_mark = (*event).end_mark;
    533            (*node).data.mapping.pairs.start = pairs.start;
    534            (*node).data.mapping.pairs.end = pairs.end;
    535            (*node).data.mapping.pairs.top = pairs.start;
    536            (*node).data.mapping.style = (*event).data.mapping_start.style;
    537            PUSH!((*(*parser).document).nodes, *node);
    538            index = (*(*parser).document)
    539                .nodes
    540                .top
    541                .c_offset_from((*(*parser).document).nodes.start)
    542                as libc::c_int;
    543            if yaml_parser_register_anchor(parser, index, (*event).data.mapping_start.anchor).fail {
    544                return FAIL;
    545            }
    546            if yaml_parser_load_node_add(parser, ctx, index).fail {
    547                return FAIL;
    548            }
    549            if STACK_LIMIT!(parser, *ctx).fail {
    550                return FAIL;
    551            }
    552            PUSH!(*ctx, index);
    553            return OK;
    554        }
    555    }
    556    yaml_free(tag as *mut libc::c_void);
    557    yaml_free((*event).data.mapping_start.anchor as *mut libc::c_void);
    558    FAIL
    559}
    560
    561unsafe fn yaml_parser_load_mapping_end(
    562    parser: *mut yaml_parser_t,
    563    event: *mut yaml_event_t,
    564    ctx: *mut loader_ctx,
    565) -> Success {
    566    __assert!(((*ctx).top).c_offset_from((*ctx).start) as libc::c_long > 0_i64);
    567    let index: libc::c_int = *(*ctx).top.wrapping_offset(-1_isize);
    568    __assert!(
    569        (*((*(*parser).document).nodes.start).wrapping_offset((index - 1) as isize)).type_
    570            == YAML_MAPPING_NODE
    571    );
    572    (*(*(*parser).document)
    573        .nodes
    574        .start
    575        .wrapping_offset((index - 1) as isize))
    576    .end_mark = (*event).end_mark;
    577    let _ = POP!(*ctx);
    578    OK
    579}