aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetri Lehtinen <petri@digip.org>2016-08-11 22:15:01 +0300
committerGitHub <noreply@github.com>2016-08-11 22:15:01 +0300
commit71594af7d522e2bcae1cabdc975608d48de66d5e (patch)
tree82cd3c0d86515ca0a805198d2a7236295417ccb4
parent8f067962f6442bda65f0a8909f589f2616a42c5a (diff)
parent6a4b3f878dddb1525b59b86da7fb392ab8fdc7b2 (diff)
downloadjansson-71594af7d522e2bcae1cabdc975608d48de66d5e.zip
jansson-71594af7d522e2bcae1cabdc975608d48de66d5e.tar.gz
jansson-71594af7d522e2bcae1cabdc975608d48de66d5e.tar.bz2
Merge pull request #298 from pasiopou/oom-crash
OOM crash
-rw-r--r--src/hashtable.c17
-rw-r--r--test/suites/api/test_memory_funcs.c45
2 files changed, 54 insertions, 8 deletions
diff --git a/src/hashtable.c b/src/hashtable.c
index a453b00..0ec1ef8 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -152,17 +152,20 @@ static int hashtable_do_rehash(hashtable_t *hashtable)
{
list_t *list, *next;
pair_t *pair;
- size_t i, index, new_size;
+ size_t i, index, new_size, new_order;
+ struct hashtable_bucket *new_buckets;
- jsonp_free(hashtable->buckets);
-
- hashtable->order++;
- new_size = hashsize(hashtable->order);
+ new_order = hashtable->order + 1;
+ new_size = hashsize(new_order);
- hashtable->buckets = jsonp_malloc(new_size * sizeof(bucket_t));
- if(!hashtable->buckets)
+ new_buckets = jsonp_malloc(new_size * sizeof(bucket_t));
+ if(!new_buckets)
return -1;
+ jsonp_free(hashtable->buckets);
+ hashtable->buckets = new_buckets;
+ hashtable->order = new_order;
+
for(i = 0; i < hashsize(hashtable->order); i++)
{
hashtable->buckets[i].first = hashtable->buckets[i].last =
diff --git a/test/suites/api/test_memory_funcs.c b/test/suites/api/test_memory_funcs.c
index 047ca67..7cb4b73 100644
--- a/test/suites/api/test_memory_funcs.c
+++ b/test/suites/api/test_memory_funcs.c
@@ -5,8 +5,9 @@
static int malloc_called = 0;
static int free_called = 0;
+static size_t malloc_used = 0;
-/* helper */
+/* helpers */
static void create_and_free_complex_object()
{
json_t *obj;
@@ -22,6 +23,21 @@ static void create_and_free_complex_object()
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;
@@ -49,6 +65,32 @@ static void test_simple()
}
+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
@@ -84,4 +126,5 @@ static void run_tests()
{
test_simple();
test_secure_funcs();
+ test_oom();
}