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 <wking@tremily.us></uid>

Now the uids are properly escaped:

   <uid>William Trevor King &lt;wking@tremily.us&gt;</uid>

Signed-off-by: W. Trevor King <wking@tremily.us>
This commit is contained in:
W. Trevor King 2012-10-06 11:30:21 -04:00 committed by Werner Koch
parent c28ebca9f2
commit 3f1329e1c9

View File

@ -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);