From: W. Trevor King Date: Sat, 6 Oct 2012 15:30:21 +0000 (-0400) Subject: gpgme-tool: escape special characters in output XML data (<, >, and &). X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=3f1329e1c9b99b1632cc4c4eec2e4399676fd93d;p=gpgme.git gpgme-tool: escape special characters in output XML data (<, >, and &). [[PGP Signed Part:Undecided]] src/gpgme-tool.c (result_xml_escape_replacement, result_xml_escape): New. (result_xml_tag_data): Use result_xml_escape() to escape data. (result_add_error): Use unescaped < and >. -- This is a general solution for generating valid XML, but the specific output that inspired the change was from the KEYLIST command: William Trevor King Now the uids are properly escaped: William Trevor King <wking@tremily.us> Signed-off-by: W. Trevor King --- diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index d37088c..b745294 100644 --- a/src/gpgme-tool.c +++ b/src/gpgme-tool.c @@ -657,12 +657,71 @@ result_xml_tag_start (struct result_xml_state *state, char *name, ...) return 0; } +const char * +result_xml_escape_replacement(char c) +{ + switch (c) + { + case '<': + return "<"; + case '>': + return ">"; + case '&': + return "&"; + default: + return NULL; + } +} + +gpg_error_t +result_xml_escape (const char *data, char **buf) +{ + int data_len, i, j = 1; + const char *r; + char *b; + + data_len = strlen (data); + for (i = 0; i < data_len; i++) + { + r = result_xml_escape_replacement(data[i]); + if (r) + j += strlen (r); + else + j += 1; + } + + b = (char *) malloc (j); + if (! b) + return gpg_error_from_syserror (); + + j = 0; + for (i = 0; i < data_len; i++) + { + r = result_xml_escape_replacement(data[i]); + if (r) + { + strcpy (b + j, r); + j += strlen (r); + } + else + { + b[j] = data[i]; + j += 1; + } + } + b[j] = 0; + *buf = b; + + return 0; +} gpg_error_t result_xml_tag_data (struct result_xml_state *state, const char *data) { + gpg_error_t err; result_xml_write_cb_t cb = state->cb; void *hook = state->hook; + char *buf = NULL; if (state->had_data[state->next_tag - 1]) { @@ -674,7 +733,13 @@ result_xml_tag_data (struct result_xml_state *state, const char *data) (*cb) (hook, ">", 1); state->had_data[state->next_tag - 1] = 2; - (*cb) (hook, data, strlen (data)); + err = result_xml_escape(data, &buf); + if (err) + return err; + + (*cb) (hook, buf, strlen (buf)); + + free (buf); return 0; } @@ -714,7 +779,7 @@ result_add_error (struct result_xml_state *state, char *name, gpg_error_t err) char code[20]; char msg[1024]; snprintf (code, sizeof (code) - 1, "0x%x", err); - snprintf (msg, sizeof (msg) - 1, "%s <%s>", + snprintf (msg, sizeof (msg) - 1, "%s <%s>", gpg_strerror (err), gpg_strsource (err)); result_xml_tag_start (state, name, "value", code, NULL); result_xml_tag_data (state, msg);