OS_ClearXML:
   62|  1.36k|{
   63|  1.36k|    unsigned int i;
   64|   121k|    for (i = 0; i < _lxml->cur; i++) {
  ------------------
  |  Branch (64:17): [True: 120k, False: 1.36k]
  ------------------
   65|   120k|        free(_lxml->el[i]);
   66|   120k|        free(_lxml->ct[i]);
   67|   120k|    }
   68|  1.36k|    _lxml->cur = 0;
   69|  1.36k|    _lxml->fol = 0;
   70|  1.36k|    _lxml->err_line = 0;
   71|       |
   72|  1.36k|    free(_lxml->el);
   73|  1.36k|    _lxml->el = NULL;
   74|       |
   75|  1.36k|    free(_lxml->ct);
   76|  1.36k|    _lxml->ct = NULL;
   77|       |
   78|  1.36k|    free(_lxml->rl);
   79|  1.36k|    _lxml->rl = NULL;
   80|       |
   81|  1.36k|    free(_lxml->tp);
   82|  1.36k|    _lxml->tp = NULL;
   83|       |
   84|  1.36k|    free(_lxml->ck);
   85|  1.36k|    _lxml->ck = NULL;
   86|       |
   87|  1.36k|    free(_lxml->ln);
   88|  1.36k|    _lxml->ln = NULL;
   89|       |
   90|  1.36k|    memset(_lxml->err, '\0', XML_ERR_LENGTH);
  ------------------
  |  |   24|  1.36k|#define XML_ERR_LENGTH  128
  ------------------
   91|  1.36k|}
OS_ReadXML:
   95|  1.36k|{
   96|  1.36k|    int r;
   97|  1.36k|    unsigned int i;
   98|  1.36k|    FILE *fp;
   99|       |
  100|       |    /* Initialize xml structure */
  101|  1.36k|    _lxml->cur = 0;
  102|  1.36k|    _lxml->fol = 0;
  103|  1.36k|    _lxml->el = NULL;
  104|  1.36k|    _lxml->ct = NULL;
  105|  1.36k|    _lxml->tp = NULL;
  106|  1.36k|    _lxml->rl = NULL;
  107|  1.36k|    _lxml->ck = NULL;
  108|  1.36k|    _lxml->ln = NULL;
  109|       |
  110|  1.36k|    _lxml->err_line = 0;
  111|  1.36k|    memset(_lxml->err, '\0', XML_ERR_LENGTH);
  ------------------
  |  |   24|  1.36k|#define XML_ERR_LENGTH  128
  ------------------
  112|       |
  113|  1.36k|    fp = fopen(file, "r");
  114|  1.36k|    if (!fp) {
  ------------------
  |  Branch (114:9): [True: 0, False: 1.36k]
  ------------------
  115|      0|        xml_error(_lxml, "XMLERR: File '%s' not found.", file);
  116|      0|        return (-2);
  117|      0|    }
  118|       |
  119|       |    /* Zero the line */
  120|  1.36k|    _line = 1;
  121|       |
  122|       |    /* Skip a leading <?xml ...?> prolog when present (PR #564 / @lazyp). */
  123|  1.36k|    if (_skip_xml_declaration(fp) < 0) {
  ------------------
  |  Branch (123:9): [True: 53, False: 1.30k]
  ------------------
  124|     53|        xml_error(_lxml, "XMLERR: XML declaration not closed.");
  125|     53|        fclose(fp);
  126|     53|        return (-1);
  127|     53|    }
  128|       |
  129|  1.30k|    if ((r = _ReadElem(fp, 0, _lxml, 0)) < 0) { /* First position */
  ------------------
  |  Branch (129:9): [True: 1.30k, False: 0]
  ------------------
  130|  1.30k|        if (r != LEOF) {
  ------------------
  |  |   18|  1.30k|#define LEOF        -2
  ------------------
  |  Branch (130:13): [True: 1.05k, False: 255]
  ------------------
  131|  1.05k|            fclose(fp);
  132|  1.05k|            return (-1);
  133|  1.05k|        }
  134|  1.30k|    }
  135|       |
  136|  80.1k|    for (i = 0; i < _lxml->cur; i++) {
  ------------------
  |  Branch (136:17): [True: 79.9k, False: 255]
  ------------------
  137|  79.9k|        if (_lxml->ck[i] == 0) {
  ------------------
  |  Branch (137:13): [True: 0, False: 79.9k]
  ------------------
  138|      0|            xml_error(_lxml, "XMLERR: Element '%s' not closed.", _lxml->el[i]);
  139|      0|            fclose(fp);
  140|      0|            return (-1);
  141|      0|        }
  142|  79.9k|    }
  143|       |
  144|    255|    fclose(fp);
  145|    255|    return (0);
  146|    255|}
os_xml.c:xml_error:
   50|  1.10k|{
   51|  1.10k|    va_list args;
   52|  1.10k|    va_start(args, msg);
   53|       |
   54|  1.10k|    memset(_lxml->err, '\0', XML_ERR_LENGTH);
  ------------------
  |  |   24|  1.10k|#define XML_ERR_LENGTH  128
  ------------------
   55|  1.10k|    vsnprintf(_lxml->err, XML_ERR_LENGTH - 1, msg, args);
  ------------------
  |  |   24|  1.10k|#define XML_ERR_LENGTH  128
  ------------------
   56|       |    va_end(args);
   57|  1.10k|    _lxml->err_line = _line;
   58|  1.10k|}
