]> git.saurik.com Git - apple/xnu.git/blobdiff - libkern/c++/OSUnserializeXML.y
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / libkern / c++ / OSUnserializeXML.y
index 1769fb6317a949639779f89082bbb11f814164ea..f4138fe38acd85bac71f0779b383708f310032a7 100644 (file)
@@ -124,11 +124,57 @@ static object_t         *buildData(parser_state_t *state, object_t *o);
 static object_t         *buildNumber(parser_state_t *state, object_t *o);
 static object_t         *buildBoolean(parser_state_t *state, object_t *o);
 
-#include <libkern/OSRuntime.h>
+__BEGIN_DECLS
+#include <kern/kalloc.h>
+__END_DECLS
 
-#define malloc(s) kern_os_malloc(s)
-#define realloc(a, s) kern_os_realloc(a, s)
-#define free(a) kern_os_free((void *)a)
+#define malloc(size) malloc_impl(size)
+static inline void *
+malloc_impl(size_t size)
+{
+       if (size == 0) {
+               return NULL;
+       }
+       return kheap_alloc_tag_bt(KHEAP_DEFAULT, size,
+                  (zalloc_flags_t) (Z_WAITOK | Z_ZERO),
+                  VM_KERN_MEMORY_LIBKERN);
+}
+
+#define free(addr) free_impl(addr)
+static inline void
+free_impl(void *addr)
+{
+       kheap_free_addr(KHEAP_DEFAULT, addr);
+}
+static inline void
+safe_free(void *addr, size_t size)
+{
+  if(addr) {
+    assert(size != 0);
+    kheap_free(KHEAP_DEFAULT, addr, size);
+  }
+}
+
+#define realloc(addr, osize, nsize) realloc_impl(addr, osize, nsize)
+static inline void *
+realloc_impl(void *addr, size_t osize, size_t nsize)
+{
+       if (!addr) {
+               return malloc(nsize);
+       }
+       if (nsize == osize) {
+               return addr;
+       }
+       void *nmem = malloc(nsize);
+       if (!nmem) {
+               safe_free(addr, osize);
+               return NULL;
+       }
+       (void)memcpy(nmem, addr, (nsize > osize) ? osize : nsize);
+       safe_free(addr, osize);
+
+       return nmem;
+}
 
 %}
 %token ARRAY
@@ -549,7 +595,7 @@ getTag(parser_state_t *state,
 }
 
 static char *
-getString(parser_state_t *state)
+getString(parser_state_t *state, int *alloc_lengthp)
 {
        int c = currentChar();
        int start, length, i, j;
@@ -580,6 +626,9 @@ getString(parser_state_t *state)
                printf("OSUnserializeXML: can't alloc temp memory\n");
                goto error;
        }
+       if (alloc_lengthp != NULL) {
+               *alloc_lengthp = length + 1;
+       }
 
        // copy out string in tempString
        // "&amp;" -> '&', "&lt;" -> '<', "&gt;" -> '>'
@@ -641,7 +690,10 @@ getString(parser_state_t *state)
 
 error:
        if (tempString) {
-               free(tempString);
+               safe_free(tempString, length + 1);
+               if (alloc_lengthp != NULL) {
+                       *alloc_lengthp = 0;
+               }
        }
        return 0;
 }
