From d103857c0f94c2ee40d6a41cd312d5e782331f7c Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Thu, 6 Dec 2007 19:03:21 -0500 Subject: [PATCH] Don't create any elements of an element path that contains an invalid element name. --- src/commands.c | 15 ++++++++++----- src/xml.c | 44 ++++++++++++++++++++++++-------------------- src/xml.h | 1 + 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/commands.c b/src/commands.c index b850fb69..50de7a78 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1116,15 +1116,15 @@ static int store_command_finalize(gpointer data, gint rc, guchar *line, if (!req || !*req) return EPWMD_COMMAND_SYNTAX; + if (valid_element_path(req, TRUE) == FALSE) { + g_strfreev(req); + return EPWMD_INVALID_ELEMENT; + } + again: n = find_account(client->doc, &req, &error, NULL, 0); if (error && error == EPWMD_ELEMENT_NOT_FOUND) { - if (contains_whitespace(*req) == TRUE) { - g_strfreev(req); - return EPWMD_INVALID_ELEMENT; - } - error = new_account(client->doc, *req); if (error) { @@ -1956,6 +1956,11 @@ static gpg_error_t target_attribute(struct client_s *client, gchar **req) return EPWMD_COMMAND_SYNTAX; } + if (valid_element_path(src, FALSE) == FALSE) { + g_strfreev(src); + return EPWMD_INVALID_ELEMENT; + } + if ((dst = split_input_line(req[1], "\t", 0)) == NULL) { /* * The first argument may be only an account. diff --git a/src/xml.c b/src/xml.c index d2f9b862..3c9e06e8 100644 --- a/src/xml.c +++ b/src/xml.c @@ -71,8 +71,6 @@ gboolean is_literal_element(gchar **element) /* * Fails if 'element' begins with punctuation or digit or contains whitespace. - * If the element is a literal element which was prefixed with '!', it should - * be trimmed before calling this function. * * I'm not sure about using g_unichar_isspace() rather than isspace()? */ @@ -85,6 +83,9 @@ gboolean valid_xml_element(xmlChar *element) if (!element || !*element) return FALSE; + if (*p == '!') + p++; + len = g_utf8_strlen(p, -1) - 1; c = g_utf8_get_char(p++); @@ -101,6 +102,25 @@ gboolean valid_xml_element(xmlChar *element) return TRUE; } +gboolean valid_element_path(gchar **path, gboolean has_value) +{ + gchar **p; + + for (p = path; *p; p++) { + /* + * An empty element is valid and don't check the syntax of the + * content. + */ + if (has_value == TRUE && (!*(p+1) || !*p[0])) + break; + + if (valid_xml_element((xmlChar *)*p) == FALSE) + return FALSE; + } + + return TRUE; +} + gpg_error_t new_account(xmlDocPtr doc, gchar *name) { xmlNodePtr root = xmlDocGetRootElement(doc); @@ -114,13 +134,6 @@ gpg_error_t new_account(xmlDocPtr doc, gchar *name) if (is_literal_element_str(p)) p++; - /* - * Event though the account name is an attribute and not an element, - * element syntax still applies. - */ - if (valid_xml_element((xmlChar *)p) == FALSE) - return EPWMD_INVALID_ELEMENT; - n = xmlNewNode(NULL, (xmlChar *)"account"); n = xmlAddChild(root, n); a = xmlNewProp(n, (xmlChar *)"name", (xmlChar *)p); @@ -283,11 +296,6 @@ xmlNodePtr create_target_elements_cb(xmlNodePtr node, gchar **path, for (i = 0; req[i]; i++) { xmlNodePtr n; - if (valid_xml_element((xmlChar *)req[i]) == FALSE) { - *error = EPWMD_INVALID_ELEMENT; - return NULL; - } - if ((n = find_element(node, req[i])) == NULL) { n = xmlNewNode(NULL, (xmlChar *)req[i]); @@ -328,14 +336,10 @@ xmlNodePtr create_elements_cb(xmlNodePtr node, gchar **elements, if (req[i+1]) { /* * Strip the first '!' if needed. If there's another, it's an - * error. + * error. The syntax has already been checked before calling this + * function. */ is_literal_element(&req[i]); - - if (valid_xml_element((xmlChar *)req[i]) == FALSE) { - *error = EPWMD_INVALID_ELEMENT; - return NULL; - } } /* diff --git a/src/xml.h b/src/xml.h index a0894aa9..ccb6ff95 100644 --- a/src/xml.h +++ b/src/xml.h @@ -49,5 +49,6 @@ gboolean is_literal_element_str(gchar *element); xmlChar *node_has_attribute(xmlNodePtr n, xmlChar *attr); gboolean node_has_child_element(xmlNodePtr node); gint sort_element_list(gconstpointer a, gconstpointer b); +gboolean valid_element_path(gchar **path, gboolean has_value); #endif -- 2.11.4.GIT