aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpgme-tool.c
diff options
context:
space:
mode:
authorW. Trevor King <[email protected]>2012-10-06 15:30:21 +0000
committerWerner Koch <[email protected]>2012-10-11 14:22:46 +0000
commit3f1329e1c9b99b1632cc4c4eec2e4399676fd93d (patch)
tree2cc05aa8d56d4ec47358c06aa624c19fe0f9b11f /src/gpgme-tool.c
parentgpgme-tool: Fix chain_id -> chain-id in KEYLIST XML. (diff)
downloadgpgme-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 &lt;[email protected]&gt;</uid> Signed-off-by: W. Trevor King <[email protected]>
Diffstat (limited to 'src/gpgme-tool.c')
-rw-r--r--src/gpgme-tool.c69
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 "&lt;";
+ case '>':
+ return "&gt;";
+ case '&':
+ return "&amp;";
+ 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 &lt;%s&gt;",
+ 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);