Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:yukoff:openSUSE:Leap:42.1:Backports
mxml.6523
0001-mxmlDelete-used-a-recursive-algorithm-whic...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-mxmlDelete-used-a-recursive-algorithm-which-could-re.patch of Package mxml.6523
From e562e556902192fe8d4fd87610101bc996f8928c Mon Sep 17 00:00:00 2001 From: Michael R Sweet <michaelrsweet@users.noreply.github.com> Date: Sat, 11 Jun 2016 20:51:49 +0000 Subject: [PATCH 1/2] mxmlDelete used a recursive algorithm which could require large amounts of stack space depending on the file (Bug #549) Bump version to 2.10. --- CHANGES | 8 ++- configure | 54 +++++++++------- configure.in => configure.ac | 8 +-- mxml-node.c | 148 +++++++++++++++++++++++++++++-------------- 4 files changed, 144 insertions(+), 74 deletions(-) rename configure.in => configure.ac (97%) diff --git a/mxml-node.c b/mxml-node.c index 77b1641..ea7c103 100644 --- a/mxml-node.c +++ b/mxml-node.c @@ -3,7 +3,7 @@ * * Node support 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 @@ -26,6 +26,7 @@ * Local functions... */ +static void mxml_free(mxml_node_t *node); static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type); @@ -177,7 +178,8 @@ mxmlAdd(mxml_node_t *parent, /* I - Parent node */ void mxmlDelete(mxml_node_t *node) /* I - Node to delete */ { - int i; /* Looping var */ + mxml_node_t *current, /* Current node */ + *next; /* Next node */ #ifdef DEBUG @@ -201,60 +203,50 @@ mxmlDelete(mxml_node_t *node) /* I - Node to delete */ * Delete children... */ - while (node->child) - mxmlDelete(node->child); + for (current = node->child; current; current = next) + { + /* + * Get the next node... + */ - /* - * Now delete any node data... - */ + if ((next = current->child) != NULL) + { + /* + * Free parent nodes after child nodes have been freed... + */ - switch (node->type) - { - case MXML_ELEMENT : - if (node->value.element.name) - free(node->value.element.name); + current->child = NULL; + continue; + } - if (node->value.element.num_attrs) - { - for (i = 0; i < node->value.element.num_attrs; i ++) - { - if (node->value.element.attrs[i].name) - free(node->value.element.attrs[i].name); - if (node->value.element.attrs[i].value) - free(node->value.element.attrs[i].value); - } + if ((next = current->next) == NULL) + { + mxml_node_t *temp = current->parent; + /* Pointer to parent node */ + + if (temp == node) + { + /* + * Got back to the top node... + */ + + next = NULL; + } + else if ((next = temp->next) == NULL) + { + if ((next = temp->parent) == node) + next = NULL; + } + } - free(node->value.element.attrs); - } - break; - case MXML_INTEGER : - /* Nothing to do */ - break; - case MXML_OPAQUE : - if (node->value.opaque) - free(node->value.opaque); - break; - case MXML_REAL : - /* Nothing to do */ - break; - case MXML_TEXT : - if (node->value.text.string) - free(node->value.text.string); - break; - case MXML_CUSTOM : - if (node->value.custom.data && - node->value.custom.destroy) - (*(node->value.custom.destroy))(node->value.custom.data); - break; - default : - break; + mxml_free(current); } /* - * Free this node... + * Then free the memory used by this node... */ - free(node); + mxml_free(node); } @@ -730,6 +722,68 @@ mxmlRetain(mxml_node_t *node) /* I - Node */ /* + * 'mxml_free()' - Free the memory used by a node. + * + * Note: Does not free child nodes, does not remove from parent. + */ + +static void +mxml_free(mxml_node_t *node) /* I - Node */ +{ + int i; /* Looping var */ + + + switch (node->type) + { + case MXML_ELEMENT : + if (node->value.element.name) + free(node->value.element.name); + + if (node->value.element.num_attrs) + { + for (i = 0; i < node->value.element.num_attrs; i ++) + { + if (node->value.element.attrs[i].name) + free(node->value.element.attrs[i].name); + if (node->value.element.attrs[i].value) + free(node->value.element.attrs[i].value); + } + + free(node->value.element.attrs); + } + break; + case MXML_INTEGER : + /* Nothing to do */ + break; + case MXML_OPAQUE : + if (node->value.opaque) + free(node->value.opaque); + break; + case MXML_REAL : + /* Nothing to do */ + break; + case MXML_TEXT : + if (node->value.text.string) + free(node->value.text.string); + break; + case MXML_CUSTOM : + if (node->value.custom.data && + node->value.custom.destroy) + (*(node->value.custom.destroy))(node->value.custom.data); + break; + default : + break; + } + + /* + * Free this node... + */ + + free(node); +} + + +/* * 'mxml_new()' - Create a new node. */ -- 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