From f3d7f3079a954d7c88c0af615bf0308fa40a062c Mon Sep 17 00:00:00 2001 From: David Robillard <d@drobilla.net> Date: Fri, 9 Jul 2021 16:25:07 -0400 Subject: Handle writer stack overflows gracefully --- test/test_writer.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'test') diff --git a/test/test_writer.c b/test/test_writer.c index 190995b6..19aaf4b3 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -19,6 +19,7 @@ #include "serd/serd.h" #include <assert.h> +#include <stdio.h> #include <string.h> static void @@ -82,11 +83,66 @@ test_write_long_literal(void) serd_free(out); } +static size_t +null_sink(const void* const buf, + const size_t size, + const size_t nmemb, + void* const stream) +{ + (void)buf; + (void)stream; + + return size * nmemb; +} + +static void +test_writer_stack_overflow(void) +{ + SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdWriter* writer = serd_writer_new(SERD_TURTLE, 0u, env, null_sink, NULL); + + 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* o = serd_new_blank(SERD_STRING("http://example.org/o")); + SerdStatus st = serd_sink_write(sink, SERD_ANON_O_BEGIN, s, p, o, NULL); + assert(!st); + + // Repeatedly write nested anonymous objects until the writer stack overflows + for (unsigned i = 0u; i < 512u; ++i) { + char buf[1024]; + snprintf(buf, sizeof(buf), "b%u", i); + + SerdNode* next_o = serd_new_blank(SERD_STRING(buf)); + + st = serd_sink_write(sink, SERD_ANON_O_BEGIN, o, p, next_o, NULL); + + serd_node_free(o); + o = next_o; + + if (st) { + assert(st == SERD_ERR_OVERFLOW); + break; + } + } + + assert(st == SERD_ERR_OVERFLOW); + + serd_node_free(o); + serd_node_free(p); + serd_node_free(s); + serd_writer_free(writer); + serd_env_free(env); +} + int main(void) { test_write_bad_prefix(); test_write_long_literal(); + test_writer_stack_overflow(); return 0; } -- cgit v1.2.1