Use calloc for the array of pointers to ensure pointers are cleared out
so we don't try to free garbage if XdmcpDisposeARRAYofARRAY8 is called
before the caller sets them to valid pointers.

Signed-off-by: Alan Coopersmith <[email protected]>
---
 Array.c      |   19 ++++++++++++++++++-
 test/Array.c |   26 ++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/Array.c b/Array.c
index c1456e1..cb57d89 100644
--- a/Array.c
+++ b/Array.c
@@ -44,6 +44,15 @@ xmalloc(size_t size)
 }
 
 /*
+ * This variant of calloc does not return NULL if zero count is passed into.
+ */
+static void *
+xcalloc(size_t n, size_t size)
+{
+    return calloc(n ? n : 1, size);
+}
+
+/*
  * This variant of realloc does not return NULL if zero size is passed into
  */
 static void *
@@ -110,7 +119,12 @@ XdmcpAllocARRAYofARRAY8 (ARRAYofARRAY8Ptr array, int 
length)
     if (length > UINT8_MAX)
         array->data = NULL;
     else
-        array->data = xmalloc(length * sizeof (ARRAY8));
+        /*
+         * Use calloc to ensure the pointers are cleared out so we
+         * don't try to free garbage if XdmcpDisposeARRAYofARRAY8()
+         * is called before the caller sets them to valid pointers.
+         */
+        array->data = xcalloc(length, sizeof (ARRAY8));
 
     if (array->data == NULL) {
        array->length = 0;
@@ -168,6 +182,9 @@ XdmcpReallocARRAYofARRAY8 (ARRAYofARRAY8Ptr array, int 
length)
     newData = (ARRAY8Ptr) xrealloc(array->data, length * sizeof (ARRAY8));
     if (!newData)
        return FALSE;
+    if (length > array->length)
+        memset(newData + array->length, 0,
+               (length - array->length) * sizeof (ARRAY8));
     array->length = (CARD8) length;
     array->data = newData;
     return TRUE;
diff --git a/test/Array.c b/test/Array.c
index 0f3430e..b246ba8 100644
--- a/test/Array.c
+++ b/test/Array.c
@@ -23,6 +23,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <assert.h>
 #include <X11/Xdmcp.h>
 #include <inttypes.h>
@@ -53,10 +54,35 @@ TestAllocOversizeArrays(void)
     TestAllocOversize(ARRAYofARRAY8, UINT8_MAX + 1);
 }
 
+static void
+TestZeroFillARRAYofARRAY8(void)
+{
+    ARRAYofARRAY8 aa;
+    int result;
+    char *noise;
+
+    printf("Checking XdmcpAllocARRAYofARRAY8 zero fills array...\n");
+    /* prefill memory with junk - hopefully next malloc will pick up some */
+    noise = malloc(32 * sizeof(ARRAY8));
+    memset(noise, 0xdeadbeef, 32 * sizeof(ARRAY8));
+    free(noise);
+    result = XdmcpAllocARRAYofARRAY8(&aa, 32);
+    assert(result == TRUE);
+    assert(aa.length == 32);
+    assert(aa.data[4].data == NULL);
+    printf("Checking XdmcpReallocARRAYofARRAY8 zero fills array...\n");
+    result = XdmcpAllocARRAYofARRAY8(&aa, 48);
+    assert(result == TRUE);
+    assert(aa.length == 48);
+    assert(aa.data[40].data == NULL);
+    XdmcpDisposeARRAYofARRAY8(&aa);
+}
+
 int
 main(int argc, char **argv)
 {
     TestAllocOversizeArrays();
+    TestZeroFillARRAYofARRAY8();
 
     exit(0);
 }
-- 
1.7.9.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to