ttxml: made alloc failure consistent - return NULL
authorDaniel Burke <dan.p.burke@gmail.com>
Sun, 26 Feb 2012 17:03:59 +0000 (03:33 +1030)
committerDaniel Burke <dan.p.burke@gmail.com>
Sun, 26 Feb 2012 17:03:59 +0000 (03:33 +1030)
ccan/ttxml/ttxml.c

index e953ba2390262cf221817671b261fc06cd7e77f0..ffda34b832621d480203ee64fa60c0291700b117 100644 (file)
@@ -31,6 +31,7 @@ typedef struct XMLBUF
        int len;
        int read_index;
        int eof;
+       int error;
 } XMLBUF;
 
 
@@ -104,6 +105,14 @@ static void xml_read_file(XMLBUF *xml)
 }
 
 
+static void xml_end_file(XMLBUF *xml)
+{
+       xml->len = 0;
+       xml->eof = 1;
+       xml->read_index = 0 ;
+       xml->error = 1;
+}
+
 /* All reading of the XML buffer done through these two functions */
 /*** read a byte without advancing the offset */
 static char xml_peek(XMLBUF *xml)
@@ -173,6 +182,7 @@ static char* xml_feed( XMLBUF *xml, int (*test)(char) )
        int offset = xml->read_index;
        int delta;
        char *ret = NULL;
+       char *tmp = NULL;
        int size = 0;
 
        /* perform first and N middle realloc()'s */
@@ -183,7 +193,9 @@ static char* xml_feed( XMLBUF *xml, int (*test)(char) )
                if(offset >= xml->len)
                {
                        delta = offset - xml->read_index;
-                       ret = realloc(ret, size + delta + 1);
+                       tmp = realloc(ret, size + delta + 1);
+                       if(!tmp)goto xml_feed_malloc;
+                       ret = tmp;
                        memcpy(ret+size, xml->buf + xml->read_index, delta);
                        size += delta;
                        ret[size]=0;
@@ -197,13 +209,19 @@ static char* xml_feed( XMLBUF *xml, int (*test)(char) )
        if(offset > xml->read_index)
        {
                delta = offset - xml->read_index;
-               ret = realloc(ret, size + delta + 1);
+               tmp = realloc(ret, size + delta + 1);
+               if(!tmp)goto xml_feed_malloc;
+               ret = tmp;
                memcpy(ret+size, xml->buf + xml->read_index, delta);
                xml->read_index = offset;
                size += delta;
                ret[size]=0;
        }
        return ret;
+xml_feed_malloc:
+       free(ret);
+       xml_end_file(xml);
+       return 0;
 }
 
 /* this reads attributes from tags, of the form...
@@ -215,6 +233,7 @@ static char* xml_feed( XMLBUF *xml, int (*test)(char) )
 static void xml_read_attr(struct XMLBUF *xml, XmlNode *node)
 {
        int n=0;
+       char **tmp;
 
        // how does this tag finish?
        while(xml->len)
@@ -223,7 +242,9 @@ static void xml_read_attr(struct XMLBUF *xml, XmlNode *node)
                        return;
 
                n = ++node->nattrib;
-               node->attrib = realloc(node->attrib, n * 2 * sizeof(char*) );
+               tmp = realloc(node->attrib, n * 2 * sizeof(char*) );
+               if(!tmp)goto xml_read_attr_malloc;
+               node->attrib = tmp;
                node->attrib[--n*2+1] = 0;
                
                feed_mask = XML_EQUALS | XML_SPACE | XML_CLOSE | XML_SLASH;
@@ -245,6 +266,9 @@ static void xml_read_attr(struct XMLBUF *xml, XmlNode *node)
                }
                xml_skip(xml, XML_SPACE);
        }
+       return;
+xml_read_attr_malloc:
+       xml_end_file(xml);
 }
 
 /* The big decision maker, is it a regular node, or a text node.
@@ -256,7 +280,8 @@ static XmlNode* xml_parse(struct XMLBUF *xml)
 {
        int offset;
        int toff;
-       char *tmp;
+       char **tmp;
+       char *stmp;
        XmlNode **this, *ret = NULL;
        
        this = &ret;
@@ -274,6 +299,7 @@ static XmlNode* xml_parse(struct XMLBUF *xml)
                                // read the tag name
                                feed_mask = XML_SPACE | XML_SLASH | XML_CLOSE;
                                *this = xml_new( xml_feed(xml, test_mask));
+                               if(xml->error)goto xml_parse_malloc;
                                xml_skip(xml, XML_SPACE);       // skip any whitespace
 
                                xml_read_attr(xml, *this);      // read attributes
@@ -299,26 +325,32 @@ static XmlNode* xml_parse(struct XMLBUF *xml)
                                xml_skip(xml, XML_SPACE);       // skip any whitespace
                                feed_mask = XML_OPEN;
                                (*this)->nattrib=1;
-                               (*this)->attrib = malloc(sizeof(char*)*2);
+                               tmp = malloc(sizeof(char*)*2);
+                               if(!tmp)goto xml_parse_malloc;
+                               (*this)->attrib = tmp;
                                (*this)->attrib[1] = NULL;
-                               tmp = (*this)->attrib[0] = xml_feed(xml, test_mask);
+                               stmp = (*this)->attrib[0] = xml_feed(xml, test_mask);
 
                                /* trim the whitespace off the end of text nodes,
                                 * by overwriting the spaces will null termination. */
-                               toff = strlen(tmp)-1;
-                               while( ( is_special(tmp[toff]) & XML_SPACE ) )
+                               toff = strlen(stmp)-1;
+                               while( ( is_special(stmp[toff]) & XML_SPACE ) )
                                {
-                                       tmp[toff] = 0;
+                                       stmp[toff] = 0;
                                        toff --;
                                }
 
                                break;
                }
-               this = &(*this)->next; 
+               this = &(*this)->next;
                xml_skip(xml, XML_SPACE);       // skip whitespace
-       }       
+       }
 
        return ret;
+xml_parse_malloc:
+       xml_end_file(xml);
+       if(ret)xml_free(ret);
+       return 0;
 }
 
 
@@ -330,6 +362,7 @@ XmlNode* xml_load(const char * filename)
 
 //     printf("xml_load(\"%s\");\n", filename);
 
+       xml.error = 0;
        xml.eof = 0;
        xml.read_index = 0;
        xml.fptr = fopen(filename, "rb");
@@ -346,6 +379,12 @@ XmlNode* xml_load(const char * filename)
 
        ret = xml_parse(&xml);
 
+       if(xml.error)
+       {
+               xml_free(ret);
+               ret = NULL;
+       }
+
        free(xml.buf);
 xml_load_fail_malloc_buf:
        fclose(xml.fptr);