aboutsummaryrefslogtreecommitdiff
path: root/test/suites/api/test_memory_funcs.c
blob: 7cb4b730ab544db009f5c4d4a6f9262181dae047 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <string.h>
#include <jansson.h>

#include "util.h"

static int malloc_called = 0;
static int free_called = 0;
static size_t malloc_used = 0;

/* helpers */
static void create_and_free_complex_object()
{
    json_t *obj;

    obj = json_pack("{s:i,s:n,s:b,s:b,s:{s:s},s:[i,i,i]}",
                    "foo", 42,
                    "bar",
                    "baz", 1,
                    "qux", 0,
                    "alice", "bar", "baz",
                    "bob", 9, 8, 7);

    json_decref(obj);
}

static void create_and_free_object_with_oom()
{
    int i;
    char key[4];
    json_t *obj = json_object();

    for (i = 0; i < 10; i++)
    {
        snprintf(key, sizeof key, "%d", i);
        json_object_set_new(obj, key, json_integer(i));
    }

    json_decref(obj);
}

static void *my_malloc(size_t size)
{
    malloc_called = 1;
    return malloc(size);
}

static void my_free(void *ptr)
{
    free_called = 1;
    free(ptr);
}

static void test_simple()
{
    json_malloc_t mfunc = NULL;
    json_free_t ffunc = NULL;

    json_set_alloc_funcs(my_malloc, my_free);
    json_get_alloc_funcs(&mfunc, &ffunc);
    create_and_free_complex_object();

    if (malloc_called != 1 || free_called != 1
        || mfunc != my_malloc || ffunc != my_free)
        fail("Custom allocation failed");
}


static void *oom_malloc(size_t size)
{
    if (malloc_used + size > 800)
        return NULL;

    malloc_used += size;
    return malloc(size);
}

static void oom_free(void *ptr)
{
    free_called++;
    free(ptr);
}

static void test_oom()
{
    free_called = 0;
    json_set_alloc_funcs(oom_malloc, oom_free);
    create_and_free_object_with_oom();

    if (free_called == 0)
        fail("Allocation with OOM failed");
}


/*
  Test the secure memory functions code given in the API reference
  documentation, but by using plain memset instead of
  guaranteed_memset().
*/

static void *secure_malloc(size_t size)
{
    /* Store the memory area size in the beginning of the block */
    void *ptr = malloc(size + 8);
    *((size_t *)ptr) = size;
    return (char *)ptr + 8;
}

static void secure_free(void *ptr)
{
    size_t size;

    ptr = (char *)ptr - 8;
    size = *((size_t *)ptr);

    /*guaranteed_*/memset(ptr, 0, size + 8);
    free(ptr);
}

static void test_secure_funcs(void)
{
    json_set_alloc_funcs(secure_malloc, secure_free);
    create_and_free_complex_object();
}

static void run_tests()
{
    test_simple();
    test_secure_funcs();
    test_oom();
}