diff options
author | W. Trevor King <[email protected]> | 2012-10-06 15:30:21 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2012-10-11 14:22:46 +0000 |
commit | 3f1329e1c9b99b1632cc4c4eec2e4399676fd93d (patch) | |
tree | 2cc05aa8d56d4ec47358c06aa624c19fe0f9b11f /src/gpgme-tool.c | |
parent | gpgme-tool: Fix chain_id -> chain-id in KEYLIST XML. (diff) | |
download | gpgme-3f1329e1c9b99b1632cc4c4eec2e4399676fd93d.tar.gz gpgme-3f1329e1c9b99b1632cc4c4eec2e4399676fd93d.zip |
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:
<uid>William Trevor King <[email protected]></uid>
Now the uids are properly escaped:
<uid>William Trevor King <[email protected]></uid>
Signed-off-by: W. Trevor King <[email protected]>
Diffstat (limited to 'src/gpgme-tool.c')
-rw-r--r-- | src/gpgme-tool.c | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index d37088cd..b7452947 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); |