os_xml.c:_skip_xml_declaration:
  152|  1.36k|{
  153|  1.36k|    long start;
  154|  1.36k|    unsigned char sig[5];
  155|  1.36k|    size_t n;
  156|  1.36k|    int c;
  157|  1.36k|    int prev = 0;
  158|  1.36k|    size_t i;
  159|       |
  160|  1.36k|    start = ftell(fp);
  161|  1.36k|    if (start < 0) {
  ------------------
  |  Branch (161:9): [True: 0, False: 1.36k]
  ------------------
  162|      0|        return (0);
  163|      0|    }
  164|       |
  165|       |    /* Optional UTF-8 BOM */
  166|  1.36k|    n = fread(sig, 1, 3, fp);
  167|  1.36k|    if (n == 3 && sig[0] == 0xEF && sig[1] == 0xBB && sig[2] == 0xBF) {
  ------------------
  |  Branch (167:9): [True: 1.29k, False: 68]
  |  Branch (167:19): [True: 27, False: 1.26k]
  |  Branch (167:37): [True: 14, False: 13]
  |  Branch (167:55): [True: 1, False: 13]
  ------------------
  168|      1|        start = ftell(fp);
  169|  1.36k|    } else {
  170|  1.36k|        clearerr(fp);
  171|  1.36k|        if (fseek(fp, start, SEEK_SET) != 0) {
  ------------------
  |  Branch (171:13): [True: 0, False: 1.36k]
  ------------------
  172|      0|            return (0);
  173|      0|        }
  174|  1.36k|    }
  175|       |
  176|  1.36k|    n = fread(sig, 1, 5, fp);
  177|  1.36k|    if (n == 5 &&
  ------------------
  |  Branch (177:9): [True: 1.06k, False: 292]
  ------------------
  178|  1.06k|            sig[0] == (unsigned char)_R_CONFS &&
  ------------------
  |  |   13|  2.43k|#define _R_CONFS    '<'
  ------------------
  |  Branch (178:13): [True: 954, False: 115]
  ------------------
  179|    954|            sig[1] == (unsigned char)_R_HEADER &&
  ------------------
  |  |   16|  2.31k|#define _R_HEADER   '?'
  ------------------
  |  Branch (179:13): [True: 107, False: 847]
  ------------------
  180|    107|            sig[2] == 'x' && sig[3] == 'm' && sig[4] == 'l') {
  ------------------
  |  Branch (180:13): [True: 86, False: 21]
  |  Branch (180:30): [True: 72, False: 14]
  |  Branch (180:47): [True: 54, False: 18]
  ------------------
  181|    324|        for (i = 0; i < n; i++) {
  ------------------
  |  Branch (181:21): [True: 270, False: 54]
  ------------------
  182|    270|            if (sig[i] == '\n') {
  ------------------
  |  Branch (182:17): [True: 0, False: 270]
  ------------------
  183|      0|                _line++;
  184|      0|            }
  185|    270|        }
  186|     54|        prev = 'l';
  187|    667|        while ((c = _xml_fgetc(fp)) != EOF) {
  ------------------
  |  Branch (187:16): [True: 614, False: 53]
  ------------------
  188|    614|            if (prev == _R_HEADER && c == _R_CONFE) {
  ------------------
  |  |   16|  1.22k|#define _R_HEADER   '?'
  ------------------
                          if (prev == _R_HEADER && c == _R_CONFE) {
  ------------------
  |  |   14|     73|#define _R_CONFE    '>'
  ------------------
  |  Branch (188:17): [True: 73, False: 541]
  |  Branch (188:38): [True: 1, False: 72]
  ------------------
  189|      1|                return (0);
  190|      1|            }
  191|    613|            prev = c;
  192|    613|        }
  193|     53|        return (-1);
  194|     54|    }
  195|       |
  196|  1.30k|    clearerr(fp);
  197|  1.30k|    if (fseek(fp, start, SEEK_SET) != 0) {
  ------------------
  |  Branch (197:9): [True: 0, False: 1.30k]
  ------------------
  198|      0|        return (0);
  199|      0|    }
  200|  1.30k|    return (0);
  201|  1.30k|}
os_xml.c:_xml_fgetc:
   38|   787k|{
   39|   787k|    int c;
   40|   787k|    c = fgetc(fp);
   41|       |
   42|   787k|    if (c == '\n') { /* add newline */
  ------------------
  |  Branch (42:9): [True: 5.37k, False: 782k]
  ------------------
   43|  5.37k|        _line++;
   44|  5.37k|    }
   45|       |
   46|   787k|    return (c);
   47|   787k|}
os_xml.c:_ReadElem:
  233|  26.8k|{
  234|  26.8k|    int c;
  235|  26.8k|    unsigned int count = 0;
  236|  26.8k|    unsigned int _currentlycont = 0;
  237|  26.8k|    short int location = -1;
  238|  26.8k|    int retval = -1;
  239|       |
  240|  26.8k|    int prevv = 0;
  241|  26.8k|    char *elem = NULL;
  242|  26.8k|    char *cont = NULL;
  243|  26.8k|    char *closedelim = NULL;
  244|       |
  245|  26.8k|    if (++recursion_level > 1024) {
  ------------------
  |  Branch (245:9): [True: 1, False: 26.8k]
  ------------------
  246|      1|        xml_error(_lxml, "XMLERR: Max recursion level reached.");
  247|      1|        return (-1);
  248|      1|    }
  249|       |
  250|  26.8k|    elem = (char *)calloc(XML_MAXSIZE + 1, sizeof(char));
  ------------------
  |  |   20|  26.8k|#define XML_MAXSIZE          8192
  ------------------
  251|  26.8k|    cont = (char *)calloc(XML_MAXSIZE + 1, sizeof(char));
  ------------------
  |  |   20|  26.8k|#define XML_MAXSIZE          8192
  ------------------
  252|  26.8k|    closedelim = (char *)calloc(XML_MAXSIZE + 1, sizeof(char));
  ------------------
  |  |   20|  26.8k|#define XML_MAXSIZE          8192
  ------------------
  253|       |
  254|  26.8k|    if (!elem || !cont || !closedelim) {
  ------------------
  |  Branch (254:9): [True: 0, False: 26.8k]
  |  Branch (254:18): [True: 0, False: 26.8k]
  |  Branch (254:27): [True: 0, False: 26.8k]
  ------------------
  255|      0|        xml_error(_lxml, "XMLERR: Memory error.");
  256|      0|        goto end;
  257|      0|    }
  258|       |
  259|   456k|    while ((c = _xml_fgetc(fp)) != EOF) {
  ------------------
  |  Branch (259:12): [True: 456k, False: 520]
  ------------------
  260|   456k|        if (c == '\\') {
  ------------------
  |  Branch (260:13): [True: 2.58k, False: 453k]
  ------------------
  261|  2.58k|            prevv = c;
  262|   453k|        } else if (prevv == '\\') {
  ------------------
  |  Branch (262:20): [True: 700, False: 453k]
  ------------------
  263|    700|            if (c != _R_CONFS) {
  ------------------
  |  |   13|    700|#define _R_CONFS    '<'
  ------------------
  |  Branch (263:17): [True: 237, False: 463]
  ------------------
  264|    237|                prevv = 0;
  265|    237|            }
  266|    700|        }
  267|       |
  268|       |        /* Max size */
  269|   456k|        if (count >= XML_MAXSIZE) {
  ------------------
  |  |   20|   456k|#define XML_MAXSIZE          8192
  ------------------
  |  Branch (269:13): [True: 1, False: 456k]
  ------------------
  270|      1|            xml_error(_lxml, "XMLERR: String overflow.");
  271|      1|            goto end;
  272|      1|        }
  273|       |
  274|       |        /* Check for comments */
  275|   456k|        if (c == _R_CONFS) {
  ------------------
  |  |   13|   456k|#define _R_CONFS    '<'
  ------------------
  |  Branch (275:13): [True: 132k, False: 323k]
  ------------------
  276|   132k|            int r = 0;
  277|   132k|            if ((r = _oscomment(fp)) < 0) {
  ------------------
  |  Branch (277:17): [True: 116, False: 132k]
  ------------------
  278|    116|                xml_error(_lxml, "XMLERR: Comment not closed.");
  279|    116|                goto end;
  280|   132k|            } else if (r == 1) {
  ------------------
  |  Branch (280:24): [True: 389, False: 131k]
  ------------------
  281|    389|                continue;
  282|    389|            }
  283|   132k|        }
  284|       |
  285|       |        /* Real checking */
  286|   455k|        if ((location == -1) && (prevv == 0)) {
  ------------------
  |  Branch (286:13): [True: 181k, False: 274k]
  |  Branch (286:33): [True: 180k, False: 925]
  ------------------
  287|   180k|            if (c == _R_CONFS) {
  ------------------
  |  |   13|   180k|#define _R_CONFS    '<'
  ------------------
  |  Branch (287:17): [True: 100k, False: 80.4k]
  ------------------
  288|   100k|                if ((c = fgetc(fp)) == '/') {
  ------------------
  |  Branch (288:21): [True: 2, False: 100k]
  ------------------
  289|      2|                    xml_error(_lxml, "XMLERR: Element not opened.");
  290|      2|                    goto end;
  291|   100k|                } else {
  292|   100k|                    ungetc(c, fp);
  293|   100k|                }
  294|   100k|                location = 0;
  295|   100k|            } else {
  296|  80.4k|                continue;
  297|  80.4k|            }
  298|   180k|        }
  299|       |
  300|   275k|        else if ((location == 0) && ((c == _R_CONFE) || isspace(c))) {
  ------------------
  |  |   14|   237k|#define _R_CONFE    '>'
  ------------------
  |  Branch (300:18): [True: 237k, False: 37.5k]
  |  Branch (300:38): [True: 16.2k, False: 221k]
  |  Branch (300:57): [True: 83.6k, False: 137k]
  ------------------
  301|  99.8k|            int _ge = 0;
  302|  99.8k|            int _ga = 0;
  303|  99.8k|            elem[count] = '\0';
  304|       |
  305|       |            /* Remove the / at the end of the element name */
  306|  99.8k|            if (count > 0 && elem[count - 1] == '/') {
  ------------------
  |  Branch (306:17): [True: 2.72k, False: 97.1k]
  |  Branch (306:30): [True: 207, False: 2.51k]
  ------------------
  307|    207|                _ge = '/';
  308|    207|                elem[count - 1] = '\0';
  309|    207|            }
  310|       |
  311|  99.8k|            if (_writememory(elem, XML_ELEM, count + 1, parent, _lxml) < 0) {
  ------------------
  |  Branch (311:17): [True: 0, False: 99.8k]
  ------------------
  312|      0|                goto end;
  313|      0|            }
  314|  99.8k|            _currentlycont = _lxml->cur - 1;
  315|  99.8k|            if (isspace(c)) {
  ------------------
  |  Branch (315:17): [True: 83.6k, False: 16.2k]
  ------------------
  316|  83.6k|                if ((_ga = _getattributes(fp, parent, _lxml)) < 0) {
  ------------------
  |  Branch (316:21): [True: 544, False: 83.1k]
  ------------------
  317|    544|                    goto end;
  318|    544|                }
  319|  83.6k|            }
  320|       |
  321|       |            /* If the element is closed already (finished in />) */
  322|  99.3k|            if ((_ge == '/') || (_ga == '/')) {
  ------------------
  |  Branch (322:17): [True: 207, False: 99.1k]
  |  Branch (322:33): [True: 82.6k, False: 16.4k]
  ------------------
  323|  82.8k|                if (_writecontent("\0", 2, _currentlycont, _lxml) < 0) {
  ------------------
  |  Branch (323:21): [True: 0, False: 82.8k]
  ------------------
  324|      0|                    goto end;
  325|      0|                }
  326|  82.8k|                _lxml->ck[_currentlycont] = 1;
  327|  82.8k|                _currentlycont = 0;
  328|  82.8k|                count = 0;
  329|  82.8k|                location = -1;
  330|       |
  331|  82.8k|                memset(elem, '\0', XML_MAXSIZE);
  ------------------
  |  |   20|  82.8k|#define XML_MAXSIZE          8192
  ------------------
  332|  82.8k|                memset(closedelim, '\0', XML_MAXSIZE);
  ------------------
  |  |   20|  82.8k|#define XML_MAXSIZE          8192
  ------------------
  333|  82.8k|                memset(cont, '\0', XML_MAXSIZE);
  ------------------
  |  |   20|  82.8k|#define XML_MAXSIZE          8192
  ------------------
  334|       |
  335|  82.8k|                if (parent > 0) {
  ------------------
  |  Branch (335:21): [True: 10.0k, False: 72.8k]
  ------------------
  336|  10.0k|                    retval = 0;
  337|  10.0k|                    goto end;
  338|  10.0k|                }
  339|  82.8k|            } else {
  340|  16.4k|                count = 0;
  341|  16.4k|                location = 1;
  342|  16.4k|            }
  343|  99.3k|        }
  344|       |
  345|   175k|        else if ((location == 2) && (c == _R_CONFE)) {
  ------------------
  |  |   14|  5.19k|#define _R_CONFE    '>'
  ------------------
  |  Branch (345:18): [True: 5.19k, False: 170k]
  |  Branch (345:37): [True: 2.53k, False: 2.66k]
  ------------------
  346|  2.53k|            closedelim[count] = '\0';
  347|  2.53k|            if (strcmp(closedelim, elem) != 0) {
  ------------------
  |  Branch (347:17): [True: 124, False: 2.40k]
  ------------------
  348|    124|                xml_error(_lxml, "XMLERR: Element '%s' not closed.", elem);
  349|    124|                goto end;
  350|    124|            }
  351|  2.40k|            if (_writecontent(cont, strlen(cont) + 1, _currentlycont, _lxml) < 0) {
  ------------------
  |  Branch (351:17): [True: 0, False: 2.40k]
  ------------------
  352|      0|                goto end;
  353|      0|            }
  354|  2.40k|            _lxml->ck[_currentlycont] = 1;
  355|  2.40k|            memset(elem, '\0', XML_MAXSIZE);
  ------------------
  |  |   20|  2.40k|#define XML_MAXSIZE          8192
  ------------------
  356|  2.40k|            memset(closedelim, '\0', XML_MAXSIZE);
  ------------------
  |  |   20|  2.40k|#define XML_MAXSIZE          8192
  ------------------
  357|  2.40k|            memset(cont, '\0', XML_MAXSIZE);
  ------------------
  |  |   20|  2.40k|#define XML_MAXSIZE          8192
  ------------------
  358|  2.40k|            _currentlycont = 0;
  359|  2.40k|            count = 0;
  360|  2.40k|            location = -1;
  361|  2.40k|            if (parent > 0) {
  ------------------
  |  Branch (361:17): [True: 1.70k, False: 708]
  ------------------
  362|  1.70k|                retval = 0;
  363|  1.70k|                goto end;
  364|  1.70k|            }
  365|   172k|        } else if ((location == 1) && (c == _R_CONFS) && (prevv == 0)) {
  ------------------
  |  |   13|  31.3k|#define _R_CONFS    '<'
  ------------------
  |  Branch (365:20): [True: 31.3k, False: 141k]
  |  Branch (365:39): [True: 28.3k, False: 3.03k]
  |  Branch (365:58): [True: 28.1k, False: 204]
  ------------------
  366|  28.1k|            if ((c = fgetc(fp)) == '/') {
  ------------------
  |  Branch (366:17): [True: 2.55k, False: 25.5k]
  ------------------
  367|  2.55k|                cont[count] = '\0';
  368|  2.55k|                count = 0;
  369|  2.55k|                location = 2;
  370|  25.5k|            } else {
  371|  25.5k|                ungetc(c, fp);
  372|  25.5k|                ungetc(_R_CONFS, fp);
  ------------------
  |  |   13|  25.5k|#define _R_CONFS    '<'
  ------------------
  373|       |
  374|  25.5k|                if (_ReadElem(fp, parent + 1, _lxml, recursion_level) < 0) {
  ------------------
  |  Branch (374:21): [True: 13.8k, False: 11.7k]
  ------------------
  375|  13.8k|                    goto end;
  376|  13.8k|                }
  377|  11.7k|                count = 0;
  378|  11.7k|            }
  379|   144k|        } else {
  380|   144k|            if (location == 0) {
  ------------------
  |  Branch (380:17): [True: 137k, False: 6.83k]
  ------------------
  381|   137k|                elem[count++] = (char) c;
  382|   137k|            } else if (location == 1) {
  ------------------
  |  Branch (382:24): [True: 3.24k, False: 3.59k]
  ------------------
  383|  3.24k|                cont[count++] = (char) c;
  384|  3.59k|            } else if (location == 2) {
  ------------------
  |  Branch (384:24): [True: 2.66k, False: 925]
  ------------------
  385|  2.66k|                closedelim[count++] = (char) c;
  386|  2.66k|            }
  387|       |
  388|   144k|            if ((_R_CONFS == c) && (prevv != 0)) {
  ------------------
  |  |   13|   144k|#define _R_CONFS    '<'
  ------------------
  |  Branch (388:17): [True: 3.77k, False: 140k]
  |  Branch (388:36): [True: 463, False: 3.31k]
  ------------------
  389|    463|                prevv = 0;
  390|    463|            }
  391|   144k|        }
  392|   455k|    }
  393|    520|    if (location == -1) {
  ------------------
  |  Branch (393:9): [True: 255, False: 265]
  ------------------
  394|    255|        retval = LEOF;
  ------------------
  |  |   18|    255|#define LEOF        -2
  ------------------
  395|    255|        goto end;
  396|    255|    }
  397|       |
  398|    265|    xml_error(_lxml, "XMLERR: End of file and some elements were not closed.");
  399|       |
  400|  26.8k|end:
  401|  26.8k|    free(elem);
  402|  26.8k|    free(cont);
  403|  26.8k|    free(closedelim);
  404|  26.8k|    return (retval);
  405|    265|}
os_xml.c:_oscomment:
  204|   132k|{
  205|   132k|    int c;
  206|   132k|    if ((c = fgetc(fp)) == _R_COM) {
  ------------------
  |  |   15|   132k|#define _R_COM      '!'
  ------------------
  |  Branch (206:9): [True: 505, False: 131k]
  ------------------
  207|  2.44k|        while ((c = _xml_fgetc(fp)) != EOF) {
  ------------------
  |  Branch (207:16): [True: 2.32k, False: 116]
  ------------------
  208|  2.32k|            if (c == _R_COM) {
  ------------------
  |  |   15|  2.32k|#define _R_COM      '!'
  ------------------
  |  Branch (208:17): [True: 411, False: 1.91k]
  ------------------
  209|    411|                if ((c = fgetc(fp)) == _R_CONFE) {
  ------------------
  |  |   14|    411|#define _R_CONFE    '>'
  ------------------
  |  Branch (209:21): [True: 194, False: 217]
  ------------------
  210|    194|                    return (1);
  211|    194|                }
  212|    217|                ungetc(c, fp);
  213|  1.91k|            } else if (c == '-') {  /* W3C way of finishing comments */
  ------------------
  |  Branch (213:24): [True: 814, False: 1.10k]
  ------------------
  214|    814|                if ((c = _xml_fgetc(fp)) == '-') {
  ------------------
  |  Branch (214:21): [True: 404, False: 410]
  ------------------
  215|    404|                    if ((c = fgetc(fp)) == _R_CONFE) {
  ------------------
  |  |   14|    404|#define _R_CONFE    '>'
  ------------------
  |  Branch (215:25): [True: 195, False: 209]
  ------------------
  216|    195|                        return (1);
  217|    195|                    }
  218|    209|                    ungetc(c, fp);
  219|    209|                }
  220|    619|                ungetc(c, fp);
  221|  1.10k|            } else {
  222|  1.10k|                continue;
  223|  1.10k|            }
  224|  2.32k|        }
  225|    116|        return (-1);
  226|   131k|    } else {
  227|   131k|        ungetc(c, fp);
  228|   131k|    }
  229|   131k|    return (0);
  230|   132k|}
os_xml.c:_writememory:
  409|   120k|{
  410|   120k|    char **tmp;
  411|   120k|    int *tmp2;
  412|   120k|    unsigned int *tmp3;
  413|   120k|    XML_TYPE *tmp4;
  414|       |
  415|       |    /* Allocate for the element */
  416|   120k|    tmp = (char **)realloc(_lxml->el, (_lxml->cur + 1) * sizeof(char *));
  417|   120k|    if (tmp == NULL) {
  ------------------
  |  Branch (417:9): [True: 0, False: 120k]
  ------------------
  418|      0|        goto fail;
  419|      0|    }
  420|   120k|    _lxml->el = tmp;
  421|   120k|    _lxml->el[_lxml->cur] = (char *)calloc(size, sizeof(char));
  422|   120k|    if (_lxml->el[_lxml->cur] == NULL) {
  ------------------
  |  Branch (422:9): [True: 0, False: 120k]
  ------------------
  423|      0|        goto fail;
  424|      0|    }
  425|   120k|    strncpy(_lxml->el[_lxml->cur], str, size - 1);
  426|       |
  427|       |    /* Allocate for the content */
  428|   120k|    tmp = (char **)realloc(_lxml->ct, (_lxml->cur + 1) * sizeof(char *));
  429|   120k|    if (tmp == NULL) {
  ------------------
  |  Branch (429:9): [True: 0, False: 120k]
  ------------------
  430|      0|        goto fail;
  431|      0|    }
  432|   120k|    _lxml->ct = tmp;
  433|   120k|    _lxml->ct[_lxml->cur] = NULL;
  434|       |
  435|       |    /* Allocate for the type */
  436|   120k|    tmp4 = (XML_TYPE *) realloc(_lxml->tp, (_lxml->cur + 1) * sizeof(XML_TYPE));
  437|   120k|    if (tmp4 == NULL) {
  ------------------
  |  Branch (437:9): [True: 0, False: 120k]
  ------------------
  438|      0|        goto fail;
  439|      0|    }
  440|   120k|    _lxml->tp = tmp4;
  441|   120k|    _lxml->tp[_lxml->cur] = type;
  442|       |
  443|       |    /* Allocate for the relation */
  444|   120k|    tmp3 = (unsigned int *) realloc(_lxml->rl, (_lxml->cur + 1) * sizeof(unsigned int));
  445|   120k|    if (tmp3 == NULL) {
  ------------------
  |  Branch (445:9): [True: 0, False: 120k]
  ------------------
  446|      0|        goto fail;
  447|      0|    }
  448|   120k|    _lxml->rl = tmp3;
  449|   120k|    _lxml->rl[_lxml->cur] = parent;
  450|       |
  451|       |    /* Allocate for the "check" */
  452|   120k|    tmp2 = (int *) realloc(_lxml->ck, (_lxml->cur + 1) * sizeof(int));
  453|   120k|    if (tmp2 == NULL) {
  ------------------
  |  Branch (453:9): [True: 0, False: 120k]
  ------------------
  454|      0|        goto fail;
  455|      0|    }
  456|   120k|    _lxml->ck = tmp2;
  457|   120k|    _lxml->ck[_lxml->cur] = 0;
  458|       |
  459|       |    /* Allocate for the line */
  460|   120k|    tmp3 = (unsigned int *) realloc(_lxml->ln, (_lxml->cur + 1) * sizeof(unsigned int));
  461|   120k|    if (tmp3 == NULL) {
  ------------------
  |  Branch (461:9): [True: 0, False: 120k]
  ------------------
  462|      0|        goto fail;
  463|      0|    }
  464|   120k|    _lxml->ln = tmp3;
  465|   120k|    _lxml->ln[_lxml->cur] = _line;
  466|       |
  467|       |    /* Attributes does not need to be closed */
  468|   120k|    if (type == XML_ATTR) {
  ------------------
  |  Branch (468:9): [True: 20.1k, False: 99.8k]
  ------------------
  469|  20.1k|        _lxml->ck[_lxml->cur] = 1;
  470|  20.1k|    }
  471|       |
  472|       |    /* Check if it is a variable */
  473|   120k|    if (strcasecmp(XML_VAR, str) == 0) {
  ------------------
  |  |   23|   120k|#define XML_VAR              "var"
  ------------------
  |  Branch (473:9): [True: 1.41k, False: 118k]
  ------------------
  474|  1.41k|        _lxml->tp[_lxml->cur] = XML_VARIABLE_BEGIN;
  475|  1.41k|    }
  476|       |
  477|   120k|    _lxml->cur++;
  478|   120k|    return (0);
  479|       |
  480|      0|fail:
  481|      0|    snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error.");
  ------------------
  |  |   24|      0|#define XML_ERR_LENGTH  128
  ------------------
  482|      0|    return (-1);
  483|   120k|}
os_xml.c:_getattributes:
  499|  92.3k|{
  500|  92.3k|    int location = 0;
  501|  92.3k|    unsigned int count = 0;
  502|  92.3k|    int c;
  503|  92.3k|    int c_to_match = 0;
  504|       |
  505|  92.3k|    char attr[XML_MAXSIZE + 1];
  506|  92.3k|    char value[XML_MAXSIZE + 1];
  507|       |
  508|  92.3k|    memset(attr, '\0', XML_MAXSIZE + 1);
  ------------------
  |  |   20|  92.3k|#define XML_MAXSIZE          8192
  ------------------
  509|  92.3k|    memset(value, '\0', XML_MAXSIZE + 1);
  ------------------
  |  |   20|  92.3k|#define XML_MAXSIZE          8192
  ------------------
  510|       |
  511|   284k|    while ((c = _xml_fgetc(fp)) != EOF) {
  ------------------
  |  Branch (511:12): [True: 284k, False: 255]
  ------------------
  512|   284k|        if (count >= XML_MAXSIZE) {
  ------------------
  |  |   20|   284k|#define XML_MAXSIZE          8192
  ------------------
  |  Branch (512:13): [True: 1, False: 284k]
  ------------------
  513|      1|            attr[count - 1] = '\0';
  514|      1|            xml_error(_lxml,
  515|      1|                      "XMLERR: Overflow attempt at attribute '%.20s'.", attr);
  516|      1|            return (-1);
  517|      1|        }
  518|       |
  519|   284k|        else if ((c == _R_CONFE) || ((location == 0) && (c == '/'))) {
  ------------------
  |  |   14|   284k|#define _R_CONFE    '>'
  ------------------
  |  Branch (519:18): [True: 266, False: 284k]
  |  Branch (519:38): [True: 230k, False: 54.0k]
  |  Branch (519:57): [True: 71.3k, False: 158k]
  ------------------
  520|  71.6k|            if (location == 1) {
  ------------------
  |  Branch (520:17): [True: 2, False: 71.6k]
  ------------------
  521|      2|                xml_error(_lxml, "XMLERR: Attribute '%s' not closed.",
  522|      2|                          attr);
  523|      2|                return (-1);
  524|  71.6k|            } else if ((location == 0) && (count > 0)) {
  ------------------
  |  Branch (524:24): [True: 71.6k, False: 0]
  |  Branch (524:43): [True: 10, False: 71.6k]
  ------------------
  525|     10|                xml_error(_lxml, "XMLERR: Attribute '%s' has no value.",
  526|     10|                          attr);
  527|     10|                return (-1);
  528|  71.6k|            } else if (c == '/') {
  ------------------
  |  Branch (528:24): [True: 71.3k, False: 255]
  ------------------
  529|  71.3k|                return (c);
  530|  71.3k|            } else {
  531|    255|                return (0);
  532|    255|            }
  533|   212k|        } else if ((location == 0) && (c == '=')) {
  ------------------
  |  Branch (533:20): [True: 158k, False: 54.0k]
  |  Branch (533:39): [True: 20.4k, False: 138k]
  ------------------
  534|  20.4k|            attr[count] = '\0';
  535|       |
  536|       |            /* Check for existing attribute with same name */
  537|  20.4k|            unsigned int i = _lxml->cur - 1;
  538|       |            /* Search attributes backwards in same parent */
  539|  43.7k|            while (_lxml->rl[i] == parent && _lxml->tp[i] == XML_ATTR) {
  ------------------
  |  Branch (539:20): [True: 43.7k, False: 0]
  |  Branch (539:46): [True: 23.3k, False: 20.4k]
  ------------------
  540|  23.3k|                if (strcmp(_lxml->el[i], attr) == 0) {
  ------------------
  |  Branch (540:21): [True: 8, False: 23.3k]
  ------------------
  541|      8|                    xml_error(_lxml, "XMLERR: Attribute '%s' already defined.", attr);
  542|      8|                    return (-1);
  543|      8|                }
  544|       |
  545|       |                /* Continue with previous element */
  546|  23.3k|                if (i == 0) {
  ------------------
  |  Branch (546:21): [True: 0, False: 23.3k]
  ------------------
  547|      0|                    break;
  548|      0|                }
  549|  23.3k|                i--;
  550|  23.3k|            }
  551|       |
  552|  20.4k|            c = _xml_fgetc(fp);
  553|  20.4k|            if ((c != '"') && (c != '\'')) {
  ------------------
  |  Branch (553:17): [True: 1.04k, False: 19.4k]
  |  Branch (553:31): [True: 716, False: 324]
  ------------------
  554|    716|                unsigned short int _err = 1;
  555|    716|                if (isspace(c)) {
  ------------------
  |  Branch (555:21): [True: 540, False: 176]
  ------------------
  556|  1.27k|                    while ((c = _xml_fgetc(fp)) != EOF) {
  ------------------
  |  Branch (556:28): [True: 1.24k, False: 28]
  ------------------
  557|  1.24k|                        if (isspace(c)) {
  ------------------
  |  Branch (557:29): [True: 735, False: 512]
  ------------------
  558|    735|                            continue;
  559|    735|                        } else if ((c == '"') || (c == '\'')) {
  ------------------
  |  Branch (559:36): [True: 279, False: 233]
  |  Branch (559:50): [True: 206, False: 27]
  ------------------
  560|    485|                            _err = 0;
  561|    485|                            break;
  562|    485|                        } else {
  563|     27|                            break;
  564|     27|                        }
  565|  1.24k|                    }
  566|    540|                }
  567|    716|                if (_err != 0) {
  ------------------
  |  Branch (567:21): [True: 231, False: 485]
  ------------------
  568|    231|                    xml_error(_lxml,
  569|    231|                              "XMLERR: Attribute '%s' not followed by a \" or \'."
  570|    231|                              , attr);
  571|    231|                    return (-1);
  572|    231|                }
  573|    716|            }
  574|       |
  575|  20.2k|            c_to_match = c;
  576|  20.2k|            location = 1;
  577|  20.2k|            count = 0;
  578|   192k|        } else if ((location == 0) && (isspace(c))) {
  ------------------
  |  Branch (578:20): [True: 138k, False: 54.0k]
  |  Branch (578:39): [True: 3.84k, False: 134k]
  ------------------
  579|  3.84k|            if (count == 0) {
  ------------------
  |  Branch (579:17): [True: 3.83k, False: 8]
  ------------------
  580|  3.83k|                continue;
  581|  3.83k|            } else {
  582|      8|                xml_error(_lxml, "XMLERR: Attribute '%s' has no value.", attr);
  583|      8|                return (-1);
  584|      8|            }
  585|   188k|        } else if ((location == 1) && (c == c_to_match)) {
  ------------------
  |  Branch (585:20): [True: 54.0k, False: 134k]
  |  Branch (585:39): [True: 20.1k, False: 33.9k]
  ------------------
  586|  20.1k|            value[count] = '\0';
  587|       |
  588|  20.1k|            if (_writememory(attr, XML_ATTR, strlen(attr) + 1,
  ------------------
  |  Branch (588:17): [True: 0, False: 20.1k]
  ------------------
  589|  20.1k|                             parent, _lxml) < 0) {
  590|      0|                return (-1);
  591|      0|            }
  592|  20.1k|            if (_writecontent(value, count + 1, _lxml->cur - 1, _lxml) < 0) {
  ------------------
  |  Branch (592:17): [True: 0, False: 20.1k]
  ------------------
  593|      0|                return (-1);
  594|      0|            }
  595|  20.1k|            c = _xml_fgetc(fp);
  596|  20.1k|            if (isspace(c)) {
  ------------------
  |  Branch (596:17): [True: 8.64k, False: 11.5k]
  ------------------
  597|  8.64k|                return (_getattributes(fp, parent, _lxml));
  598|  11.5k|            } else if (c == _R_CONFE) {
  ------------------
  |  |   14|  11.5k|#define _R_CONFE    '>'
  ------------------
  |  Branch (598:24): [True: 236, False: 11.2k]
  ------------------
  599|    236|                return (0);
  600|  11.2k|            } else if (c == '/') {
  ------------------
  |  Branch (600:24): [True: 11.2k, False: 29]
  ------------------
  601|  11.2k|                return (c);
  602|  11.2k|            }
  603|       |
  604|     29|            xml_error(_lxml,
  605|     29|                      "XMLERR: Bad attribute closing for '%s'='%s'.",
  606|     29|                      attr, value);
  607|     29|            return (-1);
  608|   168k|        } else if (location == 0) {
  ------------------
  |  Branch (608:20): [True: 134k, False: 33.9k]
  ------------------
  609|   134k|            attr[count++] = (char) c;
  610|   134k|        } else if (location == 1) {
  ------------------
  |  Branch (610:20): [True: 33.9k, False: 0]
  ------------------
  611|  33.9k|            value[count++] = (char) c;
  612|  33.9k|        }
  613|   284k|    }
  614|       |
  615|    255|    xml_error(_lxml, "XMLERR: End of file while reading an attribute.");
  616|    255|    return (-1);
  617|  92.3k|}
os_xml.c:_writecontent:
  486|   105k|{
  487|   105k|    _lxml->ct[parent] = (char *)calloc(size, sizeof(char));
  488|   105k|    if ( _lxml->ct[parent] == NULL) {
  ------------------
  |  Branch (488:10): [True: 0, False: 105k]
  ------------------
  489|      0|        snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error.");
  ------------------
  |  |   24|      0|#define XML_ERR_LENGTH  128
  ------------------
  490|      0|        return (-1);
  491|      0|    }
  492|   105k|    strncpy(_lxml->ct[parent], str, size - 1);
  493|       |
  494|   105k|    return (0);
  495|   105k|}

OS_ClearNode:
   20|    524|{
   21|    524|    if (node) {
  ------------------
  |  Branch (21:9): [True: 524, False: 0]
  ------------------
   22|    524|        int i = 0;
   23|  67.1k|        while (node[i]) {
  ------------------
  |  Branch (23:16): [True: 66.6k, False: 524]
  ------------------
   24|  66.6k|            if (node[i]->element) {
  ------------------
  |  Branch (24:17): [True: 66.6k, False: 0]
  ------------------
   25|  66.6k|                free(node[i]->element);
   26|  66.6k|            }
   27|  66.6k|            if (node[i]->content) {
  ------------------
  |  Branch (27:17): [True: 66.6k, False: 0]
  ------------------
   28|  66.6k|                free(node[i]->content);
   29|  66.6k|            }
   30|  66.6k|            if (node[i]->attributes) {
  ------------------
  |  Branch (30:17): [True: 11.2k, False: 55.4k]
  ------------------
   31|  11.2k|                int j = 0;
   32|  22.8k|                while (node[i]->attributes[j]) {
  ------------------
  |  Branch (32:24): [True: 11.6k, False: 11.2k]
  ------------------
   33|  11.6k|                    free(node[i]->attributes[j]);
   34|  11.6k|                    j++;
   35|  11.6k|                }
   36|  11.2k|                free(node[i]->attributes);
   37|  11.2k|            }
   38|  66.6k|            if (node[i]->values) {
  ------------------
  |  Branch (38:17): [True: 11.2k, False: 55.4k]
  ------------------
   39|  11.2k|                int j = 0;
   40|  22.8k|                while (node[i]->values[j]) {
  ------------------
  |  Branch (40:24): [True: 11.6k, False: 11.2k]
  ------------------
   41|  11.6k|                    free(node[i]->values[j]);
   42|  11.6k|                    j++;
   43|  11.6k|                }
   44|  11.2k|                free(node[i]->values);
   45|  11.2k|            }
   46|       |
   47|  66.6k|            node[i]->element = NULL;
   48|  66.6k|            node[i]->content = NULL;
   49|  66.6k|            node[i]->attributes = NULL;
   50|  66.6k|            node[i]->values = NULL;
   51|  66.6k|            free(node[i]);
   52|       |            node[i] = NULL;
   53|  66.6k|            i++;
   54|  66.6k|        }
   55|    524|        free(node);
   56|    524|    }
   57|    524|}
OS_GetElementsbyNode:
   62|  66.3k|{
   63|  66.3k|    unsigned int i, k = 0, m;
   64|  66.3k|    xml_node **ret = NULL;
   65|  66.3k|    xml_node **ret_tmp = NULL;
   66|       |
   67|  66.3k|    if (node == NULL) {
  ------------------
  |  Branch (67:9): [True: 255, False: 66.0k]
  ------------------
   68|    255|        m = 0;
   69|    255|        i = 0;
   70|  66.0k|    } else {
   71|  66.0k|        i = node->key;
   72|  66.0k|        m = _lxml->rl[i++] + 1;
   73|  66.0k|    }
   74|       |
   75|   160k|    for (; i < _lxml->cur; i++) {
  ------------------
  |  Branch (75:12): [True: 159k, False: 373]
  ------------------
   76|   159k|        if (_lxml->tp[i] == XML_ELEM) {
  ------------------
  |  Branch (76:13): [True: 136k, False: 23.2k]
  ------------------
   77|   136k|            if ((_lxml->rl[i] == m) && (_lxml->el[i] != NULL)) {
  ------------------
  |  Branch (77:17): [True: 66.6k, False: 69.8k]
  |  Branch (77:40): [True: 66.6k, False: 0]
  ------------------
   78|  66.6k|                unsigned int l = i + 1;
   79|       |                /* Allocate for xml_node ** */
   80|  66.6k|                ret_tmp = (xml_node **)realloc(ret, (k + 2) * sizeof(xml_node *));
   81|  66.6k|                if (ret_tmp == NULL) {
  ------------------
  |  Branch (81:21): [True: 0, False: 66.6k]
  ------------------
   82|      0|                    goto fail;
   83|      0|                }
   84|  66.6k|                ret = ret_tmp;
   85|       |
   86|       |                /* Allocate for the xml_node * */
   87|  66.6k|                ret[k] = (xml_node *)calloc(1, sizeof(xml_node));
   88|  66.6k|                ret[k + 1] = NULL;
   89|  66.6k|                if (ret[k] == NULL) {
  ------------------
  |  Branch (89:21): [True: 0, False: 66.6k]
  ------------------
   90|      0|                    goto fail;
   91|      0|                }
   92|       |
   93|  66.6k|                ret[k]->element = NULL;
   94|  66.6k|                ret[k]->content = NULL;
   95|  66.6k|                ret[k]->attributes = NULL;
   96|  66.6k|                ret[k]->values = NULL;
   97|       |
   98|       |                /* Get element */
   99|  66.6k|                ret[k]->element = strdup(_lxml->el[i]);
  100|  66.6k|                if (ret[k]->element == NULL) {
  ------------------
  |  Branch (100:21): [True: 0, False: 66.6k]
  ------------------
  101|      0|                    goto fail;
  102|      0|                }
  103|       |
  104|       |                /* Get content */
  105|  66.6k|                if (_lxml->ct[i]) {
  ------------------
  |  Branch (105:21): [True: 66.6k, False: 0]
  ------------------
  106|  66.6k|                    ret[k]->content = strdup(_lxml->ct[i]);
  107|  66.6k|                    if (ret[k]->content == NULL) {
  ------------------
  |  Branch (107:25): [True: 0, False: 66.6k]
  ------------------
  108|      0|                        goto fail;
  109|      0|                    }
  110|  66.6k|                }
  111|       |                /* Assign key */
  112|  66.6k|                ret[k]->key = i;
  113|       |
  114|       |                /* Get attributes */
  115|  78.2k|                while (l < _lxml->cur) {
  ------------------
  |  Branch (115:24): [True: 78.1k, False: 105]
  ------------------
  116|  78.1k|                    if ((_lxml->tp[l] == XML_ATTR) && (_lxml->rl[l] == m) &&
  ------------------
  |  Branch (116:25): [True: 11.6k, False: 66.5k]
  |  Branch (116:55): [True: 11.6k, False: 0]
  ------------------
  117|  11.6k|                            (_lxml->el[l]) && (_lxml->ct[l])) {
  ------------------
  |  Branch (117:29): [True: 11.6k, False: 0]
  |  Branch (117:47): [True: 11.6k, False: 0]
  ------------------
  118|  11.6k|                        char **tmp;
  119|  11.6k|                        tmp = (char **)realloc(ret[k]->attributes, (l - i + 1) * sizeof(char *));
  120|  11.6k|                        if (tmp == NULL) {
  ------------------
  |  Branch (120:29): [True: 0, False: 11.6k]
  ------------------
  121|      0|                            goto fail;
  122|      0|                        }
  123|  11.6k|                        ret[k]->attributes = tmp;
  124|  11.6k|                        ret[k]->attributes[l - i] = NULL;
  125|  11.6k|                        tmp = (char **)realloc(ret[k]->values, (l - i + 1) * sizeof(char *));
  126|  11.6k|                        if (tmp == NULL) {
  ------------------
  |  Branch (126:29): [True: 0, False: 11.6k]
  ------------------
  127|      0|                            goto fail;
  128|      0|                        }
  129|  11.6k|                        ret[k]->values = tmp;
  130|  11.6k|                        ret[k]->values[l - i] = NULL;
  131|       |
  132|  11.6k|                        ret[k]->attributes[l - i - 1] = strdup(_lxml->el[l]);
  133|  11.6k|                        ret[k]->values[l - i - 1] = strdup(_lxml->ct[l]);
  134|  11.6k|                        if (!(ret[k]->attributes[l - i - 1]) ||
  ------------------
  |  Branch (134:29): [True: 0, False: 11.6k]
  ------------------
  135|  11.6k|                                !(ret[k]->values[l - i - 1])) {
  ------------------
  |  Branch (135:33): [True: 0, False: 11.6k]
  ------------------
  136|      0|                            goto fail;
  137|      0|                        }
  138|  11.6k|                        l++;
  139|  66.5k|                    } else {
  140|  66.5k|                        break;
  141|  66.5k|                    }
  142|  78.1k|                }
  143|  66.6k|                k++;
  144|  66.6k|                continue;
  145|  66.6k|            }
  146|   136k|        }
  147|  93.0k|        if ((_lxml->tp[i] == XML_ELEM) && (m > _lxml->rl[i])) {
  ------------------
  |  Branch (147:13): [True: 69.8k, False: 23.2k]
  |  Branch (147:43): [True: 65.9k, False: 3.84k]
  ------------------
  148|  65.9k|            if (node == NULL) {
  ------------------
  |  Branch (148:17): [True: 0, False: 65.9k]
  ------------------
  149|      0|                continue;
  150|  65.9k|            } else {
  151|  65.9k|                break;
  152|  65.9k|            }
  153|  65.9k|        }
  154|  93.0k|    }
  155|       |
  156|  66.3k|    return (ret);
  157|       |
  158|      0|fail:
  159|      0|    OS_ClearNode(ret);
  160|       |    return (NULL);
  161|  66.3k|}

LLVMFuzzerTestOneInput:
   21|  1.36k|{
   22|  1.36k|    char path[] = "/tmp/ossec-fuzz-os-xml-XXXXXX";
   23|  1.36k|    int fd;
   24|  1.36k|    FILE *fp;
   25|  1.36k|    OS_XML xml;
   26|  1.36k|    XML_NODE node;
   27|  1.36k|    int i;
   28|       |
   29|  1.36k|    if (data == NULL || size == 0) {
  ------------------
  |  Branch (29:9): [True: 0, False: 1.36k]
  |  Branch (29:25): [True: 0, False: 1.36k]
  ------------------
   30|      0|        return 0;
   31|      0|    }
   32|       |
   33|  1.36k|    fd = mkstemp(path);
   34|  1.36k|    if (fd < 0) {
  ------------------
  |  Branch (34:9): [True: 0, False: 1.36k]
  ------------------
   35|      0|        return 0;
   36|      0|    }
   37|       |
   38|  1.36k|    fp = fdopen(fd, "wb");
   39|  1.36k|    if (!fp) {
  ------------------
  |  Branch (39:9): [True: 0, False: 1.36k]
  ------------------
   40|      0|        close(fd);
   41|      0|        unlink(path);
   42|      0|        return 0;
   43|      0|    }
   44|       |
   45|  1.36k|    if (fwrite(data, 1, size, fp) != size) {
  ------------------
  |  Branch (45:9): [True: 0, False: 1.36k]
  ------------------
   46|      0|        fclose(fp);
   47|      0|        unlink(path);
   48|      0|        return 0;
   49|      0|    }
   50|  1.36k|    fclose(fp);
   51|       |
   52|  1.36k|    memset(&xml, 0, sizeof(xml));
   53|  1.36k|    if (OS_ReadXML(path, &xml) < 0) {
  ------------------
  |  Branch (53:9): [True: 1.10k, False: 255]
  ------------------
   54|  1.10k|        OS_ClearXML(&xml);
   55|  1.10k|        unlink(path);
   56|  1.10k|        return 0;
   57|  1.10k|    }
   58|       |
   59|    255|    node = OS_GetElementsbyNode(&xml, NULL);
   60|    255|    if (node == NULL) {
  ------------------
  |  Branch (60:9): [True: 137, False: 118]
  ------------------
   61|    137|        OS_ClearXML(&xml);
   62|    137|        unlink(path);
   63|    137|        return 0;
   64|    137|    }
   65|       |
   66|    118|    i = 0;
   67|  66.2k|    while (node[i]) {
  ------------------
  |  Branch (67:12): [True: 66.0k, False: 118]
  ------------------
   68|  66.0k|        XML_NODE cnode;
   69|  66.0k|        int j = 0;
   70|       |
   71|  66.0k|        cnode = OS_GetElementsbyNode(&xml, node[i]);
   72|  66.0k|        if (cnode == NULL) {
  ------------------
  |  Branch (72:13): [True: 65.6k, False: 406]
  ------------------
   73|  65.6k|            i++;
   74|  65.6k|            continue;
   75|  65.6k|        }
   76|       |
   77|    964|        while (cnode[j]) {
  ------------------
  |  Branch (77:16): [True: 558, False: 406]
  ------------------
   78|    558|            if (cnode[j]->attributes && cnode[j]->values) {
  ------------------
  |  Branch (78:17): [True: 8, False: 550]
  |  Branch (78:41): [True: 8, False: 0]
  ------------------
   79|      8|                int k = 0;
   80|       |
   81|     16|                while (cnode[j]->attributes[k]) {
  ------------------
  |  Branch (81:24): [True: 8, False: 8]
  ------------------
   82|      8|                    k++;
   83|      8|                }
   84|      8|            }
   85|    558|            j++;
   86|    558|        }
   87|       |
   88|    406|        OS_ClearNode(cnode);
   89|    406|        i++;
   90|    406|    }
   91|       |
   92|    118|    OS_ClearNode(node);
   93|    118|    OS_ClearXML(&xml);
   94|    118|    unlink(path);
   95|    118|    return 0;
   96|    255|}

