aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-07-09 16:25:07 -0400
committerDavid Robillard <d@drobilla.net>2022-01-13 23:03:32 -0500
commitf3d7f3079a954d7c88c0af615bf0308fa40a062c (patch)
tree9e01d6bf8a9a1a5d91622f2d58b936bc9be8a8fa /test
parent5c90b6aff410bb4a9737680baffd79d10b5281fd (diff)
downloadserd-f3d7f3079a954d7c88c0af615bf0308fa40a062c.tar.gz
serd-f3d7f3079a954d7c88c0af615bf0308fa40a062c.tar.bz2
serd-f3d7f3079a954d7c88c0af615bf0308fa40a062c.zip
Handle writer stack overflows gracefully
Diffstat (limited to 'test')
-rw-r--r--test/test_writer.c56
1 files changed, 56 insertions, 0 deletions
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;
}