diff options
author | David Robillard <d@drobilla.net> | 2021-02-20 16:50:11 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-12-02 16:27:02 -0500 |
commit | b16765b4830587c42db16587eda86f1eebb9a352 (patch) | |
tree | a1cc261786bbf0e06f59bad76a9fa11c5646d8d9 /src | |
parent | 8771f4611a37efbe2841abe6db06c662490bdd88 (diff) | |
download | serd-b16765b4830587c42db16587eda86f1eebb9a352.tar.gz serd-b16765b4830587c42db16587eda86f1eebb9a352.tar.bz2 serd-b16765b4830587c42db16587eda86f1eebb9a352.zip |
Zero node padding before passing to reader sinks
Diffstat (limited to 'src')
-rw-r--r-- | src/n3.c | 5 | ||||
-rw-r--r-- | src/node.c | 30 | ||||
-rw-r--r-- | src/node.h | 3 | ||||
-rw-r--r-- | src/reader.c | 4 | ||||
-rw-r--r-- | src/stack.h | 1 |
5 files changed, 41 insertions, 2 deletions
@@ -1211,7 +1211,7 @@ read_object(SerdReader* const reader, o->flags = flags; } - if (!st && emit && simple) { + if (!st && emit && simple && o) { st = emit_statement(reader, *ctx, o); } else if (!st && !emit) { ctx->object = o; @@ -1451,6 +1451,7 @@ read_base(SerdReader* const reader, const bool sparql, const bool token) SerdNode* uri = NULL; TRY(st, read_IRIREF(reader, &uri)); + serd_node_zero_pad(uri); TRY(st, serd_sink_write_base(reader->sink, uri)); read_ws_star(reader); @@ -1489,6 +1490,8 @@ read_prefixID(SerdReader* const reader, const bool sparql, const bool token) SerdNode* uri = NULL; TRY(st, read_IRIREF(reader, &uri)); + serd_node_zero_pad(name); + serd_node_zero_pad(uri); st = serd_sink_write_prefix(reader->sink, name, uri); if (!sparql) { @@ -152,6 +152,27 @@ serd_node_set(SerdNode** const dst, const SerdNode* const src) memcpy(*dst, src, size); } +/** + Zero node padding. + + This is used for nodes which live in re-used stack memory during reading, + which must be normalized before being passed to a sink so comparison will + work correctly. +*/ +void +serd_node_zero_pad(SerdNode* node) +{ + char* buf = serd_node_buffer(node); + const size_t size = node->length; + const size_t padded_size = serd_node_pad_size(size); + + memset(buf + size, 0, padded_size - size); + + if (node->flags & (SERD_HAS_DATATYPE | SERD_HAS_LANGUAGE)) { + serd_node_zero_pad(serd_node_meta(node)); + } +} + SerdNode* serd_new_token(const SerdNodeType type, const SerdStringView str) { @@ -275,7 +296,14 @@ serd_node_copy(const SerdNode* node) } const size_t size = serd_node_total_size(node); - SerdNode* copy = (SerdNode*)serd_calloc_aligned(serd_node_align, size); +#ifndef NDEBUG + const size_t unpadded_size = node->length; + const size_t padded_size = serd_node_pad_size(node->length); + for (size_t i = 0; i < padded_size - unpadded_size; ++i) { + assert(serd_node_buffer_c(node)[unpadded_size + i] == '\0'); + } +#endif + SerdNode* copy = (SerdNode*)serd_calloc_aligned(serd_node_align, size); memcpy(copy, node, size); return copy; } @@ -39,6 +39,9 @@ void serd_node_set(SerdNode* SERD_NONNULL* SERD_NONNULL dst, const SerdNode* SERD_NONNULL src); +void +serd_node_zero_pad(SerdNode* SERD_NONNULL node); + /// Create a new URI from a string, resolved against a base URI SerdNode* SERD_ALLOCATED serd_new_resolved_uri(SerdStringView string, SerdURIView base_uri); diff --git a/src/reader.c b/src/reader.c index ae50adab..fc39d7fa 100644 --- a/src/reader.c +++ b/src/reader.c @@ -114,6 +114,10 @@ emit_statement(SerdReader* const reader, graph = reader->default_graph; } + /* Zero the pad of the object node on the top of the stack. Lower nodes + (subject and predicate) were already zeroed by subsequent pushes. */ + serd_node_zero_pad(o); + const SerdStatus st = serd_sink_write( reader->sink, *ctx.flags, ctx.subject, ctx.predicate, o, graph); diff --git a/src/stack.h b/src/stack.h index 4592705e..6ad3385d 100644 --- a/src/stack.h +++ b/src/stack.h @@ -72,6 +72,7 @@ static inline void serd_stack_pop_to(SerdStack* stack, size_t n_bytes) { assert(stack->size >= n_bytes); + memset(stack->buf + n_bytes, 0, stack->size - n_bytes); stack->size = n_bytes; } |