From f6373368d062cd6e674af2e9ce6c1300d1bc0c52 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Fri, 13 Feb 2015 15:36:59 +0100 Subject: [PATCH] XML: Bug fixes of namespaces --- ucw-xml/common.c | 5 ++++- ucw-xml/ns.c | 19 +++++++++++-------- ucw-xml/parse.c | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/ucw-xml/common.c b/ucw-xml/common.c index 5cfd8513..8c23ce2a 100644 --- a/ucw-xml/common.c +++ b/ucw-xml/common.c @@ -120,7 +120,8 @@ void xml_reset(struct xml_context *ctx) { TRACE(ctx, "reset"); - struct mempool *pool = ctx->pool, *stack = ctx->stack; + struct mempool *pool = ctx->pool, *stack = ctx->stack, *ns_pool = ctx->ns_pool; + const char **ns_by_id = ctx->ns_by_id; xml_dtd_cleanup(ctx); xml_sources_cleanup(ctx); mp_flush(pool); @@ -128,5 +129,7 @@ xml_reset(struct xml_context *ctx) *ctx = xml_defaults; ctx->pool = pool; ctx->stack = stack; + ctx->ns_pool = ns_pool; + ctx->ns_by_id = ns_by_id; xml_ns_reset(ctx); } diff --git a/ucw-xml/ns.c b/ucw-xml/ns.c index 66a4fdbb..18412ddd 100644 --- a/ucw-xml/ns.c +++ b/ucw-xml/ns.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -31,10 +32,10 @@ struct ns_hash_entry { #define HASH_NODE struct ns_hash_entry #define HASH_PREFIX(x) ns_hash_##x #define HASH_KEY_ENDSTRING name -#define HASH_WANT_CLEANUP #define HASH_WANT_FIND #define HASH_WANT_LOOKUP #define HASH_TABLE_DYNAMIC +#define HASH_TABLE_ALLOC #define HASH_LOOKUP_DETECT_NEW #define HASH_GIVE_ALLOC XML_HASH_GIVE_ALLOC @@ -60,9 +61,11 @@ xml_ns_enable(struct xml_context *ctx) return; TRACE(ctx, "NS: Enabling"); + ASSERT(!ctx->depth); ctx->flags |= XML_NAMESPACES; if (!ctx->ns_pool) { + // CAVEAT: xml_reset() must handle everything we allocate here TRACE(ctx, "NS: Allocating data structures"); ctx->ns_pool = mp_new(4096); GARY_INIT(ctx->ns_by_id, 16); @@ -95,8 +98,6 @@ xml_ns_cleanup(struct xml_context *ctx) return; TRACE(ctx, "NS: Cleanup"); - ns_hash_cleanup(ctx->ns_by_prefix); - ns_hash_cleanup(ctx->ns_by_name); GARY_FREE(ctx->ns_by_id); mp_delete(ctx->ns_pool); } @@ -108,21 +109,23 @@ xml_ns_reset(struct xml_context *ctx) return; TRACE(ctx, "NS: Reset"); - GARY_RESIZE(ctx->ns_by_id, 1); - ctx->ns_by_id[0] = ""; + GARY_RESIZE(ctx->ns_by_id, 0); mp_flush(ctx->ns_pool); } const char * xml_ns_by_id(struct xml_context *ctx, uint ns) { - ASSERT(ns < GARY_SIZE(ctx->ns_by_id)); + if (!ns) // This should work even if namespaces are disabled + return ""; + ASSERT(ns_enabled(ctx) && ns < GARY_SIZE(ctx->ns_by_id)); return ctx->ns_by_id[ns]; } uint xml_ns_by_name(struct xml_context *ctx, const char *name) { + ASSERT(ns_enabled(ctx)); int new_p; struct ns_hash_entry *he = ns_hash_lookup(ctx->ns_by_name, (char *) name, &new_p); if (new_p) @@ -181,10 +184,10 @@ void xml_ns_push_element(struct xml_context *ctx) /* Scan attributes for prefix definitions */ XML_ATTR_FOR_EACH(a, e) - if (!memcmp(a->name, "xmlns", 5)) + if (str_has_prefix(a->name, "xmlns")) { uint ns = xml_ns_by_name(ctx, a->val); - if (a->name[5] == ':' && a->name[6]) + if (a->name[5] == ':') { if (!ns) xml_error(ctx, "Namespace prefixes must not be undeclared"); diff --git a/ucw-xml/parse.c b/ucw-xml/parse.c index 2ddfa2b8..b1790d0b 100644 --- a/ucw-xml/parse.c +++ b/ucw-xml/parse.c @@ -850,7 +850,7 @@ xml_parse_etag(struct xml_context *ctx) if (xml_get_char(ctx) != '>') { recover: - xml_error(ctx, "Invalid ETag, expected ", e->name); + xml_error(ctx, "Invalid ETag, expected ", xml_node_qname(ctx, e)); while (xml_get_char(ctx) != '>'); } xml_dec(ctx); -- 2.39.5