aboutsummaryrefslogtreecommitdiffstats
path: root/src
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 /src
parent5c90b6aff410bb4a9737680baffd79d10b5281fd (diff)
downloadserd-f3d7f3079a954d7c88c0af615bf0308fa40a062c.tar.gz
serd-f3d7f3079a954d7c88c0af615bf0308fa40a062c.tar.bz2
serd-f3d7f3079a954d7c88c0af615bf0308fa40a062c.zip
Handle writer stack overflows gracefully
Diffstat (limited to 'src')
-rw-r--r--src/writer.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/writer.c b/src/writer.c
index a2ba0482..b132dc83 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -501,11 +501,11 @@ reset_context(SerdWriter* writer, bool graph)
}
static SerdStatus
-free_context(SerdWriter* writer)
+free_context(const WriteContext* const ctx)
{
- serd_node_free(writer->context.graph);
- serd_node_free(writer->context.subject);
- serd_node_free(writer->context.predicate);
+ serd_node_free(ctx->graph);
+ serd_node_free(ctx->subject);
+ serd_node_free(ctx->predicate);
return SERD_SUCCESS;
}
@@ -888,6 +888,10 @@ serd_writer_write_statement(SerdWriter* const writer,
if (flags & (SERD_ANON_S_BEGIN | SERD_ANON_O_BEGIN)) {
WriteContext* ctx =
(WriteContext*)serd_stack_push(&writer->anon_stack, sizeof(WriteContext));
+ if (!ctx) {
+ return SERD_ERR_OVERFLOW;
+ }
+
*ctx = writer->context;
WriteContext new_context = {
serd_node_copy(graph), serd_node_copy(subject), NULL};
@@ -916,7 +920,7 @@ serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
}
--writer->indent;
write_sep(writer, SEP_ANON_END);
- free_context(writer);
+ free_context(&writer->context);
writer->context = *anon_stack_top(writer);
serd_stack_pop(&writer->anon_stack, sizeof(WriteContext));
const bool is_subject = serd_node_equals(node, writer->context.subject);
@@ -937,7 +941,7 @@ serd_writer_finish(SerdWriter* writer)
write_sep(writer, SEP_GRAPH_END);
}
serd_byte_sink_flush(&writer->byte_sink);
- free_context(writer);
+ free_context(&writer->context);
writer->indent = 0;
writer->context = WRITE_CONTEXT_NULL;
return SERD_SUCCESS;
@@ -958,7 +962,7 @@ serd_writer_new(SerdSyntax syntax,
writer->env = env;
writer->root_node = NULL;
writer->root_uri = SERD_URI_NULL;
- writer->anon_stack = serd_stack_new(4 * sizeof(WriteContext));
+ writer->anon_stack = serd_stack_new(SERD_PAGE_SIZE);
writer->context = context;
writer->list_subj = NULL;
writer->empty = true;
@@ -1077,6 +1081,13 @@ serd_writer_free(SerdWriter* writer)
}
serd_writer_finish(writer);
+
+ // Free any leaked entries in the anonymous context stack
+ while (!serd_stack_is_empty(&writer->anon_stack)) {
+ free_context(anon_stack_top(writer));
+ serd_stack_pop(&writer->anon_stack, sizeof(WriteContext));
+ }
+
serd_stack_free(&writer->anon_stack);
free(writer->bprefix);
serd_byte_sink_free(&writer->byte_sink);