diff options
author | David Robillard <d@drobilla.net> | 2018-05-26 11:49:43 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-11-25 22:12:47 +0100 |
commit | 29d83d5902596ca269196894b154e486465f6ced (patch) | |
tree | 9673e1f32dd64f9bc54aab02dbf421714df4dbe4 | |
parent | 9c5e41683fc2da0ba4089c728992f481e9908bf2 (diff) | |
download | serd-29d83d5902596ca269196894b154e486465f6ced.tar.gz serd-29d83d5902596ca269196894b154e486465f6ced.tar.bz2 serd-29d83d5902596ca269196894b154e486465f6ced.zip |
Add debug checks for node padding
-rw-r--r-- | src/node.c | 47 |
1 files changed, 39 insertions, 8 deletions
@@ -41,7 +41,7 @@ static const size_t serd_node_align = sizeof(SerdNode); typedef struct StaticNode { SerdNode node; - char buf[sizeof(NS_XSD) + sizeof("base64Binary") + 1]; + char buf[sizeof(NS_XSD) + sizeof("base64Binary") + sizeof(SerdNode)]; } StaticNode; #define DEFINE_XSD_NODE(name) \ @@ -76,6 +76,26 @@ serd_node_get_meta(SerdNode* node) return node + 1 + (serd_node_pad_size(node->n_bytes) / serd_node_align); } +static void +serd_node_check_padding(const SerdNode* node) +{ +#ifndef NDEBUG + if (node) { + const size_t unpadded_size = node->n_bytes; + const size_t padded_size = serd_node_pad_size(node->n_bytes); + for (size_t i = 0; i < padded_size - unpadded_size; ++i) { + assert(serd_node_buffer_c(node)[unpadded_size + i] == '\0'); + } + + if (node->flags & SERD_HAS_DATATYPE) { + serd_node_check_padding(serd_node_get_datatype(node)); + } else if (node->flags & SERD_HAS_LANGUAGE) { + serd_node_check_padding(serd_node_get_language(node)); + } + } +#endif +} + static size_t serd_node_total_size(const SerdNode* node) { @@ -126,6 +146,7 @@ serd_node_new_simple(SerdType type, const char* str) SerdNode* node = serd_node_malloc(n_bytes, 0, type); memcpy(serd_node_buffer(node), str, n_bytes); node->n_bytes = n_bytes; + serd_node_check_padding(node); return node; } @@ -141,6 +162,7 @@ serd_node_new_string(const char* str) SerdNode* node = serd_node_malloc(n_bytes, flags, SERD_LITERAL); memcpy(serd_node_buffer(node), str, n_bytes); node->n_bytes = n_bytes; + serd_node_check_padding(node); return node; } @@ -149,6 +171,8 @@ serd_node_new_literal(const char* str, const SerdNode* datatype, const char* lang) { + serd_node_check_padding(datatype); + if (!str || (lang && datatype && strcmp(serd_node_buffer_c(datatype), NS_RDF "#langString")) || (datatype && serd_node_get_type(datatype) != SERD_URI)) { @@ -172,6 +196,7 @@ serd_node_new_literal(const char* str, lang_node->type = SERD_LITERAL; lang_node->n_bytes = lang_len; memcpy(serd_node_buffer(lang_node), lang, lang_len); + serd_node_check_padding(lang_node); } else if (datatype) { flags |= SERD_HAS_DATATYPE; const size_t datatype_len = strlen(serd_node_buffer_c(datatype)); @@ -182,12 +207,14 @@ serd_node_new_literal(const char* str, SerdNode* datatype_node = node + 1 + (len / serd_node_align); memcpy(datatype_node, datatype, sizeof(SerdNode) + datatype_len); + serd_node_check_padding(datatype_node); } else { node = serd_node_malloc(n_bytes, flags, SERD_LITERAL); memcpy(serd_node_buffer(node), str, n_bytes); node->n_bytes = n_bytes; } + serd_node_check_padding(node); return node; } @@ -225,6 +252,10 @@ serd_node_zero_pad(SerdNode* node) if (padded_size > size) { memset(buf + size, 0, padded_size - size); } + + if (node->flags & (SERD_HAS_DATATYPE|SERD_HAS_LANGUAGE)) { + serd_node_zero_pad(serd_node_get_meta(node)); + } } SerdNode* @@ -235,13 +266,7 @@ serd_node_copy(const SerdNode* node) } const size_t size = serd_node_total_size(node); -#ifndef NDEBUG - const size_t unpadded_size = node->n_bytes; - const size_t padded_size = serd_node_pad_size(node->n_bytes); - for (size_t i = 0; i < padded_size - unpadded_size; ++i) { - assert(serd_node_buffer_c(node)[unpadded_size + i] == '\0'); - } -#endif + serd_node_check_padding(node); SerdNode* copy = (SerdNode*)calloc(1, size + 3); memcpy(copy, node, size); return copy; @@ -382,6 +407,7 @@ serd_node_new_file_uri(const char* path, const char* hostname, bool escape) SerdNode* node = serd_node_new_uri((const char*)buffer.buf); free(buffer.buf); + serd_node_check_padding(node); return node; } @@ -401,6 +427,7 @@ serd_node_new_from_uri(const SerdURI* uri, const SerdURI* base) serd_node_buffer(node)[actual_len] = '\0'; node->n_bytes = actual_len; + serd_node_check_padding(node); return node; } @@ -431,6 +458,7 @@ serd_node_new_relative_uri(const char* str, serd_node_buffer(node)[actual_len] = '\0'; node->n_bytes = actual_len; + serd_node_check_padding(node); return node; } @@ -500,6 +528,7 @@ serd_node_new_decimal(double d, unsigned frac_digits, const SerdNode* datatype) } memcpy(serd_node_get_meta(node), type, type_len); + serd_node_check_padding(node); return node; } @@ -531,6 +560,7 @@ serd_node_new_integer(int64_t i, const SerdNode* datatype) } while ((abs_i /= 10) > 0); memcpy(serd_node_get_meta(node), type, type_len); + serd_node_check_padding(node); return node; } @@ -558,6 +588,7 @@ serd_node_new_blob(const void* buf, node->n_bytes = len; memcpy(serd_node_get_meta(node), type, type_len); + serd_node_check_padding(node); return node; } |