Add first pass at a memory validator
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 09dece8..87f9154 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,7 +8,7 @@
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dist_dir}/test )
-add_executable ( cose_test test.c json.c encrypt.c )
+add_executable ( cose_test test.c json.c encrypt.c context.c )
target_link_libraries (cose_test PRIVATE cose-c )
diff --git a/test/context.c b/test/context.c
new file mode 100644
index 0000000..04a7a8e
--- /dev/null
+++ b/test/context.c
@@ -0,0 +1,115 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <assert.h>
+
+#include <cn-cbor\cn-cbor.h>
+
+#include "context.h"
+
+typedef unsigned char byte;
+
+typedef struct {
+ cn_cbor_context context;
+ byte * pFirst;
+} MyContext;
+
+typedef struct _MyItem {
+ struct _MyItem * pNext;
+ size_t size;
+ byte pad[4];
+ byte data[4];
+} MyItem;
+
+
+bool CheckMemory(MyContext * pContext)
+{
+ MyItem * p;
+ int i;
+
+ // Walk memory and check every block
+
+ for (p = (MyItem *) pContext->pFirst; p != NULL; p = p->pNext) {
+ if (p->pad[0] == (byte) 0xab) {
+ // Block has been freed
+ for (i = 0; i < p->size + 8; i++) {
+ if (p->pad[i] != (byte) 0xab) {
+ fprintf(stderr, "Freed block is modified");
+ assert(false);
+ }
+ }
+ }
+ else if (p->pad[0] == (byte) 0xef) {
+ for (i = 0; i < 4; i++) {
+ if ((p->pad[i] != (byte) 0xef) || (p->pad[i + 4 + p->size] != (byte) 0xef)) {
+ fprintf(stderr, "Curent block was overrun");
+ assert(false);
+ }
+ }
+ }
+ else {
+ fprintf(stderr, "Incorrect pad value");
+ assert(false);
+ }
+ }
+
+ return true;
+}
+
+void * MyCalloc(size_t count, size_t size, void * context)
+{
+ MyItem * pb = (MyItem *) malloc(sizeof(MyItem) + count*size);
+ MyContext * myContext = (MyContext *)context;
+
+ CheckMemory(myContext);
+
+ memset(pb, 0xef, sizeof(MyItem) + count*size);
+ memset(&pb->data, 0, count*size);
+
+ pb->pNext = (struct _MyItem *) myContext->pFirst;
+ myContext->pFirst = (byte *) pb;
+ pb->size = count*size;
+
+ return &pb->data;
+}
+
+void MyFree(void * ptr, void * context)
+{
+ MyItem * pb = (MyItem *) ((byte *) ptr - sizeof(MyItem) + 4);
+ MyContext * myContext = (MyContext *)context;
+
+ CheckMemory(myContext);
+
+ memset(&pb->pad, 0xab, pb->size + 8);
+}
+
+
+cn_cbor_context * CreateContext()
+{
+ MyContext * p = malloc(sizeof(MyContext));
+
+ p->context.calloc_func = MyCalloc;
+ p->context.free_func = MyFree;
+ p->context.context = p;
+ p->pFirst = NULL;
+
+ return &p->context;
+}
+
+void FreeContext(cn_cbor_context* pContext)
+{
+ MyContext * myContext = (MyContext *)pContext;
+ MyItem * pItem;
+ MyItem * pItem2;
+
+ CheckMemory(myContext);
+
+ for (pItem = (MyItem *) myContext->pFirst; pItem != NULL; pItem = pItem2) {
+ pItem2 = pItem->pNext;
+ free(pItem);
+ }
+
+ free(myContext);
+
+ return;
+}
diff --git a/test/context.h b/test/context.h
new file mode 100644
index 0000000..5e9f1d2
--- /dev/null
+++ b/test/context.h
@@ -0,0 +1,4 @@
+
+extern cn_cbor_context * CreateContext();
+extern void FreeContext(cn_cbor_context * pContext);
+
diff --git a/test/encrypt.c b/test/encrypt.c
index cefb104..11e7af0 100644
--- a/test/encrypt.c
+++ b/test/encrypt.c
@@ -11,6 +11,7 @@
#include "json.h"
#include "test.h"
+#include "context.h"
int ValidateEnveloped(const cn_cbor * pControl)
@@ -27,6 +28,8 @@
bool fFail = false;
bool fFailBody = false;
+ allocator = CreateContext();
+
pFail = cn_cbor_mapget_string(pControl, "fail");
if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
fFailBody = true;
@@ -79,6 +82,9 @@
else fFail = false;
}
+ FreeContext(allocator);
+ allocator = NULL;
+
if (fFail) CFails += 1;
return 0;
}