diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/failing_allocator.c | 104 | ||||
-rw-r--r-- | test/failing_allocator.h | 21 | ||||
-rw-r--r-- | test/meson.build | 2 | ||||
-rw-r--r-- | test/test_caret.c | 83 | ||||
-rw-r--r-- | test/test_env.c | 202 | ||||
-rw-r--r-- | test/test_free_null.c | 6 | ||||
-rw-r--r-- | test/test_log.c | 18 | ||||
-rw-r--r-- | test/test_node.c | 218 | ||||
-rw-r--r-- | test/test_overflow.c | 12 | ||||
-rw-r--r-- | test/test_reader.c | 144 | ||||
-rw-r--r-- | test/test_reader_writer.c | 66 | ||||
-rw-r--r-- | test/test_sink.c | 52 | ||||
-rw-r--r-- | test/test_statement.c | 110 | ||||
-rw-r--r-- | test/test_terse_write.c | 46 | ||||
-rw-r--r-- | test/test_uri.c | 86 | ||||
-rw-r--r-- | test/test_world.c | 24 | ||||
-rw-r--r-- | test/test_writer.c | 269 |
17 files changed, 1016 insertions, 447 deletions
diff --git a/test/failing_allocator.c b/test/failing_allocator.c new file mode 100644 index 00000000..89c19bad --- /dev/null +++ b/test/failing_allocator.c @@ -0,0 +1,104 @@ +// Copyright 2021 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#include "failing_allocator.h" + +#include "zix/attributes.h" + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +static bool +attempt(SerdFailingAllocator* const allocator) +{ + ++allocator->n_allocations; + + if (!allocator->n_remaining) { + return false; + } + + --allocator->n_remaining; + return true; +} + +ZIX_MALLOC_FUNC static void* +serd_failing_malloc(SerdAllocator* const allocator, const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->malloc(base, size) : NULL; +} + +ZIX_MALLOC_FUNC static void* +serd_failing_calloc(SerdAllocator* const allocator, + const size_t nmemb, + const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->calloc(base, nmemb, size) : NULL; +} + +static void* +serd_failing_realloc(SerdAllocator* const allocator, + void* const ptr, + const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->realloc(base, ptr, size) : NULL; +} + +static void +serd_failing_free(SerdAllocator* const allocator, void* const ptr) +{ + (void)allocator; + + SerdAllocator* const base = serd_default_allocator(); + + base->free(base, ptr); +} + +ZIX_MALLOC_FUNC static void* +serd_failing_aligned_alloc(SerdAllocator* const allocator, + const size_t alignment, + const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->aligned_alloc(base, alignment, size) : NULL; +} + +static void +serd_failing_aligned_free(SerdAllocator* const allocator, void* const ptr) +{ + (void)allocator; + + SerdAllocator* const base = serd_default_allocator(); + + base->aligned_free(base, ptr); +} + +ZIX_CONST_FUNC SerdFailingAllocator +serd_failing_allocator(void) +{ + SerdFailingAllocator failing_allocator = { + { + serd_failing_malloc, + serd_failing_calloc, + serd_failing_realloc, + serd_failing_free, + serd_failing_aligned_alloc, + serd_failing_aligned_free, + }, + 0, + SIZE_MAX, + }; + + return failing_allocator; +} diff --git a/test/failing_allocator.h b/test/failing_allocator.h new file mode 100644 index 00000000..7bc514bb --- /dev/null +++ b/test/failing_allocator.h @@ -0,0 +1,21 @@ +// Copyright 2021 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef SERD_TEST_FAILING_ALLOCATOR_H +#define SERD_TEST_FAILING_ALLOCATOR_H + +#include "serd/serd.h" + +#include <stddef.h> + +/// An allocator that fails after some number of successes for testing +typedef struct { + SerdAllocator base; ///< Base allocator instance + size_t n_allocations; ///< Number of attempted allocations + size_t n_remaining; ///< Number of remaining successful allocations +} SerdFailingAllocator; + +SerdFailingAllocator +serd_failing_allocator(void); + +#endif // SERD_TEST_FAILING_ALLOCATOR_H diff --git a/test/meson.build b/test/meson.build index dde17566..5c0ac7e8 100644 --- a/test/meson.build +++ b/test/meson.build @@ -155,7 +155,7 @@ foreach unit : unit_tests unit, executable( 'test_@0@'.format(unit), - files('test_@0@.c'.format(unit)), + files('failing_allocator.c', 'test_@0@.c'.format(unit)), c_args: c_suppressions + platform_c_args, dependencies: [serd_dep, zix_dep], ), diff --git a/test/test_caret.c b/test/test_caret.c index a239c242..a97b3d0f 100644 --- a/test/test_caret.c +++ b/test/test_caret.c @@ -1,35 +1,38 @@ -// Copyright 2019-2020 David Robillard <d@drobilla.net> +// Copyright 2019-2021 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #undef NDEBUG +#include "failing_allocator.h" + #include "serd/caret.h" #include "serd/node.h" #include "serd/string_view.h" #include <assert.h> #include <stddef.h> +#include <stdint.h> -int -main(void) +static int +test_caret(void) { - SerdNode* const node = serd_new_string(serd_string("node")); - SerdCaret* const caret = serd_caret_new(node, 46, 2); + SerdNode* const node = serd_new_string(NULL, serd_string("node")); + SerdCaret* const caret = serd_caret_new(NULL, node, 46, 2); assert(serd_caret_equals(caret, caret)); assert(serd_caret_document(caret) == node); assert(serd_caret_line(caret) == 46); assert(serd_caret_column(caret) == 2); - SerdCaret* const copy = serd_caret_copy(caret); + SerdCaret* const copy = serd_caret_copy(NULL, caret); assert(serd_caret_equals(caret, copy)); - assert(!serd_caret_copy(NULL)); + assert(!serd_caret_copy(NULL, NULL)); - SerdNode* const other_node = serd_new_string(serd_string("other")); - SerdCaret* const other_file = serd_caret_new(other_node, 46, 2); - SerdCaret* const other_line = serd_caret_new(node, 47, 2); - SerdCaret* const other_col = serd_caret_new(node, 46, 3); + SerdNode* const other_node = serd_new_string(NULL, serd_string("other")); + SerdCaret* const other_file = serd_caret_new(NULL, other_node, 46, 2); + SerdCaret* const other_line = serd_caret_new(NULL, node, 47, 2); + SerdCaret* const other_col = serd_caret_new(NULL, node, 46, 3); assert(!serd_caret_equals(caret, other_file)); assert(!serd_caret_equals(caret, other_line)); @@ -37,13 +40,57 @@ main(void) assert(!serd_caret_equals(caret, NULL)); assert(!serd_caret_equals(NULL, caret)); - serd_caret_free(other_col); - serd_caret_free(other_line); - serd_caret_free(other_file); - serd_node_free(other_node); - serd_caret_free(copy); - serd_caret_free(caret); - serd_node_free(node); + serd_caret_free(NULL, other_col); + serd_caret_free(NULL, other_line); + serd_caret_free(NULL, other_file); + serd_node_free(NULL, other_node); + serd_caret_free(NULL, copy); + serd_caret_free(NULL, caret); + serd_node_free(NULL, node); + + return 0; +} + +static void +test_failed_alloc(void) +{ + SerdNode* node = serd_new_token(NULL, SERD_LITERAL, serd_string("node")); + + SerdFailingAllocator allocator = serd_failing_allocator(); + // Successfully allocate a new caret to count the number of allocations + SerdCaret* const caret = serd_caret_new(&allocator.base, node, 46, 2); + assert(caret); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations; + for (size_t i = 0U; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_caret_new(&allocator.base, node, 46, 2)); + } + + // Successfully copy the caret to count the number of allocations + allocator.n_allocations = 0; + allocator.n_remaining = SIZE_MAX; + SerdCaret* const copy = serd_caret_copy(&allocator.base, caret); + assert(copy); + + // Test that each allocation failing is handled gracefully + const size_t n_copy_allocs = allocator.n_allocations; + for (size_t i = 0U; i < n_copy_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_caret_copy(&allocator.base, caret)); + } + + serd_caret_free(&allocator.base, copy); + serd_caret_free(&allocator.base, caret); + serd_node_free(NULL, node); +} + +int +main(void) +{ + test_caret(); + test_failed_alloc(); return 0; } diff --git a/test/test_env.c b/test/test_env.c index 33e41af4..89947826 100644 --- a/test/test_env.c +++ b/test/test_env.c @@ -3,6 +3,8 @@ #undef NDEBUG +#include "failing_allocator.h" + #include "serd/env.h" #include "serd/event.h" #include "serd/node.h" @@ -11,21 +13,139 @@ #include "serd/string_view.h" #include <assert.h> +#include <stdio.h> #include <string.h> #define NS_EG "http://example.org/" static void +test_new_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + // Successfully allocate a env to count the number of allocations + SerdEnv* const env = serd_env_new(&allocator.base, serd_empty_string()); + assert(env); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations; + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_env_new(&allocator.base, serd_empty_string())); + } + + serd_env_free(env); +} + +static void +test_copy_failed_alloc(void) +{ + static const char name[] = "eg"; + static const char uri[] = "http://example.org/"; + + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdEnv* const env = serd_env_new(&allocator.base, serd_empty_string()); + + assert(!serd_env_set_prefix(env, serd_string(name), serd_string(uri))); + assert(!serd_env_set_base_uri(env, serd_string(uri))); + + // Successfully copy an env to count the number of allocations + const size_t n_setup_allocs = allocator.n_allocations; + SerdEnv* const copy = serd_env_copy(&allocator.base, env); + assert(copy); + + // Test that each allocation failing is handled gracefully + const size_t n_copy_allocs = allocator.n_allocations - n_setup_allocs; + for (size_t i = 0; i < n_copy_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_env_copy(&allocator.base, env)); + } + + serd_env_free(copy); + serd_env_free(env); +} + +static void +test_set_prefix_absolute_failed_alloc(void) +{ + const SerdStringView base_uri = serd_string("http://example.org/"); + + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdEnv* const env = serd_env_new(&allocator.base, base_uri); + + char name[64] = "eg"; + char uri[64] = "http://example.org/"; + + SerdStatus st = SERD_SUCCESS; + const size_t n_setup_allocs = allocator.n_allocations; + + // Successfully set an absolute prefix to count the number of allocations + st = serd_env_set_prefix(env, serd_string(name), serd_string(uri)); + assert(st == SERD_SUCCESS); + + // Test that each allocation failing is handled gracefully + const size_t n_set_prefix_allocs = allocator.n_allocations - n_setup_allocs; + for (size_t i = 0; i < n_set_prefix_allocs; ++i) { + allocator.n_remaining = i; + + snprintf(name, sizeof(name), "eg%zu", i); + snprintf(uri, sizeof(name), "http://example.org/%zu", i); + + st = serd_env_set_prefix(env, serd_string(name), serd_string(uri)); + assert(st == SERD_BAD_ALLOC); + } + + serd_env_free(env); +} + +static void +test_set_prefix_relative_failed_alloc(void) +{ + const SerdStringView base_uri = serd_string("http://example.org/"); + + SerdFailingAllocator allocator = serd_failing_allocator(); + + char name[64] = "egX"; + char uri[64] = "relativeX"; + + // Successfully set an absolute prefix to count the number of allocations + SerdEnv* env = serd_env_new(&allocator.base, base_uri); + SerdStatus st = serd_env_set_prefix(env, serd_string(name), serd_string(uri)); + assert(st == SERD_SUCCESS); + serd_env_free(env); + + // Test that each allocation failing is handled gracefully + const size_t n_set_prefix_allocs = allocator.n_allocations; + for (size_t i = 0; i < n_set_prefix_allocs; ++i) { + allocator.n_remaining = i; + + snprintf(name, sizeof(name), "eg%zu", i); + snprintf(uri, sizeof(uri), "relative%zu", i); + + env = serd_env_new(&allocator.base, base_uri); + if (env) { + st = serd_env_set_prefix(env, serd_string(name), serd_string(uri)); + assert(st == SERD_BAD_ALLOC); + } + + serd_env_free(env); + } +} + +static void test_copy(void) { - assert(!serd_env_copy(NULL)); + assert(!serd_env_copy(NULL, NULL)); - SerdEnv* const env = serd_env_new(serd_string("http://example.org/base/")); + SerdEnv* const env = + serd_env_new(NULL, serd_string("http://example.org/base/")); serd_env_set_prefix( env, serd_string("eg"), serd_string("http://example.org/")); - SerdEnv* const env_copy = serd_env_copy(env); + SerdEnv* const env_copy = serd_env_copy(NULL, env); assert(serd_env_equals(env, env_copy)); @@ -46,7 +166,7 @@ test_copy(void) static void test_comparison(void) { - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(!serd_env_equals(env, NULL)); assert(!serd_env_equals(NULL, env)); @@ -60,7 +180,7 @@ static void test_null(void) { // "Copying" NULL returns null - assert(!serd_env_copy(NULL)); + assert(!serd_env_copy(NULL, NULL)); // Accessors are tolerant to a NULL env for convenience assert(!serd_env_base_uri(NULL)); @@ -81,8 +201,8 @@ count_prefixes(void* handle, const SerdEvent* event) static void test_base_uri(void) { - SerdEnv* const env = serd_env_new(serd_empty_string()); - SerdNode* const eg = serd_new_uri(serd_string(NS_EG)); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); + SerdNode* const eg = serd_new_uri(NULL, serd_string(NS_EG)); // Test that invalid calls work as expected assert(!serd_env_base_uri(env)); @@ -101,8 +221,8 @@ test_base_uri(void) assert(!serd_env_set_base_uri(env, serd_empty_string())); assert(!serd_env_base_uri(env)); + serd_node_free(NULL, eg); serd_env_free(env); - serd_node_free(eg); } static void @@ -114,7 +234,7 @@ test_set_prefix(void) const SerdStringView rel = serd_string("rel"); const SerdStringView base = serd_string("http://example.org/"); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); // Set a valid prefix assert(!serd_env_set_prefix(env, name1, eg)); @@ -130,7 +250,7 @@ test_set_prefix(void) size_t n_prefixes = 0; SerdSink* const count_prefixes_sink = - serd_sink_new(&n_prefixes, count_prefixes, NULL); + serd_sink_new(NULL, &n_prefixes, count_prefixes, NULL); serd_env_write_prefixes(env, count_prefixes_sink); serd_sink_free(count_prefixes_sink); @@ -142,13 +262,13 @@ test_set_prefix(void) static void test_expand_untyped_literal(void) { - SerdNode* const untyped = serd_new_string(serd_string("data")); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdNode* const untyped = serd_new_string(NULL, serd_string("data")); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(!serd_env_expand_node(env, untyped)); serd_env_free(env); - serd_node_free(untyped); + serd_node_free(NULL, untyped); } static void @@ -157,14 +277,14 @@ test_expand_bad_uri_datatype(void) const SerdStringView type = serd_string("Type"); SerdNode* const typed = - serd_new_literal(serd_string("data"), SERD_HAS_DATATYPE, type); + serd_new_literal(NULL, serd_string("data"), SERD_HAS_DATATYPE, type); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(!serd_env_expand_node(env, typed)); serd_env_free(env); - serd_node_free(typed); + serd_node_free(NULL, typed); } static void @@ -172,19 +292,19 @@ test_expand_uri(void) { const SerdStringView base = serd_string("http://example.org/b/"); - SerdEnv* const env = serd_env_new(base); - SerdNode* const rel = serd_new_uri(serd_string("rel")); + SerdEnv* const env = serd_env_new(NULL, base); + SerdNode* const rel = serd_new_uri(NULL, serd_string("rel")); SerdNode* const rel_out = serd_env_expand_node(env, rel); - SerdNode* const empty = serd_new_uri(serd_empty_string()); + SerdNode* const empty = serd_new_uri(NULL, serd_empty_string()); SerdNode* const empty_out = serd_env_expand_node(env, empty); assert(!strcmp(serd_node_string(rel_out), "http://example.org/b/rel")); assert(!strcmp(serd_node_string(empty_out), "http://example.org/b/")); - serd_node_free(empty_out); - serd_node_free(empty); - serd_node_free(rel_out); - serd_node_free(rel); + serd_node_free(NULL, empty_out); + serd_node_free(NULL, empty); + serd_node_free(NULL, rel_out); + serd_node_free(NULL, rel); serd_env_free(env); } @@ -193,27 +313,27 @@ test_expand_empty_uri_ref(void) { const SerdStringView base = serd_string("http://example.org/b/"); - SerdNode* const rel = serd_new_uri(serd_string("rel")); - SerdEnv* const env = serd_env_new(base); + SerdNode* const rel = serd_new_uri(NULL, serd_string("rel")); + SerdEnv* const env = serd_env_new(NULL, base); SerdNode* const rel_out = serd_env_expand_node(env, rel); assert(!strcmp(serd_node_string(rel_out), "http://example.org/b/rel")); - serd_node_free(rel_out); + serd_node_free(NULL, rel_out); serd_env_free(env); - serd_node_free(rel); + serd_node_free(NULL, rel); } static void test_expand_bad_uri(void) { - SerdNode* const bad_uri = serd_new_uri(serd_string("rel")); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdNode* const bad_uri = serd_new_uri(NULL, serd_string("rel")); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(!serd_env_expand_node(env, bad_uri)); serd_env_free(env); - serd_node_free(bad_uri); + serd_node_free(NULL, bad_uri); } static void @@ -222,7 +342,7 @@ test_expand_curie(void) const SerdStringView name = serd_string("eg.1"); const SerdStringView eg = serd_string(NS_EG); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(!serd_env_set_prefix(env, name, eg)); @@ -231,7 +351,7 @@ test_expand_curie(void) assert(expanded); assert(!strcmp(serd_node_string(expanded), "http://example.org/foo")); - serd_node_free(expanded); + serd_node_free(NULL, expanded); serd_env_free(env); } @@ -239,7 +359,7 @@ test_expand_curie(void) static void test_expand_bad_curie(void) { - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(!serd_env_expand_curie(NULL, serd_empty_string())); assert(!serd_env_expand_curie(NULL, serd_string("what:ever"))); @@ -252,13 +372,13 @@ test_expand_bad_curie(void) static void test_expand_blank(void) { - SerdNode* const blank = serd_new_blank(serd_string("b1")); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdNode* const blank = serd_new_blank(NULL, serd_string("b1")); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(!serd_env_expand_node(env, blank)); serd_env_free(env); - serd_node_free(blank); + serd_node_free(NULL, blank); } static void @@ -268,8 +388,8 @@ test_equals(void) const SerdStringView base1 = serd_string(NS_EG "b1/"); const SerdStringView base2 = serd_string(NS_EG "b2/"); - SerdEnv* const env1 = serd_env_new(base1); - SerdEnv* const env2 = serd_env_new(base2); + SerdEnv* const env1 = serd_env_new(NULL, base1); + SerdEnv* const env2 = serd_env_new(NULL, base2); assert(!serd_env_equals(env1, NULL)); assert(!serd_env_equals(NULL, env1)); @@ -289,7 +409,7 @@ test_equals(void) serd_env_set_base_uri(env2, base2); assert(!serd_env_equals(env1, env2)); - SerdEnv* const env3 = serd_env_copy(env2); + SerdEnv* const env3 = serd_env_copy(NULL, env2); assert(serd_env_equals(env3, env2)); serd_env_free(env3); @@ -300,6 +420,10 @@ test_equals(void) int main(void) { + test_new_failed_alloc(); + test_copy_failed_alloc(); + test_set_prefix_absolute_failed_alloc(); + test_set_prefix_relative_failed_alloc(); test_copy(); test_comparison(); test_null(); diff --git a/test/test_free_null.c b/test/test_free_null.c index 87dfa7db..891f9b65 100644 --- a/test/test_free_null.c +++ b/test/test_free_null.c @@ -17,14 +17,14 @@ int main(void) { - serd_free(NULL); - serd_node_free(NULL); + serd_free(NULL, NULL); + serd_node_free(NULL, NULL); serd_world_free(NULL); serd_env_free(NULL); serd_sink_free(NULL); serd_reader_free(NULL); serd_writer_free(NULL); - serd_caret_free(NULL); + serd_caret_free(NULL, NULL); return 0; } diff --git a/test/test_log.c b/test/test_log.c index 3ab2008f..5da8ec09 100644 --- a/test/test_log.c +++ b/test/test_log.c @@ -39,7 +39,7 @@ custom_log_func(void* const handle, static void test_bad_arg(void) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); bool called = false; serd_set_log_func(world, custom_log_func, &called); @@ -52,7 +52,7 @@ test_bad_arg(void) static void test_default_log(void) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); for (unsigned i = 0; i <= SERD_LOG_LEVEL_DEBUG; ++i) { const SerdLogLevel level = (SerdLogLevel)i; @@ -66,7 +66,7 @@ test_default_log(void) static void test_custom_log(void) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); bool called = false; serd_set_log_func(world, custom_log_func, &called); @@ -82,22 +82,22 @@ test_custom_log(void) static void test_caret(void) { - SerdWorld* const world = serd_world_new(); - SerdNode* const name = serd_new_string(serd_string("filename")); - SerdCaret* const caret = serd_caret_new(name, 46, 2); + SerdWorld* const world = serd_world_new(NULL); + SerdNode* const name = serd_new_string(NULL, serd_string("filename")); + SerdCaret* const caret = serd_caret_new(NULL, name, 46, 2); serd_logf_at(world, SERD_LOG_LEVEL_NOTICE, caret, "is just ahead of me"); serd_logf_at(world, SERD_LOG_LEVEL_NOTICE, NULL, "isn't"); - serd_caret_free(caret); - serd_node_free(name); + serd_caret_free(NULL, caret); + serd_node_free(NULL, name); serd_world_free(world); } static void test_filename_only(void) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); const SerdLogField fields[3] = {{"TEST_KEY", "TEST VALUE"}, {"SERD_FILE", "somename"}, diff --git a/test/test_node.c b/test/test_node.c index 07ea4973..23d1a45a 100644 --- a/test/test_node.c +++ b/test/test_node.c @@ -3,7 +3,6 @@ #undef NDEBUG -#include "serd/memory.h" #include "serd/node.h" #include "serd/status.h" #include "serd/string_view.h" @@ -51,23 +50,23 @@ static void test_boolean(void) { - SerdNode* const true_node = serd_new_boolean(true); + SerdNode* const true_node = serd_new_boolean(NULL, true); assert(!strcmp(serd_node_string(true_node), "true")); assert(serd_get_boolean(true_node)); const SerdNode* const true_datatype = serd_node_datatype(true_node); assert(true_datatype); assert(!strcmp(serd_node_string(true_datatype), NS_XSD "boolean")); - serd_node_free(true_node); + serd_node_free(NULL, true_node); - SerdNode* const false_node = serd_new_boolean(false); + SerdNode* const false_node = serd_new_boolean(NULL, false); assert(!strcmp(serd_node_string(false_node), "false")); assert(!serd_get_boolean(false_node)); const SerdNode* const false_datatype = serd_node_datatype(false_node); assert(false_datatype); assert(!strcmp(serd_node_string(false_datatype), NS_XSD "boolean")); - serd_node_free(false_node); + serd_node_free(NULL, false_node); } static void @@ -76,12 +75,12 @@ check_get_boolean(const char* string, const bool expected) { SerdNode* const node = serd_new_literal( - serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); + NULL, serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); assert(node); assert(serd_get_boolean(node) == expected); - serd_node_free(node); + serd_node_free(NULL, node); } static void @@ -115,7 +114,7 @@ test_decimal(void) "0.0000000001"}; for (size_t i = 0; i < sizeof(test_values) / sizeof(double); ++i) { - SerdNode* node = serd_new_decimal(test_values[i], NULL); + SerdNode* node = serd_new_decimal(NULL, test_values[i], NULL); const char* node_str = serd_node_string(node); assert(!strcmp(node_str, test_strings[i])); @@ -128,7 +127,7 @@ test_decimal(void) const double value = serd_get_double(node); assert(!memcmp(&value, &test_values[i], sizeof(value))); - serd_node_free(node); + serd_node_free(NULL, node); } } @@ -140,7 +139,7 @@ test_double(void) "0.0E0", "-0.0E0", "1.2E0", "-2.3E0", "4.56789E6"}; for (size_t i = 0; i < sizeof(test_values) / sizeof(double); ++i) { - SerdNode* node = serd_new_double(test_values[i]); + SerdNode* node = serd_new_double(NULL, test_values[i]); const char* node_str = serd_node_string(node); assert(!strcmp(node_str, test_strings[i])); @@ -153,7 +152,7 @@ test_double(void) const double value = serd_get_double(node); assert(!memcmp(&value, &test_values[i], sizeof(value))); - serd_node_free(node); + serd_node_free(NULL, node); } } @@ -163,14 +162,14 @@ check_get_double(const char* string, const double expected) { SerdNode* const node = serd_new_literal( - serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); + NULL, serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); assert(node); const double value = serd_get_double(node); assert(!memcmp(&value, &expected, sizeof(value))); - serd_node_free(node); + serd_node_free(NULL, node); } static void @@ -187,20 +186,22 @@ test_get_double(void) SERD_DISABLE_CONVERSION_WARNINGS - SerdNode* const nan = serd_new_string(serd_string("unknown")); + SerdNode* const nan = serd_new_string(NULL, serd_string("unknown")); assert(isnan(serd_get_double(nan))); - serd_node_free(nan); + serd_node_free(NULL, nan); - SerdNode* const invalid = serd_new_literal( - serd_string("!invalid"), SERD_HAS_DATATYPE, serd_string(NS_XSD "long")); + SerdNode* const invalid = serd_new_literal(NULL, + serd_string("!invalid"), + SERD_HAS_DATATYPE, + serd_string(NS_XSD "long")); assert(isnan(serd_get_double(invalid))); - serd_node_free(invalid); + serd_node_free(NULL, invalid); - SerdNode* const base64 = serd_new_base64(blob, sizeof(blob)); + SerdNode* const base64 = serd_new_base64(NULL, blob, sizeof(blob)); assert(isnan(serd_get_double(base64))); - serd_node_free(base64); + serd_node_free(NULL, base64); SERD_RESTORE_WARNINGS } @@ -213,7 +214,7 @@ test_float(void) "0.0E0", "-0.0E0", "1.5E0", "-2.5E0", "4.56789E6"}; for (size_t i = 0; i < sizeof(test_values) / sizeof(float); ++i) { - SerdNode* node = serd_new_float(test_values[i]); + SerdNode* node = serd_new_float(NULL, test_values[i]); const char* node_str = serd_node_string(node); assert(!strcmp(node_str, test_strings[i])); @@ -226,7 +227,7 @@ test_float(void) const float value = serd_get_float(node); assert(!memcmp(&value, &test_values[i], sizeof(value))); - serd_node_free(node); + serd_node_free(NULL, node); } } @@ -236,14 +237,14 @@ check_get_float(const char* string, const float expected) { SerdNode* const node = serd_new_literal( - serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); + NULL, serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); assert(node); const float value = serd_get_float(node); assert(!memcmp(&value, &expected, sizeof(value))); - serd_node_free(node); + serd_node_free(NULL, node); } static void @@ -258,18 +259,20 @@ test_get_float(void) SERD_DISABLE_CONVERSION_WARNINGS - SerdNode* const nan = serd_new_string(serd_string("unknown")); + SerdNode* const nan = serd_new_string(NULL, serd_string("unknown")); assert(isnan(serd_get_float(nan))); - serd_node_free(nan); + serd_node_free(NULL, nan); - SerdNode* const invalid = serd_new_literal( - serd_string("!invalid"), SERD_HAS_DATATYPE, serd_string(NS_XSD "long")); + SerdNode* const invalid = serd_new_literal(NULL, + serd_string("!invalid"), + SERD_HAS_DATATYPE, + serd_string(NS_XSD "long")); assert(isnan(serd_get_double(invalid))); SERD_RESTORE_WARNINGS - serd_node_free(invalid); + serd_node_free(NULL, invalid); } static void @@ -280,7 +283,7 @@ test_integer(void) "0", "0", "-23", "23", "-12340", "1000", "-1000"}; for (size_t i = 0; i < sizeof(test_values) / sizeof(double); ++i) { - SerdNode* node = serd_new_integer(test_values[i]); + SerdNode* node = serd_new_integer(NULL, test_values[i]); const char* node_str = serd_node_string(node); assert(!strcmp(node_str, test_strings[i])); const size_t len = strlen(node_str); @@ -291,7 +294,7 @@ test_integer(void) assert(!strcmp(serd_node_string(datatype), NS_XSD "integer")); assert(serd_get_integer(node) == test_values[i]); - serd_node_free(node); + serd_node_free(NULL, node); } } @@ -301,12 +304,12 @@ check_get_integer(const char* string, const int64_t expected) { SerdNode* const node = serd_new_literal( - serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); + NULL, serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); assert(node); assert(serd_get_integer(node) == expected); - serd_node_free(node); + serd_node_free(NULL, node); } static void @@ -325,7 +328,7 @@ test_get_integer(void) static void test_base64(void) { - assert(!serd_new_base64(&SERD_URI_NULL, 0)); + assert(!serd_new_base64(NULL, &SERD_URI_NULL, 0)); // Test valid base64 blobs with a range of sizes for (size_t size = 1; size < 256; ++size) { @@ -334,7 +337,7 @@ test_base64(void) data[i] = (uint8_t)((size + i) % 256); } - SerdNode* blob = serd_new_base64(data, size); + SerdNode* blob = serd_new_base64(NULL, data, size); const char* blob_str = serd_node_string(blob); const size_t max_size = serd_get_base64_size(blob); uint8_t* out = (uint8_t*)calloc(1, max_size); @@ -353,8 +356,8 @@ test_base64(void) assert(datatype); assert(!strcmp(serd_node_string(datatype), NS_XSD "base64Binary")); - serd_node_free(blob); - serd_free(out); + serd_node_free(NULL, blob); + free(out); free(data); } } @@ -365,7 +368,7 @@ check_get_base64(const char* string, const char* expected) { SerdNode* const node = serd_new_literal( - serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); + NULL, serd_string(string), SERD_HAS_DATATYPE, serd_string(datatype_uri)); assert(node); @@ -380,7 +383,7 @@ check_get_base64(const char* string, assert(strlen(decoded) <= max_size); free(decoded); - serd_node_free(node); + serd_node_free(NULL, node); } static void @@ -390,14 +393,16 @@ test_get_base64(void) check_get_base64("Zm9vYg==", NS_XSD "base64Binary", "foob"); check_get_base64(" \f\n\r\t\vZm9v \f\n\r\t\v", NS_XSD "base64Binary", "foo"); - SerdNode* const node = serd_new_literal( - serd_string("Zm9v"), SERD_HAS_DATATYPE, serd_string(NS_XSD "base64Binary")); + SerdNode* const node = serd_new_literal(NULL, + serd_string("Zm9v"), + SERD_HAS_DATATYPE, + serd_string(NS_XSD "base64Binary")); char small[2] = {0}; const SerdWriteResult r = serd_get_base64(node, sizeof(small), small); assert(r.status == SERD_OVERFLOW); - serd_node_free(node); + serd_node_free(NULL, node); } static void @@ -408,56 +413,56 @@ test_node_equals(void) static const SerdStringView replacement_char = { (const char*)replacement_char_str, 3}; - SerdNode* lhs = serd_new_string(replacement_char); - SerdNode* rhs = serd_new_string(serd_string("123")); + SerdNode* lhs = serd_new_string(NULL, replacement_char); + SerdNode* rhs = serd_new_string(NULL, serd_string("123")); assert(serd_node_equals(lhs, lhs)); assert(!serd_node_equals(lhs, rhs)); - assert(!serd_node_copy(NULL)); + assert(!serd_node_copy(NULL, NULL)); - serd_node_free(lhs); - serd_node_free(rhs); + serd_node_free(NULL, lhs); + serd_node_free(NULL, rhs); } static void test_node_from_string(void) { - SerdNode* const hello = serd_new_string(serd_string("hello\"")); + SerdNode* const hello = serd_new_string(NULL, serd_string("hello\"")); assert(serd_node_length(hello) == 6); assert(!serd_node_flags(hello)); assert(!strncmp(serd_node_string(hello), "hello\"", 6)); assert(!strcmp(serd_node_string_view(hello).data, "hello\"")); assert(serd_node_string_view(hello).length == 6); - serd_node_free(hello); + serd_node_free(NULL, hello); - SerdNode* const uri = serd_new_uri(serd_string("http://example.org/")); + SerdNode* const uri = serd_new_uri(NULL, serd_string("http://example.org/")); assert(serd_node_length(uri) == 19); assert(!strcmp(serd_node_string(uri), "http://example.org/")); assert(serd_node_uri_view(uri).authority.length == 11); assert(!strncmp(serd_node_uri_view(uri).authority.data, "example.org", 11)); - serd_node_free(uri); + serd_node_free(NULL, uri); } static void test_node_from_substring(void) { - SerdNode* const a_b = serd_new_string(serd_substring("a\"bc", 3)); + SerdNode* const a_b = serd_new_string(NULL, serd_substring("a\"bc", 3)); assert(serd_node_length(a_b) == 3); assert(!serd_node_flags(a_b)); assert(strlen(serd_node_string(a_b)) == 3); assert(!strncmp(serd_node_string(a_b), "a\"b", 3)); - serd_node_free(a_b); + serd_node_free(NULL, a_b); } static void check_copy_equals(const SerdNode* const node) { - SerdNode* const copy = serd_node_copy(node); + SerdNode* const copy = serd_node_copy(NULL, node); assert(serd_node_equals(node, copy)); - serd_node_free(copy); + serd_node_free(NULL, copy); } static void @@ -466,35 +471,46 @@ test_literal(void) const SerdStringView hello_str = serd_string("hello"); const SerdStringView empty_str = serd_empty_string(); - assert(!serd_new_literal( - hello_str, SERD_HAS_DATATYPE | SERD_HAS_LANGUAGE, serd_string("whatever"))); + assert(!serd_new_literal(NULL, + hello_str, + SERD_HAS_DATATYPE | SERD_HAS_LANGUAGE, + serd_string("whatever"))); - assert(!serd_new_literal(hello_str, SERD_HAS_DATATYPE, empty_str)); - assert(!serd_new_literal(hello_str, SERD_HAS_LANGUAGE, empty_str)); + assert(!serd_new_literal(NULL, hello_str, SERD_HAS_DATATYPE, empty_str)); + assert(!serd_new_literal(NULL, hello_str, SERD_HAS_LANGUAGE, empty_str)); - assert(!serd_new_literal(hello_str, SERD_HAS_DATATYPE, serd_string("Type"))); - assert(!serd_new_literal(hello_str, SERD_HAS_DATATYPE, serd_string("de"))); + assert( + !serd_new_literal(NULL, hello_str, SERD_HAS_DATATYPE, serd_string("Type"))); + assert( + !serd_new_literal(NULL, hello_str, SERD_HAS_DATATYPE, serd_string("de"))); - assert(!serd_new_literal(hello_str, SERD_HAS_LANGUAGE, serd_string("3n"))); - assert(!serd_new_literal(hello_str, SERD_HAS_LANGUAGE, serd_string("d3"))); - assert(!serd_new_literal(hello_str, SERD_HAS_LANGUAGE, serd_string("d3"))); - assert(!serd_new_literal(hello_str, SERD_HAS_LANGUAGE, serd_string("en-!"))); + assert( + !serd_new_literal(NULL, hello_str, SERD_HAS_LANGUAGE, serd_string("3n"))); + assert( + !serd_new_literal(NULL, hello_str, SERD_HAS_LANGUAGE, serd_string("d3"))); + assert( + !serd_new_literal(NULL, hello_str, SERD_HAS_LANGUAGE, serd_string("d3"))); + assert( + !serd_new_literal(NULL, hello_str, SERD_HAS_LANGUAGE, serd_string("en-!"))); - SerdNode* hello2 = serd_new_string(serd_string("hello\"")); + SerdNode* hello2 = serd_new_string(NULL, serd_string("hello\"")); assert(serd_node_length(hello2) == 6 && !strcmp(serd_node_string(hello2), "hello\"")); check_copy_equals(hello2); - assert(!serd_new_literal( - serd_string("plain"), SERD_HAS_DATATYPE, serd_string(NS_RDF "langString"))); + assert(!serd_new_literal(NULL, + serd_string("plain"), + SERD_HAS_DATATYPE, + serd_string(NS_RDF "langString"))); - serd_node_free(hello2); + serd_node_free(NULL, hello2); const char* lang_lit_str = "\"Hello\"@en-ca"; SerdNode* sliced_lang_lit = - serd_new_literal(serd_substring(lang_lit_str + 1, 5), + serd_new_literal(NULL, + serd_substring(lang_lit_str + 1, 5), SERD_HAS_LANGUAGE, serd_substring(lang_lit_str + 8, 5)); @@ -504,11 +520,12 @@ test_literal(void) assert(lang); assert(!strcmp(serd_node_string(lang), "en-ca")); check_copy_equals(sliced_lang_lit); - serd_node_free(sliced_lang_lit); + serd_node_free(NULL, sliced_lang_lit); const char* type_lit_str = "\"Hallo\"^^<http://example.org/Greeting>"; SerdNode* sliced_type_lit = - serd_new_literal(serd_substring(type_lit_str + 1, 5), + serd_new_literal(NULL, + serd_substring(type_lit_str + 1, 5), SERD_HAS_DATATYPE, serd_substring(type_lit_str + 10, 27)); @@ -517,53 +534,56 @@ test_literal(void) const SerdNode* const datatype = serd_node_datatype(sliced_type_lit); assert(datatype); assert(!strcmp(serd_node_string(datatype), "http://example.org/Greeting")); - serd_node_free(sliced_type_lit); + serd_node_free(NULL, sliced_type_lit); } static void test_blank(void) { - SerdNode* blank = serd_new_blank(serd_string("b0")); + SerdNode* blank = serd_new_blank(NULL, serd_string("b0")); assert(serd_node_length(blank) == 2); assert(serd_node_flags(blank) == 0); assert(!strcmp(serd_node_string(blank), "b0")); - serd_node_free(blank); + serd_node_free(NULL, blank); } static void test_compare(void) { SerdNode* xsd_short = - serd_new_uri(serd_string("http://www.w3.org/2001/XMLSchema#short")); + serd_new_uri(NULL, serd_string("http://www.w3.org/2001/XMLSchema#short")); - SerdNode* angst = serd_new_string(serd_string("angst")); + SerdNode* angst = serd_new_string(NULL, serd_string("angst")); SerdNode* angst_de = serd_new_literal( - serd_string("angst"), SERD_HAS_LANGUAGE, serd_string("de")); + NULL, serd_string("angst"), SERD_HAS_LANGUAGE, serd_string("de")); assert(angst_de); SerdNode* angst_en = serd_new_literal( - serd_string("angst"), SERD_HAS_LANGUAGE, serd_string("en")); + NULL, serd_string("angst"), SERD_HAS_LANGUAGE, serd_string("en")); SerdNode* hallo = serd_new_literal( - serd_string("Hallo"), SERD_HAS_LANGUAGE, serd_string("de")); + NULL, serd_string("Hallo"), SERD_HAS_LANGUAGE, serd_string("de")); - SerdNode* hello = serd_new_string(serd_string("Hello")); - SerdNode* universe = serd_new_string(serd_string("Universe")); - SerdNode* integer = serd_new_integer(4); - SerdNode* blank = serd_new_blank(serd_string("b1")); - SerdNode* uri = serd_new_uri(serd_string("http://example.org/")); + SerdNode* hello = serd_new_string(NULL, serd_string("Hello")); + SerdNode* universe = serd_new_string(NULL, serd_string("Universe")); + SerdNode* integer = serd_new_integer(NULL, 4); + SerdNode* blank = serd_new_blank(NULL, serd_string("b1")); + SerdNode* uri = serd_new_uri(NULL, serd_string("http://example.org/")); SerdNode* aardvark = - serd_new_literal(serd_string("alex"), + serd_new_literal(NULL, + serd_string("alex"), SERD_HAS_DATATYPE, serd_string("http://example.org/Aardvark")); - SerdNode* badger = serd_new_literal(serd_string("bobby"), + SerdNode* badger = serd_new_literal(NULL, + serd_string("bobby"), SERD_HAS_DATATYPE, serd_string("http://example.org/Badger")); // Types are ordered according to their SerdNodeType (more or less arbitrary) + assert(serd_node_compare(integer, hello) < 0); assert(serd_node_compare(hello, uri) < 0); assert(serd_node_compare(uri, blank) < 0); @@ -575,18 +595,18 @@ test_compare(void) assert(serd_node_compare(angst_de, angst_en) < 0); assert(serd_node_compare(aardvark, badger) < 0); - serd_node_free(uri); - serd_node_free(blank); - serd_node_free(integer); - serd_node_free(badger); - serd_node_free(aardvark); - serd_node_free(universe); - serd_node_free(hello); - serd_node_free(hallo); - serd_node_free(angst_en); - serd_node_free(angst_de); - serd_node_free(angst); - serd_node_free(xsd_short); + serd_node_free(NULL, uri); + serd_node_free(NULL, blank); + serd_node_free(NULL, integer); + serd_node_free(NULL, badger); + serd_node_free(NULL, aardvark); + serd_node_free(NULL, universe); + serd_node_free(NULL, hello); + serd_node_free(NULL, hallo); + serd_node_free(NULL, angst_en); + serd_node_free(NULL, angst_de); + serd_node_free(NULL, angst); + serd_node_free(NULL, xsd_short); } int diff --git a/test/test_overflow.c b/test/test_overflow.c index 6272e807..7b1693a8 100644 --- a/test/test_overflow.c +++ b/test/test_overflow.c @@ -22,14 +22,14 @@ test_size(SerdWorld* const world, limits.reader_stack_size = stack_size; serd_world_set_limits(world, limits); - SerdSink* sink = serd_sink_new(NULL, NULL, NULL); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdSink* sink = serd_sink_new(NULL, NULL, NULL, NULL); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); SerdReader* const reader = serd_reader_new(world, syntax, flags, env, sink); if (!reader) { return SERD_BAD_STACK; } - SerdNode* string_name = serd_new_string(serd_string("string")); + SerdNode* string_name = serd_new_string(NULL, serd_string("string")); const char* position = str; SerdInputStream in = serd_open_input_string(&position); serd_reader_start(reader, &in, string_name, 1); @@ -37,7 +37,7 @@ test_size(SerdWorld* const world, const SerdStatus st = serd_reader_read_document(reader); serd_close_input(&in); - serd_node_free(string_name); + serd_node_free(NULL, string_name); serd_reader_free(reader); serd_env_free(env); serd_sink_free(sink); @@ -76,7 +76,7 @@ test_ntriples_overflow(void) NULL, }; - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); for (const char* const* t = test_strings; *t; ++t) { test_all_sizes(world, *t, SERD_NTRIPLES, 0U); @@ -202,7 +202,7 @@ test_turtle_overflow(void) NULL, }; - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); for (const char* const* t = test_strings; *t; ++t) { test_all_sizes(world, *t, SERD_TURTLE, SERD_READ_VARIABLES); diff --git a/test/test_reader.c b/test/test_reader.c index f1ec1d35..a0eaee5c 100644 --- a/test/test_reader.c +++ b/test/test_reader.c @@ -3,6 +3,8 @@ #undef NDEBUG +#include "failing_allocator.h" + #include "serd/caret.h" #include "serd/env.h" #include "serd/event.h" @@ -60,6 +62,81 @@ test_sink(void* handle, const SerdEvent* event) return SERD_SUCCESS; } +static void +test_new_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdWorld* const world = serd_world_new(&allocator.base); + SerdEnv* const env = serd_env_new(&allocator.base, serd_empty_string()); + size_t ignored = 0U; + SerdSink* const sink = + serd_sink_new(&allocator.base, &ignored, test_sink, NULL); + + // Successfully allocate a reader to count the number of allocations + const size_t n_world_allocs = allocator.n_allocations; + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); + assert(reader); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations - n_world_allocs; + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_reader_new(world, SERD_TURTLE, 0U, env, sink)); + } + + serd_reader_free(reader); + serd_env_free(env); + serd_sink_free(sink); + serd_world_free(world); +} + +static void +test_start_failed_alloc(const char* const path) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + FILE* const f = fopen(path, "w+b"); + assert(f); + + fprintf(f, "_:s <http://example.org/p> _:o .\n"); + fflush(f); + fseek(f, 0L, SEEK_SET); + + SerdWorld* world = serd_world_new(&allocator.base); + SerdEnv* env = serd_env_new(&allocator.base, serd_empty_string()); + size_t ignored = 0U; + SerdSink* sink = serd_sink_new(&allocator.base, &ignored, test_sink, NULL); + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); + assert(reader); + + SerdInputStream in = + serd_open_input_stream((SerdReadFunc)fread, (SerdErrorFunc)ferror, NULL, f); + + // Successfully start a new read to count the number of allocations + const size_t n_setup_allocs = allocator.n_allocations; + assert(serd_reader_start(reader, &in, NULL, 4096) == SERD_SUCCESS); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations - n_setup_allocs; + assert(!serd_reader_finish(reader)); + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + + in = serd_open_input_stream( + (SerdReadFunc)fread, (SerdErrorFunc)ferror, NULL, f); + + SerdStatus st = serd_reader_start(reader, &in, NULL, 4096); + assert(st == SERD_BAD_ALLOC); + } + + serd_reader_free(reader); + serd_env_free(env); + serd_sink_free(sink); + serd_world_free(world); + fclose(f); +} + ZIX_PURE_FUNC static size_t prepare_test_read(void* buf, size_t size, size_t nmemb, void* stream) { @@ -84,7 +161,7 @@ prepare_test_error(void* stream) static void test_prepare_error(const char* const path) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); ReaderTest rt = {0, 0, 0, 0}; FILE* const f = fopen(path, "w+b"); @@ -94,12 +171,11 @@ test_prepare_error(const char* const path) fflush(f); fseek(f, 0L, SEEK_SET); - SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL); + SerdSink* const sink = serd_sink_new(NULL, &rt, test_sink, NULL); assert(sink); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, env, sink); - assert(reader); SerdInputStream in = @@ -124,14 +200,13 @@ test_prepare_error(const char* const path) static void test_read_string(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); ReaderTest rt = {0, 0, 0, 0}; - SerdSink* sink = serd_sink_new(&rt, test_sink, NULL); + SerdSink* sink = serd_sink_new(NULL, &rt, test_sink, NULL); assert(sink); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); - assert(reader); static const char* const string1 = @@ -228,11 +303,12 @@ test_read_eof_by_page(const char* const path) fflush(f); fseek(f, 0L, SEEK_SET); - SerdWorld* world = serd_world_new(); - ReaderTest ignored = {0, 0, 0, 0}; - SerdSink* sink = serd_sink_new(&ignored, test_sink, NULL); - SerdEnv* env = serd_env_new(serd_empty_string()); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); + SerdWorld* const world = serd_world_new(NULL); + ReaderTest rt = {0, 0, 0, 0}; + SerdSink* const sink = serd_sink_new(NULL, &rt, test_sink, NULL); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); + SerdInputStream in = serd_open_input_stream((SerdReadFunc)fread, (SerdErrorFunc)ferror, NULL, f); @@ -255,11 +331,11 @@ test_read_eof_by_page(const char* const path) static void test_read_eof_by_byte(void) { - SerdWorld* world = serd_world_new(); - ReaderTest ignored = {0, 0, 0, 0}; - SerdSink* sink = serd_sink_new(&ignored, test_sink, NULL); - SerdEnv* env = serd_env_new(serd_empty_string()); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); + SerdWorld* const world = serd_world_new(NULL); + ReaderTest rt = {0, 0, 0, 0}; + SerdSink* const sink = serd_sink_new(NULL, &rt, test_sink, NULL); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); size_t n_reads = 0U; SerdInputStream in = serd_open_input_stream( @@ -305,12 +381,12 @@ test_read_nquads_chunks(const char* const path) fseek(f, 0, SEEK_SET); - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); ReaderTest rt = {0, 0, 0, 0}; - SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL); + SerdSink* const sink = serd_sink_new(NULL, &rt, test_sink, NULL); assert(sink); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(env); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); @@ -391,12 +467,12 @@ test_read_turtle_chunks(const char* const path) fwrite(&null, sizeof(null), 1, f); fseek(f, 0, SEEK_SET); - SerdWorld* world = serd_world_new(); - ReaderTest rt = {0, 0, 0, 0}; - SerdSink* sink = serd_sink_new(&rt, test_sink, NULL); + SerdWorld* const world = serd_world_new(NULL); + ReaderTest rt = {0, 0, 0, 0}; + SerdSink* const sink = serd_sink_new(NULL, &rt, test_sink, NULL); assert(sink); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(env); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); @@ -479,13 +555,13 @@ test_read_turtle_chunks(const char* const path) static void test_read_empty(const char* const path) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); ReaderTest rt = {0, 0, 0, 0}; - SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL); + SerdSink* const sink = serd_sink_new(NULL, &rt, test_sink, NULL); assert(sink); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(env); SerdReader* const reader = @@ -536,10 +612,10 @@ check_cursor(void* handle, const SerdEvent* event) static void test_error_cursor(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); bool called = false; - SerdSink* sink = serd_sink_new(&called, check_cursor, NULL); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdSink* const sink = serd_sink_new(NULL, &called, check_cursor, NULL); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink); assert(sink); assert(reader); @@ -548,7 +624,7 @@ test_error_cursor(void) "<http://example.org/s> <http://example.org/p> " "<http://example.org/o> ."; - SerdNode* const string_name = serd_new_string(serd_string("string")); + SerdNode* const string_name = serd_new_string(NULL, serd_string("string")); const char* position = string; SerdInputStream in = serd_open_input_string(&position); @@ -559,7 +635,7 @@ test_error_cursor(void) assert(called); assert(!serd_close_input(&in)); - serd_node_free(string_name); + serd_node_free(NULL, string_name); serd_reader_free(reader); serd_env_free(env); serd_sink_free(sink); @@ -575,6 +651,8 @@ main(void) char* const ttl_path = zix_path_join(NULL, dir, "serd_test_reader.ttl"); char* const nq_path = zix_path_join(NULL, dir, "serd_test_reader.nq"); + test_new_failed_alloc(); + test_start_failed_alloc(ttl_path); test_read_nquads_chunks(nq_path); test_read_turtle_chunks(ttl_path); test_prepare_error(ttl_path); diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c index 55c4b584..d6a2675d 100644 --- a/test/test_reader_writer.c +++ b/test/test_reader_writer.c @@ -97,7 +97,7 @@ faulty_sink(const void* const buf, static void test_write_errors(void) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); ErrorContext ctx = {0U, 0U}; const size_t max_offsets[] = {0, 368, 1900, 1992, 413}; @@ -109,7 +109,7 @@ test_write_errors(void) ctx.n_written = 0; ctx.error_offset = o; - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); SerdOutputStream out = serd_open_output_stream(faulty_sink, NULL, NULL, &ctx); @@ -141,8 +141,8 @@ test_write_errors(void) static void test_writer(const char* const path) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); SerdOutputStream output = serd_open_output_file(path); @@ -154,7 +154,7 @@ test_writer(const char* const path) serd_writer_chop_blank_prefix(writer, "tmp"); serd_writer_chop_blank_prefix(writer, NULL); - SerdNode* lit = serd_new_string(serd_string("hello")); + SerdNode* lit = serd_new_string(NULL, serd_string("hello")); const SerdSink* const iface = serd_writer_sink(writer); assert(serd_sink_write_base(iface, lit)); @@ -164,9 +164,9 @@ test_writer(const char* const path) static const uint8_t bad_buf[] = {0xEF, 0xBF, 0xBD, 0}; const SerdStringView bad_buf_view = {(const char*)bad_buf, 3}; - SerdNode* s = serd_new_uri(serd_string("http://example.org")); - SerdNode* p = serd_new_uri(serd_string("http://example.org/pred")); - SerdNode* bad = serd_new_string(bad_buf_view); + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org")); + SerdNode* p = serd_new_uri(NULL, serd_string("http://example.org/pred")); + SerdNode* bad = serd_new_string(NULL, bad_buf_view); // Write 3 invalid statements (should write nothing) const SerdNode* junk[][3] = {{s, bad, bad}, {bad, p, bad}, {s, bad, p}}; @@ -174,17 +174,18 @@ test_writer(const char* const path) assert(serd_sink_write(iface, 0, junk[i][0], junk[i][1], junk[i][2], NULL)); } - serd_node_free(bad); + serd_node_free(NULL, bad); const SerdStringView urn_Type = serd_string("urn:Type"); const SerdStringView en = serd_string("en"); - SerdNode* const o = serd_new_string(serd_string("o")); + SerdNode* const o = serd_new_string(NULL, serd_string("o")); SerdNode* const t = - serd_new_literal(serd_string("t"), SERD_HAS_DATATYPE, urn_Type); + serd_new_literal(NULL, serd_string("t"), SERD_HAS_DATATYPE, urn_Type); - SerdNode* const l = serd_new_literal(serd_string("l"), SERD_HAS_LANGUAGE, en); + SerdNode* const l = + serd_new_literal(NULL, serd_string("l"), SERD_HAS_LANGUAGE, en); const SerdNode* good[][3] = {{s, p, o}, {s, p, t}, {s, p, l}}; @@ -199,46 +200,47 @@ test_writer(const char* const path) static const char* const bad_uri_str = (const char*)bad_uri_buf; // Write statements with bad UTF-8 (should be replaced) - SerdNode* bad_lit = serd_new_string(serd_string(bad_lit_str)); - SerdNode* bad_uri = serd_new_uri(serd_string(bad_uri_str)); + SerdNode* bad_lit = serd_new_string(NULL, serd_string(bad_lit_str)); + SerdNode* bad_uri = serd_new_uri(NULL, serd_string(bad_uri_str)); assert(!serd_sink_write(iface, 0, s, p, bad_lit, 0)); assert(!serd_sink_write(iface, 0, s, p, bad_uri, 0)); - serd_node_free(bad_uri); - serd_node_free(bad_lit); + serd_node_free(NULL, bad_uri); + serd_node_free(NULL, bad_lit); // Write 1 valid statement - SerdNode* const hello = serd_new_string(serd_string("hello")); + SerdNode* const hello = serd_new_string(NULL, serd_string("hello")); assert(!serd_sink_write(iface, 0, s, p, hello, 0)); - serd_node_free(hello); + serd_node_free(NULL, hello); serd_writer_free(writer); serd_close_output(&output); - serd_node_free(lit); - serd_node_free(o); - serd_node_free(t); - serd_node_free(l); + serd_node_free(NULL, lit); + serd_node_free(NULL, o); + serd_node_free(NULL, t); + serd_node_free(NULL, l); // Test buffer sink - SerdBuffer buffer = {NULL, 0}; - SerdNode* const base = serd_new_uri(serd_string("http://example.org/base")); + SerdBuffer buffer = {NULL, NULL, 0}; + SerdNode* const base = + serd_new_uri(NULL, serd_string("http://example.org/base")); output = serd_open_output_buffer(&buffer); writer = serd_writer_new(world, SERD_TURTLE, 0, env, &output, 1U); serd_sink_write_base(serd_writer_sink(writer), base); - serd_node_free(base); + serd_node_free(NULL, base); serd_writer_free(writer); serd_close_output(&output); char* const out = (char*)buffer.buf; assert(out); assert(!strcmp(out, "@base <http://example.org/base> .\n")); - serd_free(out); + serd_free(NULL, buffer.buf); - serd_node_free(p); - serd_node_free(s); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_env_free(env); serd_world_free(world); @@ -247,12 +249,12 @@ test_writer(const char* const path) static void test_reader(const char* path) { - SerdWorld* world = serd_world_new(); - ReaderTest rt = {0}; - SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL); + SerdWorld* const world = serd_world_new(NULL); + ReaderTest rt = {0}; + SerdSink* const sink = serd_sink_new(NULL, &rt, test_sink, NULL); assert(sink); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); assert(env); // Test that too little stack space fails gracefully diff --git a/test/test_sink.c b/test/test_sink.c index b0756fcc..9c7959de 100644 --- a/test/test_sink.c +++ b/test/test_sink.c @@ -1,8 +1,10 @@ -// Copyright 2019-2020 David Robillard <d@drobilla.net> +// Copyright 2019-2021 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #undef NDEBUG +#include "failing_allocator.h" + #include "serd/env.h" #include "serd/event.h" #include "serd/node.h" @@ -88,17 +90,36 @@ on_event(void* const handle, const SerdEvent* const event) } static void +test_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + // Successfully allocate a sink to count the number of allocations + SerdSink* const sink = serd_sink_new(&allocator.base, NULL, NULL, NULL); + assert(sink); + + // Test that each allocation failing is handled gracefully + const size_t n_allocs = allocator.n_allocations; + for (size_t i = 0; i < n_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_sink_new(&allocator.base, NULL, NULL, NULL)); + } + + serd_sink_free(sink); +} + +static void test_callbacks(void) { - SerdNode* const base = serd_new_uri(serd_string(NS_EG)); - SerdNode* const name = serd_new_string(serd_string("eg")); - SerdNode* const uri = serd_new_uri(serd_string(NS_EG "uri")); - SerdNode* const blank = serd_new_blank(serd_string("b1")); - SerdEnv* env = serd_env_new(serd_node_string_view(base)); + SerdNode* const base = serd_new_uri(NULL, serd_string(NS_EG)); + SerdNode* const name = serd_new_string(NULL, serd_string("eg")); + SerdNode* const uri = serd_new_uri(NULL, serd_string(NS_EG "uri")); + SerdNode* const blank = serd_new_blank(NULL, serd_string("b1")); + SerdEnv* env = serd_env_new(NULL, serd_node_string_view(base)); State state = {0, 0, 0, 0, 0, SERD_SUCCESS}; SerdStatement* const statement = - serd_statement_new(base, uri, blank, NULL, NULL); + serd_statement_new(NULL, base, uri, blank, NULL, NULL); const SerdBaseEvent base_event = {SERD_BASE, uri}; const SerdPrefixEvent prefix_event = {SERD_PREFIX, name, uri}; @@ -107,7 +128,7 @@ test_callbacks(void) // Call functions on a sink with no functions set - SerdSink* null_sink = serd_sink_new(&state, NULL, NULL); + SerdSink* null_sink = serd_sink_new(NULL, &state, NULL, NULL); assert(!serd_sink_write_base(null_sink, base)); assert(!serd_sink_write_prefix(null_sink, name, uri)); @@ -130,7 +151,7 @@ test_callbacks(void) // Try again with a sink that has the event handler set - SerdSink* sink = serd_sink_new(&state, on_event, NULL); + SerdSink* sink = serd_sink_new(NULL, &state, on_event, NULL); assert(!serd_sink_write_base(sink, base)); assert(serd_node_equals(state.last_base, base)); @@ -150,12 +171,12 @@ test_callbacks(void) serd_sink_free(sink); - serd_statement_free(statement); + serd_statement_free(NULL, statement); serd_env_free(env); - serd_node_free(blank); - serd_node_free(uri); - serd_node_free(name); - serd_node_free(base); + serd_node_free(NULL, blank); + serd_node_free(NULL, uri); + serd_node_free(NULL, name); + serd_node_free(NULL, base); } static void @@ -166,7 +187,7 @@ test_free(void) // Set up a sink with dynamically allocated data and a free function uintptr_t* data = (uintptr_t*)calloc(1, sizeof(uintptr_t)); - SerdSink* sink = serd_sink_new(data, NULL, free); + SerdSink* sink = serd_sink_new(NULL, data, NULL, free); // Free the sink, which should free the data (rely on valgrind or sanitizers) serd_sink_free(sink); @@ -175,6 +196,7 @@ test_free(void) int main(void) { + test_failed_alloc(); test_callbacks(); test_free(); return 0; diff --git a/test/test_statement.c b/test/test_statement.c index d70542f1..0127b7bf 100644 --- a/test/test_statement.c +++ b/test/test_statement.c @@ -16,67 +16,67 @@ static void test_new(void) { - SerdNode* const u = serd_new_uri(serd_string(NS_EG "s")); - SerdNode* const b = serd_new_blank(serd_string("b0")); - SerdNode* const l = serd_new_string(serd_string("str")); - - assert(!serd_statement_new(u, b, u, NULL, NULL)); - assert(!serd_statement_new(l, u, u, NULL, NULL)); - assert(!serd_statement_new(l, u, b, u, NULL)); - assert(!serd_statement_new(u, l, b, NULL, NULL)); - assert(!serd_statement_new(u, l, b, u, NULL)); - assert(!serd_statement_new(u, u, u, l, NULL)); - - serd_node_free(l); - serd_node_free(b); - serd_node_free(u); + SerdNode* const u = serd_new_uri(NULL, serd_string(NS_EG "s")); + SerdNode* const b = serd_new_blank(NULL, serd_string("b0")); + SerdNode* const l = serd_new_string(NULL, serd_string("str")); + + assert(!serd_statement_new(NULL, u, b, u, NULL, NULL)); + assert(!serd_statement_new(NULL, l, u, u, NULL, NULL)); + assert(!serd_statement_new(NULL, l, u, b, u, NULL)); + assert(!serd_statement_new(NULL, u, l, b, NULL, NULL)); + assert(!serd_statement_new(NULL, u, l, b, u, NULL)); + assert(!serd_statement_new(NULL, u, u, u, l, NULL)); + + serd_node_free(NULL, l); + serd_node_free(NULL, b); + serd_node_free(NULL, u); } static void test_copy(void) { - assert(!serd_statement_copy(NULL)); + assert(!serd_statement_copy(NULL, NULL)); - SerdNode* const f = serd_new_string(serd_string("file")); - SerdNode* const s = serd_new_uri(serd_string(NS_EG "s")); - SerdNode* const p = serd_new_uri(serd_string(NS_EG "p")); - SerdNode* const o = serd_new_uri(serd_string(NS_EG "o")); - SerdNode* const g = serd_new_uri(serd_string(NS_EG "g")); + SerdNode* const f = serd_new_string(NULL, serd_string("file")); + SerdNode* const s = serd_new_uri(NULL, serd_string(NS_EG "s")); + SerdNode* const p = serd_new_uri(NULL, serd_string(NS_EG "p")); + SerdNode* const o = serd_new_uri(NULL, serd_string(NS_EG "o")); + SerdNode* const g = serd_new_uri(NULL, serd_string(NS_EG "g")); - SerdCaret* const caret = serd_caret_new(f, 1, 1); - SerdStatement* const statement = serd_statement_new(s, p, o, g, caret); - SerdStatement* const copy = serd_statement_copy(statement); + SerdCaret* const caret = serd_caret_new(NULL, f, 1, 1); + SerdStatement* const statement = serd_statement_new(NULL, s, p, o, g, caret); + SerdStatement* const copy = serd_statement_copy(NULL, statement); assert(serd_statement_equals(copy, statement)); assert(serd_caret_equals(serd_statement_caret(copy), caret)); - serd_statement_free(copy); - serd_caret_free(caret); - serd_statement_free(statement); - serd_node_free(g); - serd_node_free(o); - serd_node_free(p); - serd_node_free(s); - serd_node_free(f); + serd_statement_free(NULL, copy); + serd_caret_free(NULL, caret); + serd_statement_free(NULL, statement); + serd_node_free(NULL, g); + serd_node_free(NULL, o); + serd_node_free(NULL, p); + serd_node_free(NULL, s); + serd_node_free(NULL, f); } static void test_free(void) { - serd_statement_free(NULL); + serd_statement_free(NULL, NULL); } static void test_fields(void) { - SerdNode* const f = serd_new_string(serd_string("file")); - SerdNode* const s = serd_new_uri(serd_string(NS_EG "s")); - SerdNode* const p = serd_new_uri(serd_string(NS_EG "p")); - SerdNode* const o = serd_new_uri(serd_string(NS_EG "o")); - SerdNode* const g = serd_new_uri(serd_string(NS_EG "g")); + SerdNode* const f = serd_new_string(NULL, serd_string("file")); + SerdNode* const s = serd_new_uri(NULL, serd_string(NS_EG "s")); + SerdNode* const p = serd_new_uri(NULL, serd_string(NS_EG "p")); + SerdNode* const o = serd_new_uri(NULL, serd_string(NS_EG "o")); + SerdNode* const g = serd_new_uri(NULL, serd_string(NS_EG "g")); - SerdCaret* const caret = serd_caret_new(f, 1, 1); - SerdStatement* const statement = serd_statement_new(s, p, o, g, caret); + SerdCaret* const caret = serd_caret_new(NULL, f, 1, 1); + SerdStatement* const statement = serd_statement_new(NULL, s, p, o, g, caret); assert(serd_statement_equals(statement, statement)); assert(!serd_statement_equals(statement, NULL)); @@ -103,29 +103,29 @@ test_fields(void) assert(!serd_statement_matches(statement, NULL, NULL, s, NULL)); assert(!serd_statement_matches(statement, NULL, NULL, NULL, s)); - SerdStatement* const diff_s = serd_statement_new(o, p, o, g, caret); + SerdStatement* const diff_s = serd_statement_new(NULL, o, p, o, g, caret); assert(!serd_statement_equals(statement, diff_s)); - serd_statement_free(diff_s); + serd_statement_free(NULL, diff_s); - SerdStatement* const diff_p = serd_statement_new(s, o, o, g, caret); + SerdStatement* const diff_p = serd_statement_new(NULL, s, o, o, g, caret); assert(!serd_statement_equals(statement, diff_p)); - serd_statement_free(diff_p); + serd_statement_free(NULL, diff_p); - SerdStatement* const diff_o = serd_statement_new(s, p, s, g, caret); + SerdStatement* const diff_o = serd_statement_new(NULL, s, p, s, g, caret); assert(!serd_statement_equals(statement, diff_o)); - serd_statement_free(diff_o); + serd_statement_free(NULL, diff_o); - SerdStatement* const diff_g = serd_statement_new(s, p, o, s, caret); + SerdStatement* const diff_g = serd_statement_new(NULL, s, p, o, s, caret); assert(!serd_statement_equals(statement, diff_g)); - serd_statement_free(diff_g); - - serd_statement_free(statement); - serd_caret_free(caret); - serd_node_free(g); - serd_node_free(o); - serd_node_free(p); - serd_node_free(s); - serd_node_free(f); + serd_statement_free(NULL, diff_g); + + serd_statement_free(NULL, statement); + serd_caret_free(NULL, caret); + serd_node_free(NULL, g); + serd_node_free(NULL, o); + serd_node_free(NULL, p); + serd_node_free(NULL, s); + serd_node_free(NULL, f); } int diff --git a/test/test_terse_write.c b/test/test_terse_write.c index 39e3767a..0bdb0280 100644 --- a/test/test_terse_write.c +++ b/test/test_terse_write.c @@ -5,6 +5,7 @@ #include "serd/buffer.h" #include "serd/env.h" +#include "serd/memory.h" #include "serd/node.h" #include "serd/output_stream.h" #include "serd/sink.h" @@ -16,7 +17,6 @@ #include <assert.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" @@ -39,20 +39,20 @@ check_output(SerdWriter* writer, SerdBuffer* buffer, const char* expected) static int test(void) { - SerdBuffer buffer = {NULL, 0}; - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); + SerdBuffer buffer = {NULL, NULL, 0}; + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); - SerdNode* b1 = serd_new_blank(serd_string("b1")); - SerdNode* l1 = serd_new_blank(serd_string("l1")); - SerdNode* l2 = serd_new_blank(serd_string("l2")); - SerdNode* s1 = serd_new_string(serd_string("s1")); - SerdNode* s2 = serd_new_string(serd_string("s2")); + SerdNode* b1 = serd_new_blank(NULL, serd_string("b1")); + SerdNode* l1 = serd_new_blank(NULL, serd_string("l1")); + SerdNode* l2 = serd_new_blank(NULL, serd_string("l2")); + SerdNode* s1 = serd_new_string(NULL, serd_string("s1")); + SerdNode* s2 = serd_new_string(NULL, serd_string("s2")); - SerdNode* rdf_first = serd_new_uri(serd_string(NS_RDF "first")); - SerdNode* rdf_value = serd_new_uri(serd_string(NS_RDF "value")); - SerdNode* rdf_rest = serd_new_uri(serd_string(NS_RDF "rest")); - SerdNode* rdf_nil = serd_new_uri(serd_string(NS_RDF "nil")); + SerdNode* rdf_first = serd_new_uri(NULL, serd_string(NS_RDF "first")); + SerdNode* rdf_value = serd_new_uri(NULL, serd_string(NS_RDF "value")); + SerdNode* rdf_rest = serd_new_uri(NULL, serd_string(NS_RDF "rest")); + SerdNode* rdf_nil = serd_new_uri(NULL, serd_string(NS_RDF "nil")); serd_env_set_prefix(env, serd_string("rdf"), serd_string(NS_RDF)); @@ -91,19 +91,19 @@ test(void) check_output(writer, &buffer, "[] rdf:value ( \"s1\" \"s2\" ) .\n"); serd_writer_free(writer); - serd_node_free(rdf_nil); - serd_node_free(rdf_rest); - serd_node_free(rdf_value); - serd_node_free(rdf_first); - serd_node_free(s2); - serd_node_free(s1); - serd_node_free(l2); - serd_node_free(l1); - serd_node_free(b1); + serd_node_free(NULL, rdf_nil); + serd_node_free(NULL, rdf_rest); + serd_node_free(NULL, rdf_value); + serd_node_free(NULL, rdf_first); + serd_node_free(NULL, s2); + serd_node_free(NULL, s1); + serd_node_free(NULL, l2); + serd_node_free(NULL, l1); + serd_node_free(NULL, b1); serd_close_output(&output); + serd_free(NULL, buffer.buf); serd_env_free(env); serd_world_free(world); - free(buffer.buf); return 0; } diff --git a/test/test_uri.c b/test/test_uri.c index 74b732fd..79d3f73e 100644 --- a/test/test_uri.c +++ b/test/test_uri.c @@ -3,6 +3,8 @@ #undef NDEBUG +#include "failing_allocator.h" + #include "serd/memory.h" #include "serd/node.h" #include "serd/string_view.h" @@ -14,6 +16,35 @@ #include <string.h> static void +test_file_uri_failed_alloc(void) +{ + static const char* const string = "file://host/path/spacey%20dir/100%%.ttl"; + + SerdFailingAllocator allocator = serd_failing_allocator(); + + // Successfully parse a URI to count the number of allocations + char* hostname = NULL; + char* path = serd_parse_file_uri(&allocator.base, string, &hostname); + + assert(!strcmp(path, "/path/spacey dir/100%.ttl")); + assert(!strcmp(hostname, "host")); + serd_free(&allocator.base, path); + serd_free(&allocator.base, hostname); + + // Test that each allocation failing is handled gracefully + const size_t n_allocs = allocator.n_allocations; + for (size_t i = 0; i < n_allocs; ++i) { + allocator.n_remaining = i; + + path = serd_parse_file_uri(&allocator.base, string, &hostname); + assert(!path || !hostname); + + serd_free(&allocator.base, path); + serd_free(&allocator.base, hostname); + } +} + +static void test_uri_string_has_scheme(void) { assert(!serd_uri_string_has_scheme("relative")); @@ -44,19 +75,21 @@ test_file_uri(const char* const hostname, expected_path = path; } - SerdNode* node = serd_new_file_uri(serd_string(path), serd_string(hostname)); + SerdNode* node = + serd_new_file_uri(NULL, serd_string(path), serd_string(hostname)); const char* node_str = serd_node_string(node); char* out_hostname = NULL; - char* out_path = serd_parse_file_uri(node_str, &out_hostname); + char* const out_path = serd_parse_file_uri(NULL, node_str, &out_hostname); + assert(!strcmp(node_str, expected_uri)); assert((hostname && out_hostname) || (!hostname && !out_hostname)); assert(!hostname || !strcmp(hostname, out_hostname)); assert(!strcmp(out_path, expected_path)); - serd_free(out_path); - serd_free(out_hostname); - serd_node_free(node); + serd_free(NULL, out_path); + serd_free(NULL, out_hostname); + serd_node_free(NULL, node); } static void @@ -107,22 +140,22 @@ test_uri_parsing(void) #endif // Missing trailing '/' after authority - assert(!serd_parse_file_uri("file://truncated", NULL)); + assert(!serd_parse_file_uri(NULL, "file://truncated", NULL)); // Check that NULL hostname doesn't crash - char* out_path = serd_parse_file_uri("file://me/path", NULL); + char* out_path = serd_parse_file_uri(NULL, "file://me/path", NULL); assert(!strcmp(out_path, "/path")); - serd_free(out_path); + serd_free(NULL, out_path); // Invalid first escape character - out_path = serd_parse_file_uri("file:///foo/%0Xbar", NULL); + out_path = serd_parse_file_uri(NULL, "file:///foo/%0Xbar", NULL); assert(!strcmp(out_path, "/foo/bar")); - serd_free(out_path); + serd_free(NULL, out_path); // Invalid second escape character - out_path = serd_parse_file_uri("file:///foo/%X0bar", NULL); + out_path = serd_parse_file_uri(NULL, "file:///foo/%X0bar", NULL); assert(!strcmp(out_path, "/foo/bar")); - serd_free(out_path); + serd_free(NULL, out_path); } static void @@ -134,12 +167,12 @@ test_parse_uri(void) const SerdURIView empty_uri = serd_parse_uri(""); SerdNode* const nil = - serd_new_parsed_uri(serd_resolve_uri(empty_uri, base_uri)); + serd_new_parsed_uri(NULL, serd_resolve_uri(empty_uri, base_uri)); assert(serd_node_type(nil) == SERD_URI); assert(!strcmp(serd_node_string(nil), base.data)); - serd_node_free(nil); + serd_node_free(NULL, nil); } static void @@ -194,22 +227,22 @@ check_relative_uri(const char* const uri_string, assert(base_string); assert(expected_string); - SerdNode* const uri_node = serd_new_uri(serd_string(uri_string)); + SerdNode* const uri_node = serd_new_uri(NULL, serd_string(uri_string)); const SerdURIView uri = serd_node_uri_view(uri_node); - SerdNode* const base_node = serd_new_uri(serd_string(base_string)); + SerdNode* const base_node = serd_new_uri(NULL, serd_string(base_string)); const SerdURIView base = serd_node_uri_view(base_node); SerdNode* result_node = NULL; if (!root_string) { - result_node = serd_new_parsed_uri(serd_relative_uri(uri, base)); + result_node = serd_new_parsed_uri(NULL, serd_relative_uri(uri, base)); } else { - SerdNode* const root_node = serd_new_uri(serd_string(root_string)); + SerdNode* const root_node = serd_new_uri(NULL, serd_string(root_string)); const SerdURIView root = serd_node_uri_view(root_node); result_node = serd_uri_is_within(uri, root) - ? serd_new_parsed_uri(serd_relative_uri(uri, base)) - : serd_new_uri(serd_string(uri_string)); - serd_node_free(root_node); + ? serd_new_parsed_uri(NULL, serd_relative_uri(uri, base)) + : serd_new_uri(NULL, serd_string(uri_string)); + serd_node_free(NULL, root_node); } assert(!strcmp(serd_node_string(result_node), expected_string)); @@ -223,9 +256,9 @@ check_relative_uri(const char* const uri_string, assert(chunk_equals(&result.query, &expected.query)); assert(chunk_equals(&result.fragment, &expected.fragment)); - serd_node_free(result_node); - serd_node_free(base_node); - serd_node_free(uri_node); + serd_node_free(NULL, result_node); + serd_node_free(NULL, base_node); + serd_node_free(NULL, uri_node); } static void @@ -326,9 +359,9 @@ test_relative_uri(void) static void check_uri_string(const SerdURIView uri, const char* const expected) { - SerdNode* const node = serd_new_parsed_uri(uri); + SerdNode* const node = serd_new_parsed_uri(NULL, uri); assert(!strcmp(serd_node_string(node), expected)); - serd_node_free(node); + serd_node_free(NULL, node); } static void @@ -379,6 +412,7 @@ test_uri_resolution(void) int main(void) { + test_file_uri_failed_alloc(); test_uri_string_has_scheme(); test_uri_parsing(); test_parse_uri(); diff --git a/test/test_world.c b/test/test_world.c index 3f7f6ea6..7ff20143 100644 --- a/test/test_world.c +++ b/test/test_world.c @@ -3,6 +3,8 @@ #undef NDEBUG +#include "failing_allocator.h" + #include "serd/node.h" #include "serd/world.h" @@ -11,9 +13,28 @@ #include <string.h> static void +test_new_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + // Successfully allocate a world to count the number of allocations + SerdWorld* const world = serd_world_new(&allocator.base); + assert(world); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations; + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_world_new(&allocator.base)); + } + + serd_world_free(world); +} + +static void test_get_blank(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); char expected[12]; for (unsigned i = 0; i < 32; ++i) { @@ -29,6 +50,7 @@ test_get_blank(void) int main(void) { + test_new_failed_alloc(); test_get_blank(); return 0; diff --git a/test/test_writer.c b/test/test_writer.c index 47350031..39bcd34a 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -3,6 +3,8 @@ #undef NDEBUG +#include "failing_allocator.h" + #include "serd/buffer.h" #include "serd/env.h" #include "serd/event.h" @@ -26,23 +28,112 @@ static void test_writer_new(void) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); - SerdBuffer buffer = {NULL, 0}; + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); assert(!serd_writer_new(world, SERD_TURTLE, 0U, env, &output, 0U)); + serd_env_free(env); serd_world_free(world); +} + +static void +test_new_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdWorld* const world = serd_world_new(&allocator.base); + SerdEnv* env = serd_env_new(&allocator.base, serd_empty_string()); + SerdBuffer buffer = {&allocator.base, NULL, 0}; + SerdOutputStream output = serd_open_output_buffer(&buffer); + const size_t n_world_allocs = allocator.n_allocations; + + // Successfully allocate a writer to count the number of allocations + SerdWriter* const writer = + serd_writer_new(world, SERD_TURTLE, 0U, env, &output, 1U); + + assert(writer); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations - n_world_allocs; + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_writer_new(world, SERD_TURTLE, 0U, env, &output, 1U)); + } + + serd_writer_free(writer); serd_env_free(env); + serd_world_free(world); +} + +static void +test_write_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdWorld* world = serd_world_new(&allocator.base); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); + SerdBuffer buffer = {&allocator.base, NULL, 0}; + SerdOutputStream output = serd_open_output_buffer(&buffer); + + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* p1 = serd_new_uri(NULL, serd_string("http://example.org/p")); + + SerdNode* p2 = serd_new_uri( + NULL, serd_string("http://example.org/dramatically/longer/predicate")); + + SerdNode* o = serd_new_token(NULL, SERD_BLANK, serd_string("o")); + + const size_t n_setup_allocs = allocator.n_allocations; + + // Successfully write a statement to count the number of allocations + SerdWriter* writer = + serd_writer_new(world, SERD_TURTLE, 0U, env, &output, 1U); + const SerdSink* sink = serd_writer_sink(writer); + assert(writer); + assert(sink); + assert(!serd_sink_write(sink, 0U, s, p1, o, NULL)); + assert(!serd_sink_write(sink, 0U, s, p2, o, NULL)); + const size_t n_new_allocs = allocator.n_allocations - n_setup_allocs; + + serd_writer_free(writer); + + // Test that each allocation failing is handled gracefully + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + + if ((writer = serd_writer_new(world, SERD_TURTLE, 0U, env, &output, 1U))) { + sink = serd_writer_sink(writer); + + const SerdStatus st1 = serd_sink_write(sink, 0U, s, p1, o, NULL); + const SerdStatus st2 = serd_sink_write(sink, 0U, s, p2, o, NULL); + + assert(st1 == SERD_BAD_ALLOC || st1 == SERD_BAD_WRITE || + st2 == SERD_BAD_ALLOC || st2 == SERD_BAD_WRITE); + + serd_writer_free(writer); + } + } + + serd_close_output(&output); + serd_env_free(env); + serd_buffer_close(&buffer); + serd_free(NULL, buffer.buf); + serd_node_free(NULL, o); + serd_node_free(NULL, p2); + serd_node_free(NULL, p1); + serd_node_free(NULL, s); + serd_world_free(world); } static void test_write_bad_event(void) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); - SerdBuffer buffer = {NULL, 0}; + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = @@ -58,7 +149,7 @@ test_write_bad_event(void) char* const out = (char*)buffer.buf; assert(out); assert(!strcmp(out, "")); - serd_free(out); + serd_free(NULL, buffer.buf); serd_writer_free(writer); serd_env_free(env); @@ -68,26 +159,28 @@ test_write_bad_event(void) static void test_write_long_literal(void) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); - SerdBuffer buffer = {NULL, 0}; + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0U, env, &output, 1U); assert(writer); - SerdNode* s = serd_new_uri(serd_string("http://example.org/s")); - SerdNode* p = serd_new_uri(serd_string("http://example.org/p")); - SerdNode* o = serd_new_literal( - serd_string("hello \"\"\"world\"\"\"!"), SERD_IS_LONG, serd_empty_string()); + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* p = serd_new_uri(NULL, serd_string("http://example.org/p")); + SerdNode* o = serd_new_literal(NULL, + serd_string("hello \"\"\"world\"\"\"!"), + SERD_IS_LONG, + serd_empty_string()); assert(serd_node_flags(o) & SERD_IS_LONG); assert(!serd_sink_write(serd_writer_sink(writer), 0, s, p, o, NULL)); - serd_node_free(o); - serd_node_free(p); - serd_node_free(s); + serd_node_free(NULL, o); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_writer_free(writer); serd_close_output(&output); serd_env_free(env); @@ -100,7 +193,7 @@ test_write_long_literal(void) "\t<http://example.org/p> \"\"\"hello \"\"\\\"world\"\"\\\"!\"\"\" .\n"; assert(!strcmp(out, expected)); - serd_free(out); + serd_free(NULL, buffer.buf); serd_world_free(world); } @@ -121,8 +214,8 @@ static void test_writer_cleanup(void) { SerdStatus st = SERD_SUCCESS; - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); SerdOutputStream output = serd_open_output_stream(null_sink, NULL, NULL, NULL); @@ -131,9 +224,9 @@ test_writer_cleanup(void) const SerdSink* sink = serd_writer_sink(writer); - SerdNode* s = serd_new_uri(serd_string("http://example.org/s")); - SerdNode* p = serd_new_uri(serd_string("http://example.org/p")); - SerdNode* o = serd_new_blank(serd_string("start")); + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* p = serd_new_uri(NULL, serd_string("http://example.org/p")); + SerdNode* o = serd_new_blank(NULL, serd_string("start")); st = serd_sink_write(sink, SERD_ANON_O, s, p, o, NULL); assert(!st); @@ -143,11 +236,11 @@ test_writer_cleanup(void) char buf[12] = {0}; snprintf(buf, sizeof(buf), "b%u", i); - SerdNode* next_o = serd_new_blank(serd_string(buf)); + SerdNode* next_o = serd_new_blank(NULL, serd_string(buf)); st = serd_sink_write(sink, SERD_ANON_O, o, p, next_o, NULL); - serd_node_free(o); + serd_node_free(NULL, o); o = next_o; } @@ -155,14 +248,14 @@ test_writer_cleanup(void) assert(!(st = serd_writer_finish(writer))); // Set the base to an empty URI - SerdNode* empty_uri = serd_new_uri(serd_string("")); + SerdNode* empty_uri = serd_new_uri(NULL, serd_string("")); assert(!(st = serd_sink_write_base(sink, empty_uri))); - serd_node_free(empty_uri); + serd_node_free(NULL, empty_uri); // Free (which could leak if the writer doesn't clean up the stack properly) - serd_node_free(o); - serd_node_free(p); - serd_node_free(s); + serd_node_free(NULL, o); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_writer_free(writer); serd_env_free(env); serd_world_free(world); @@ -175,8 +268,8 @@ test_strict_write(void) FILE* const fd = fopen(path, "wb"); assert(fd); - SerdWorld* world = serd_world_new(); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdWorld* world = serd_world_new(NULL); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); SerdOutputStream out = serd_open_output_stream(null_sink, NULL, NULL, fd); SerdWriter* const writer = serd_writer_new(world, SERD_TURTLE, 0U, env, &out, 1U); @@ -187,19 +280,19 @@ test_strict_write(void) const uint8_t bad_str[] = {0xFF, 0x90, 'h', 'i', 0}; - SerdNode* s = serd_new_uri(serd_string("http://example.org/s")); - SerdNode* p = serd_new_uri(serd_string("http://example.org/p")); + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* p = serd_new_uri(NULL, serd_string("http://example.org/p")); - SerdNode* bad_lit = serd_new_string(serd_string((const char*)bad_str)); - SerdNode* bad_uri = serd_new_uri(serd_string((const char*)bad_str)); + SerdNode* bad_lit = serd_new_string(NULL, serd_string((const char*)bad_str)); + SerdNode* bad_uri = serd_new_uri(NULL, serd_string((const char*)bad_str)); assert(serd_sink_write(sink, 0, s, p, bad_lit, NULL) == SERD_BAD_TEXT); assert(serd_sink_write(sink, 0, s, p, bad_uri, NULL) == SERD_BAD_TEXT); - serd_node_free(bad_uri); - serd_node_free(bad_lit); - serd_node_free(p); - serd_node_free(s); + serd_node_free(NULL, bad_uri); + serd_node_free(NULL, bad_lit); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_writer_free(writer); serd_env_free(env); serd_world_free(world); @@ -224,15 +317,14 @@ error_sink(const void* const buf, static void test_write_error(void) { - SerdWorld* const world = serd_world_new(); - SerdEnv* const env = serd_env_new(serd_empty_string()); + SerdWorld* const world = serd_world_new(NULL); + SerdEnv* const env = serd_env_new(NULL, serd_empty_string()); SerdOutputStream out = serd_open_output_stream(error_sink, NULL, NULL, NULL); - SerdWriter* writer = NULL; - SerdStatus st = SERD_SUCCESS; + SerdStatus st = SERD_SUCCESS; - SerdNode* u = serd_new_uri(serd_string("http://example.com/u")); + SerdNode* u = serd_new_uri(NULL, serd_string("http://example.com/u")); - writer = + SerdWriter* const writer = serd_writer_new(world, SERD_TURTLE, (SerdWriterFlags)0, env, &out, 1U); assert(writer); @@ -242,7 +334,7 @@ test_write_error(void) assert(st == SERD_BAD_WRITE); serd_writer_free(writer); - serd_node_free(u); + serd_node_free(NULL, u); serd_env_free(env); serd_world_free(world); } @@ -250,8 +342,8 @@ test_write_error(void) static void test_writer_stack_overflow(void) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); SerdOutputStream output = serd_open_output_stream(null_sink, NULL, NULL, NULL); @@ -261,10 +353,10 @@ test_writer_stack_overflow(void) const SerdSink* sink = serd_writer_sink(writer); - SerdNode* const s = serd_new_uri(serd_string("http://example.org/s")); - SerdNode* const p = serd_new_uri(serd_string("http://example.org/p")); + SerdNode* const s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* const p = serd_new_uri(NULL, serd_string("http://example.org/p")); - SerdNode* o = serd_new_blank(serd_string("blank")); + SerdNode* o = serd_new_blank(NULL, serd_string("blank")); SerdStatus st = serd_sink_write(sink, SERD_ANON_O, s, p, o, NULL); assert(!st); @@ -273,11 +365,11 @@ test_writer_stack_overflow(void) char buf[1024]; snprintf(buf, sizeof(buf), "b%u", i); - SerdNode* next_o = serd_new_blank(serd_string(buf)); + SerdNode* next_o = serd_new_blank(NULL, serd_string(buf)); st = serd_sink_write(sink, SERD_ANON_O, o, p, next_o, NULL); - serd_node_free(o); + serd_node_free(NULL, o); o = next_o; if (st) { @@ -288,9 +380,9 @@ test_writer_stack_overflow(void) assert(st == SERD_BAD_STACK); - serd_node_free(o); - serd_node_free(p); - serd_node_free(s); + serd_node_free(NULL, o); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_writer_free(writer); serd_close_output(&output); serd_env_free(env); @@ -300,14 +392,14 @@ test_writer_stack_overflow(void) static void test_write_empty_syntax(void) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); - SerdNode* s = serd_new_uri(serd_string("http://example.org/s")); - SerdNode* p = serd_new_uri(serd_string("http://example.org/p")); - SerdNode* o = serd_new_uri(serd_string("http://example.org/o")); + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* p = serd_new_uri(NULL, serd_string("http://example.org/p")); + SerdNode* o = serd_new_uri(NULL, serd_string("http://example.org/o")); - SerdBuffer buffer = {NULL, 0}; + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = @@ -321,12 +413,12 @@ test_write_empty_syntax(void) char* const out = (char*)buffer.buf; assert(out); assert(strlen(out) == 0); - serd_free(out); + serd_free(NULL, buffer.buf); serd_writer_free(writer); - serd_node_free(o); - serd_node_free(p); - serd_node_free(s); + serd_node_free(NULL, o); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_close_output(&output); serd_env_free(env); serd_world_free(world); @@ -335,9 +427,9 @@ test_write_empty_syntax(void) static void check_pname_escape(const char* const lname, const char* const expected) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); - SerdBuffer buffer = {NULL, 0}; + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = @@ -349,20 +441,20 @@ check_pname_escape(const char* const lname, const char* const expected) serd_env_set_prefix(env, serd_string("eg"), serd_string(prefix)); - SerdNode* s = serd_new_uri(serd_string("http://example.org/s")); - SerdNode* p = serd_new_uri(serd_string("http://example.org/p")); + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* p = serd_new_uri(NULL, serd_string("http://example.org/p")); char* const uri = (char*)calloc(1, prefix_len + strlen(lname) + 1); memcpy(uri, prefix, prefix_len + 1); memcpy(uri + prefix_len, lname, strlen(lname) + 1); - SerdNode* node = serd_new_uri(serd_string(uri)); + SerdNode* node = serd_new_uri(NULL, serd_string(uri)); assert(!serd_sink_write(serd_writer_sink(writer), 0, s, p, node, NULL)); - serd_node_free(node); + serd_node_free(NULL, node); free(uri); - serd_node_free(p); - serd_node_free(s); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_writer_free(writer); serd_close_output(&output); serd_env_free(env); @@ -370,7 +462,7 @@ check_pname_escape(const char* const lname, const char* const expected) char* const out = (char*)buffer.buf; assert(!strcmp(out, expected)); - serd_free(out); + serd_free(NULL, buffer.buf); serd_world_free(world); } @@ -409,12 +501,13 @@ test_write_pname_escapes(void) static void test_write_bad_uri(void) { - SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(serd_empty_string()); - SerdNode* s = serd_new_uri(serd_string("http://example.org/s")); - SerdNode* p = serd_new_uri(serd_string("http://example.org/p")); - SerdNode* rel = serd_new_uri(serd_string("rel")); - SerdBuffer buffer = {NULL, 0}; + SerdWorld* world = serd_world_new(NULL); + SerdEnv* env = serd_env_new(NULL, serd_empty_string()); + SerdNode* s = serd_new_uri(NULL, serd_string("http://example.org/s")); + SerdNode* p = serd_new_uri(NULL, serd_string("http://example.org/p")); + SerdNode* rel = serd_new_uri(NULL, serd_string("rel")); + + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_NTRIPLES, 0U, env, &output, 1U); @@ -429,10 +522,10 @@ test_write_bad_uri(void) serd_writer_free(writer); serd_close_output(&output); - serd_free(buffer.buf); - serd_node_free(rel); - serd_node_free(p); - serd_node_free(s); + serd_free(NULL, buffer.buf); + serd_node_free(NULL, rel); + serd_node_free(NULL, p); + serd_node_free(NULL, s); serd_env_free(env); serd_world_free(world); } @@ -441,6 +534,8 @@ int main(void) { test_writer_new(); + test_new_failed_alloc(); + test_write_failed_alloc(); test_write_bad_event(); test_write_long_literal(); test_writer_cleanup(); |