Sun, 29 Dec 2019 11:30:39 +0100
fix: index buffer in string replace was not freed
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <inttypes.h> #include "mpool_tests.h" UCX_TEST(test_ucx_mempool_new) { UcxMempool *pool = ucx_mempool_new(16); UCX_TEST_BEGIN UCX_TEST_ASSERT(pool->size == 16, "wrong size"); UCX_TEST_ASSERT(pool->ndata == 0, "uninitialized counter"); UCX_TEST_ASSERT(pool->data != NULL, "no memory addressed"); UCX_TEST_END ucx_mempool_destroy(pool); } UCX_TEST(test_ucx_mempool_malloc) { UcxMempool *pool = ucx_mempool_new(1); UCX_TEST_BEGIN intptr_t *test = (intptr_t*) ucx_mempool_malloc(pool, sizeof(intptr_t)); UCX_TEST_ASSERT(pool->ndata == 1, "counter not incremented"); UCX_TEST_ASSERT(pool->size == 1, "chcap called"); intptr_t *pooladdr = (intptr_t*)((char*)pool->data[0] + sizeof(ucx_destructor)); *pooladdr = 5; UCX_TEST_ASSERT(*test == 5, "wrong pointer"); UCX_TEST_END ucx_mempool_destroy(pool); } UCX_TEST(test_ucx_mempool_malloc_with_chcap) { UcxMempool *pool = ucx_mempool_new(1); UCX_TEST_BEGIN ucx_mempool_malloc(pool, sizeof(int)); intptr_t *test = (intptr_t*) ucx_mempool_malloc(pool, sizeof(intptr_t)); UCX_TEST_ASSERT(pool->ndata == 2, "counter not incremented"); UCX_TEST_ASSERT(pool->size == 2, "chcap not called"); intptr_t *pooladdr = (intptr_t*)((char*)pool->data[1] + sizeof(ucx_destructor)); *pooladdr = 5; UCX_TEST_ASSERT(*test == 5, "wrong pointer"); // overflow test void *n0 = ucx_mempool_malloc(pool, (size_t)-1); void *n1 = ucx_mempool_malloc(pool, ((size_t)-1) - sizeof(void*)/2); UCX_TEST_ASSERT(n0 == NULL, "should not allocate SIZE_MAX bytes"); UCX_TEST_ASSERT(n1 == NULL, "should detect integer overflow"); UCX_TEST_END ucx_mempool_destroy(pool); } UCX_TEST(test_ucx_mempool_calloc) { UcxMempool *pool = ucx_mempool_new(1); UCX_TEST_BEGIN intptr_t *test = (intptr_t*) ucx_mempool_calloc(pool, 2, sizeof(intptr_t)); UCX_TEST_ASSERT(test != NULL, "no memory for test data"); UCX_TEST_ASSERT(test[0] == 0 && test[1] == 0, "failed"); // overflow test void *n0 = ucx_mempool_calloc(pool, (size_t)-1, 1); void *n1 = ucx_mempool_calloc(pool, ((size_t)-1)/2, 3); UCX_TEST_ASSERT(n0 == NULL, "should not allocate SIZE_MAX bytes"); UCX_TEST_ASSERT(n1 == NULL, "should detect integer overflow"); UCX_TEST_END ucx_mempool_destroy(pool); } UCX_TEST(test_ucx_mempool_free) { UcxMempool *pool = ucx_mempool_new(16); void *mem1; void *mem2; UCX_TEST_BEGIN mem1 = ucx_mempool_malloc(pool, 16); ucx_mempool_free(pool, mem1); UCX_TEST_ASSERT(pool->ndata == 0, "mempool not empty"); ucx_mempool_malloc(pool, 16); ucx_mempool_malloc(pool, 16); mem1 = ucx_mempool_malloc(pool, 16); ucx_mempool_malloc(pool, 16); mem2 = ucx_mempool_malloc(pool, 16); ucx_mempool_free(pool, mem1); UCX_TEST_ASSERT(pool->ndata == 4, "wrong mempool size"); ucx_mempool_free(pool, mem2); UCX_TEST_ASSERT(pool->ndata == 3, "wrong mempool size"); UCX_TEST_END ucx_mempool_destroy(pool); } #ifdef __cplusplus extern "C" #endif void test_setdestr(void* elem) { intptr_t *cb = (intptr_t*) ((intptr_t*) elem)[1]; *cb = 42; } UCX_TEST(test_ucx_mempool_set_destr) { intptr_t *cb = (intptr_t*) malloc(sizeof(intptr_t)); UCX_TEST_BEGIN UcxMempool *pool = ucx_mempool_new(2); ucx_mempool_malloc(pool, sizeof(intptr_t)); intptr_t *test = (intptr_t*) ucx_mempool_calloc(pool, 2, sizeof(intptr_t)); UCX_TEST_ASSERT(cb != NULL && test != NULL, "no memory for test data"); test[0] = 5; test[1] = (intptr_t) cb; *cb = 13; ucx_mempool_set_destr(test, test_setdestr); UCX_TEST_ASSERT( *(ucx_destructor*)(pool->data[1]) == test_setdestr, "failed") UCX_TEST_ASSERT( test[0] == 5 && test[1] == (intptr_t) cb, "setdestr destroyed data") ucx_mempool_destroy(pool); UCX_TEST_ASSERT(*cb == 42, "destructor not called"); UCX_TEST_END if (cb != NULL) free(cb); } UCX_TEST(test_ucx_mempool_reg_destr) { intptr_t *test = (intptr_t*) calloc(2, sizeof(intptr_t)); intptr_t *cb = (intptr_t*) malloc(sizeof(intptr_t)); UCX_TEST_BEGIN UcxMempool *pool = ucx_mempool_new(1); UCX_TEST_ASSERT(cb != NULL && test != NULL, "no memory for test data"); test[0] = 5; test[1] = (intptr_t) cb; *cb = 13; ucx_mempool_reg_destr(pool, test, test_setdestr); ucx_destructor *pooladdr = (ucx_destructor*) ((char*)pool->data[0] + sizeof(ucx_destructor)); UCX_TEST_ASSERT(*pooladdr == test_setdestr, "failed"); ucx_mempool_destroy(pool); UCX_TEST_ASSERT(*cb == 42, "destructor not called"); UCX_TEST_END if (test != NULL) free(test); if (cb != NULL) free(cb); } UCX_TEST(test_ucx_mempool_realloc) { intptr_t *cb = (intptr_t*) malloc(sizeof(intptr_t)); UCX_TEST_BEGIN UcxMempool *pool = ucx_mempool_new(2); ucx_mempool_malloc(pool, sizeof(intptr_t)); intptr_t *test = (intptr_t*) ucx_mempool_calloc(pool, 2, sizeof(intptr_t)); UCX_TEST_ASSERT(cb != NULL && test != NULL, "no memory for test data"); test[0] = 5; test[1] = (intptr_t) cb; *cb = 13; ucx_mempool_set_destr(test, test_setdestr); intptr_t *rtest, n = 2; do { n *= 2; UCX_TEST_ASSERT(n < 65536, "test corrupt - no movement for realloc"); rtest = (intptr_t*) ucx_mempool_realloc(pool, test, n*sizeof(intptr_t)); } while (rtest == test); test = rtest; UCX_TEST_ASSERT(*(ucx_destructor*)(pool->data[1]) == test_setdestr, "realloc killed destructor") UCX_TEST_ASSERT( test[0] == 5 && test[1] == (intptr_t) cb, "realloc destroyed data") ucx_mempool_destroy(pool); UCX_TEST_ASSERT(*cb == 42, "destructor not called"); UCX_TEST_END if (cb != NULL) free(cb); }