@@ -715,8 +767,9 @@ getCFEncodedData(parser_state_t *state, unsigned int *size)
 {
        int numeq = 0, cntr = 0;
        unsigned int acc = 0;
-       int tmpbufpos = 0, tmpbuflen = 0;
-       unsigned char *tmpbuf = (unsigned char *)malloc(DATA_ALLOC_SIZE);
+       int tmpbufpos = 0;
+       size_t tmpbuflen = DATA_ALLOC_SIZE;
+       unsigned char *tmpbuf = (unsigned char *)malloc(tmpbuflen);
 
        int c = currentChar();
        *size = 0;
@@ -724,7 +777,7 @@ getCFEncodedData(parser_state_t *state, unsigned int *size)
        while (c != '<') {
                c &= 0x7f;
                if (c == 0) {
-                       free(tmpbuf);
+                       safe_free(tmpbuf, tmpbuflen);
                        return 0;
                }
                if (c == '=') {
@@ -744,8 +797,9 @@ getCFEncodedData(parser_state_t *state, unsigned int *size)
                acc += __CFPLDataDecodeTable[c];
                if (0 == (cntr & 0x3)) {
                        if (tmpbuflen <= tmpbufpos + 2) {
+                               size_t oldsize = tmpbuflen;
                                tmpbuflen += DATA_ALLOC_SIZE;
-                               tmpbuf = (unsigned char *)realloc(tmpbuf, tmpbuflen);
+                               tmpbuf = (unsigned char *)realloc(tmpbuf, oldsize, tmpbuflen);
                        }
                        tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
                        if (numeq < 2) {
@@ -759,7 +813,7 @@ getCFEncodedData(parser_state_t *state, unsigned int *size)
        }
        *size = tmpbufpos;
        if (*size == 0) {
-               free(tmpbuf);
+               safe_free(tmpbuf, tmpbuflen);
                return 0;
        }
        return tmpbuf;
@@ -771,7 +825,8 @@ getHexData(parser_state_t *state, unsigned int *size)
        int c;
        unsigned char *d, *start, *lastStart;
 
-       start = lastStart = d = (unsigned char *)malloc(DATA_ALLOC_SIZE);
+       size_t buflen = DATA_ALLOC_SIZE;
+       start = lastStart = d = (unsigned char *)malloc(buflen);
        c = currentChar();
 
        while (c != '<') {
@@ -808,7 +863,9 @@ getHexData(parser_state_t *state, unsigned int *size)
                d++;
                if ((d - lastStart) >= DATA_ALLOC_SIZE) {
                        int oldsize = d - start;
-                       start = (unsigned char *)realloc(start, oldsize + DATA_ALLOC_SIZE);
+                       assert(oldsize == buflen);
+                       buflen += DATA_ALLOC_SIZE;
+                       start = (unsigned char *)realloc(start, oldsize, buflen);
                        d = lastStart = start + oldsize;
                }
                c = nextChar();
@@ -820,7 +877,7 @@ getHexData(parser_state_t *state, unsigned int *size)
 error:
 
        *size = 0;
-       free(start);
+       safe_free(start, buflen);
        return 0;
 }
 
@@ -834,6 +891,7 @@ yylex(YYSTYPE *lvalp, parser_state_t *state)
        char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
        char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
        object_t *object;
+       int alloc_length;
 
 top:
        c = currentChar();
@@ -968,10 +1026,11 @@ top:
                        if (tagType == TAG_EMPTY) {
                                return SYNTAX_ERROR;
                        }
-                       object->string = getString(STATE);
+                       object->string = getString(STATE, &alloc_length);
                        if (!object->string) {
                                return SYNTAX_ERROR;
                        }
+                       object->string_alloc_length = alloc_length;
                        if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
                            || strcmp(tag, "key")) {
                                return SYNTAX_ERROR;
@@ -990,12 +1049,14 @@ top:
                        if (tagType == TAG_EMPTY) {
                                object->string = (char *)malloc(1);
                                object->string[0] = 0;
+                               object->string_alloc_length = 1;
                                return STRING;
                        }
-                       object->string = getString(STATE);
+                       object->string = getString(STATE, &alloc_length);
                        if (!object->string) {
                                return SYNTAX_ERROR;
                        }
+                       object->string_alloc_length = alloc_length;
                        if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
                            || strcmp(tag, "string")) {
                                return SYNTAX_ERROR;
@@ -1048,7 +1109,6 @@ newObject(parser_state_t *state)
        } else {
                o = (object_t *)malloc(sizeof(object_t));
 //             object_count++;
-               bzero(o, sizeof(object_t));
                o->free = state->objects;
                state->objects = o;
        }
@@ -1088,7 +1148,7 @@ cleanupObjects(parser_state_t *state)
 
                t = o;
                o = o->free;
-               free(t);
+               safe_free(t, sizeof(object_t));
 //             object_count--;
        }
 //     printf("object_count = %d\n", object_count);
@@ -1260,7 +1320,7 @@ buildSymbol(parser_state_t *state, object_t *o)
                rememberObject(state, o->idref, symbol);
        }
 
-       free(o->string);
+       safe_free(o->string, strlen(o->string) + 1);
        o->string = 0;
        o->object = symbol;
 
@@ -1345,7 +1405,7 @@ OSUnserializeXML(const char *buffer, OSString **errorString)
 
        cleanupObjects(state);
        state->tags->release();
-       free(state);
+       safe_free(state, sizeof(parser_state_t));
 
        return object;
 }