Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
mxml.6523
0002-mxmlWrite-used-a-recursive-algorithm-which...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0002-mxmlWrite-used-a-recursive-algorithm-which-could-req.patch of Package mxml.6523
From 32ab134df5a647650bb01941dd04f3f965d550ff Mon Sep 17 00:00:00 2001 From: Michael R Sweet <michaelrsweet@users.noreply.github.com> Date: Sun, 12 Jun 2016 21:12:11 +0000 Subject: [PATCH 2/2] mxmlWrite* used a recursive algorithm which could require large amounts of stack space depending on the file (Bug #549, CVE-2016-4571) --- CHANGES | 6 +- doc/reference.html | 2 +- mxml-file.c | 372 +++++++++++++++++++++++++++-------------------------- 3 files changed, 198 insertions(+), 182 deletions(-) diff --git a/mxml-file.c b/mxml-file.c index dcc045b..4a8e6cb 100644 --- a/mxml-file.c +++ b/mxml-file.c @@ -3,7 +3,7 @@ * * File loading code for Mini-XML, a small XML-like file parsing library. * - * Copyright 2003-2014 by Michael R Sweet. + * Copyright 2003-2016 by Michael R Sweet. * * These coded instructions, statements, and computer programs are the * property of Michael R Sweet and are protected by Federal copyright @@ -2710,6 +2710,8 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ _mxml_putc_cb_t putc_cb,/* I - Output callback */ _mxml_global_t *global)/* I - Global data */ { + mxml_node_t *current, /* Current node */ + *next; /* Next node */ int i, /* Looping var */ width; /* Width of attr + value */ mxml_attr_t *attr; /* Current attribute */ @@ -2717,252 +2719,264 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ /* - * Print the node value... + * Loop through this node and all of its children... */ - switch (node->type) + for (current = node; current; current = next) { - case MXML_ELEMENT : - col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); + /* + * Print the node value... + */ - if ((*putc_cb)('<', p) < 0) - return (-1); - if (node->value.element.name[0] == '?' || - !strncmp(node->value.element.name, "!--", 3) || - !strncmp(node->value.element.name, "![CDATA[", 8)) - { - /* - * Comments, CDATA, and processing instructions do not - * use character entities. - */ + switch (current->type) + { + case MXML_ELEMENT : + col = mxml_write_ws(current, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); - const char *ptr; /* Pointer into name */ + if ((*putc_cb)('<', p) < 0) + return (-1); + if (current->value.element.name[0] == '?' || + !strncmp(current->value.element.name, "!--", 3) || + !strncmp(current->value.element.name, "![CDATA[", 8)) + { + /* + * Comments, CDATA, and processing instructions do not + * use character entities. + */ + const char *ptr; /* Pointer into name */ - for (ptr = node->value.element.name; *ptr; ptr ++) - if ((*putc_cb)(*ptr, p) < 0) - return (-1); - } - else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0) - return (-1); + for (ptr = current->value.element.name; *ptr; ptr ++) + if ((*putc_cb)(*ptr, p) < 0) + return (-1); + } + else if (mxml_write_name(current->value.element.name, p, putc_cb) < 0) + return (-1); - col += strlen(node->value.element.name) + 1; + col += strlen(current->value.element.name) + 1; - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) - { - width = strlen(attr->name); + for (i = current->value.element.num_attrs, attr = current->value.element.attrs; + i > 0; + i --, attr ++) + { + width = strlen(attr->name); - if (attr->value) - width += strlen(attr->value) + 3; + if (attr->value) + width += strlen(attr->value) + 3; - if (global->wrap > 0 && (col + width) > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) + if (global->wrap > 0 && (col + width) > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else + { + if ((*putc_cb)(' ', p) < 0) + return (-1); + + col ++; + } + + if (mxml_write_name(attr->name, p, putc_cb) < 0) return (-1); - col = 0; + if (attr->value) + { + if ((*putc_cb)('=', p) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + if (mxml_write_string(attr->value, p, putc_cb) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + } + + col += width; } - else + + if (current->child) { - if ((*putc_cb)(' ', p) < 0) + /* + * Write children... + */ + + if ((*putc_cb)('>', p) < 0) return (-1); + else + col ++; - col ++; + col = mxml_write_ws(current, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); } + else if (current->value.element.name[0] == '!' || + current->value.element.name[0] == '?') + { + /* + * The ? and ! elements are special-cases... + */ - if (mxml_write_name(attr->name, p, putc_cb) < 0) - return (-1); + if ((*putc_cb)('>', p) < 0) + return (-1); + else + col ++; - if (attr->value) + col = mxml_write_ws(current, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + } + else { - if ((*putc_cb)('=', p) < 0) - return (-1); - if ((*putc_cb)('\"', p) < 0) + if ((*putc_cb)(' ', p) < 0) return (-1); - if (mxml_write_string(attr->value, p, putc_cb) < 0) + if ((*putc_cb)('/', p) < 0) return (-1); - if ((*putc_cb)('\"', p) < 0) + if ((*putc_cb)('>', p) < 0) return (-1); - } - col += width; - } + col += 3; - if (node->child) - { - /* - * Write children... - */ + col = mxml_write_ws(current, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + } + break; - mxml_node_t *child; /* Current child */ + case MXML_INTEGER : + if (current->prev) + { + if (global->wrap > 0 && col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; + } - if ((*putc_cb)('>', p) < 0) + sprintf(s, "%d", current->value.integer); + if (mxml_write_string(s, p, putc_cb) < 0) return (-1); - else - col ++; - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + col += strlen(s); + break; - for (child = node->child; child; child = child->next) - { - if ((col = mxml_write_node(child, p, cb, col, putc_cb, global)) < 0) - return (-1); - } + case MXML_OPAQUE : + if (mxml_write_string(current->value.opaque, p, putc_cb) < 0) + return (-1); - /* - * The ? and ! elements are special-cases and have no end tags... - */ + col += strlen(current->value.opaque); + break; - if (node->value.element.name[0] != '!' && - node->value.element.name[0] != '?') + case MXML_REAL : + if (current->prev) { - col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_CLOSE, col, putc_cb); + if (global->wrap > 0 && col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); - if ((*putc_cb)('<', p) < 0) - return (-1); - if ((*putc_cb)('/', p) < 0) - return (-1); - if (mxml_write_string(node->value.element.name, p, putc_cb) < 0) - return (-1); - if ((*putc_cb)('>', p) < 0) + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) return (-1); - - col += strlen(node->value.element.name) + 3; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb); + else + col ++; } - } - else if (node->value.element.name[0] == '!' || - node->value.element.name[0] == '?') - { - /* - * The ? and ! elements are special-cases... - */ - - if ((*putc_cb)('>', p) < 0) - return (-1); - else - col ++; - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - } - else - { - if ((*putc_cb)(' ', p) < 0) - return (-1); - if ((*putc_cb)('/', p) < 0) - return (-1); - if ((*putc_cb)('>', p) < 0) + sprintf(s, "%f", current->value.real); + if (mxml_write_string(s, p, putc_cb) < 0) return (-1); - col += 3; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - } - break; + col += strlen(s); + break; - case MXML_INTEGER : - if (node->prev) - { - if (global->wrap > 0 && col > global->wrap) + case MXML_TEXT : + if (current->value.text.whitespace && col > 0) { - if ((*putc_cb)('\n', p) < 0) - return (-1); + if (global->wrap > 0 && col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); - col = 0; + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; } - else if ((*putc_cb)(' ', p) < 0) + + if (mxml_write_string(current->value.text.string, p, putc_cb) < 0) return (-1); - else - col ++; - } - sprintf(s, "%d", node->value.integer); - if (mxml_write_string(s, p, putc_cb) < 0) - return (-1); + col += strlen(current->value.text.string); + break; - col += strlen(s); - break; + case MXML_CUSTOM : + if (global->custom_save_cb) + { + char *data; /* Custom data string */ + const char *newline; /* Last newline in string */ - case MXML_OPAQUE : - if (mxml_write_string(node->value.opaque, p, putc_cb) < 0) - return (-1); - col += strlen(node->value.opaque); - break; + if ((data = (*global->custom_save_cb)(node)) == NULL) + return (-1); - case MXML_REAL : - if (node->prev) - { - if (global->wrap > 0 && col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) + if (mxml_write_string(data, p, putc_cb) < 0) return (-1); - col = 0; + if ((newline = strrchr(data, '\n')) == NULL) + col += strlen(data); + else + col = strlen(newline); + + free(data); + break; } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } - sprintf(s, "%f", node->value.real); - if (mxml_write_string(s, p, putc_cb) < 0) + default : /* Should never happen */ return (-1); + } - col += strlen(s); - break; - - case MXML_TEXT : - if (node->value.text.whitespace && col > 0) - { - if (global->wrap > 0 && col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); + /* + * Figure out the next node... + */ - col = 0; - } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } + if ((next = current->child) == NULL) + { + while ((next = current->next) == NULL) + { + if (current == node) + break; - if (mxml_write_string(node->value.text.string, p, putc_cb) < 0) - return (-1); + /* + * The ? and ! elements are special-cases and have no end tags... + */ - col += strlen(node->value.text.string); - break; + current = current->parent; - case MXML_CUSTOM : - if (global->custom_save_cb) + if (current->value.element.name[0] != '!' && + current->value.element.name[0] != '?') { - char *data; /* Custom data string */ - const char *newline; /* Last newline in string */ - + col = mxml_write_ws(current, p, cb, MXML_WS_BEFORE_CLOSE, col, putc_cb); - if ((data = (*global->custom_save_cb)(node)) == NULL) + if ((*putc_cb)('<', p) < 0) return (-1); - - if (mxml_write_string(data, p, putc_cb) < 0) + if ((*putc_cb)('/', p) < 0) + return (-1); + if (mxml_write_string(current->value.element.name, p, putc_cb) < 0) + return (-1); + if ((*putc_cb)('>', p) < 0) return (-1); - if ((newline = strrchr(data, '\n')) == NULL) - col += strlen(data); - else - col = strlen(newline); + col += strlen(current->value.element.name) + 3; - free(data); - break; + col = mxml_write_ws(current, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb); } - - default : /* Should never happen */ - return (-1); + } + } } return (col); -- 2.12.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor