1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-11-09 21:28:51 +01:00

common: New function percent_data_escape.

* common/percent.c (percent_data_escape): New.
* common/t-percent.c (test_percent_data_escape): New.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-07-02 20:24:10 +02:00
parent 3978df943d
commit 58baf40af6
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 95 additions and 1 deletions

View File

@ -87,6 +87,50 @@ percent_plus_escape (const char *string)
} }
/* Create a newly alloced string from (DATA,DATALEN) with embedded
* Nuls quoted as %00. The standard percent unescaping can be
* used to reverse this encoding. */
char *
percent_data_escape (const void *data, size_t datalen)
{
char *buffer, *p;
const char *s;
size_t n, length;
for (length=1, s=data, n=datalen; n; s++, n--)
{
if (!*s || *s == '%')
length += 3;
else
length++;
}
buffer = p = xtrymalloc (length);
if (!buffer)
return NULL;
for (s=data, n=datalen; n; s++, n--)
{
if (!*s)
{
memcpy (p, "%00", 3);
p += 3;
}
else if (*s == '%')
{
memcpy (p, "%25", 3);
p += 3;
}
else
*p++ = *s;
}
*p = 0;
return buffer;
}
/* Do the percent and plus/space unescaping from STRING to BUFFER and /* Do the percent and plus/space unescaping from STRING to BUFFER and
return the length of the valid buffer. Plus unescaping is only return the length of the valid buffer. Plus unescaping is only
done if WITHPLUS is true. An escaped Nul character will be done if WITHPLUS is true. An escaped Nul character will be

View File

@ -99,6 +99,55 @@ test_percent_plus_escape (void)
} }
static void
test_percent_data_escape (void)
{
static struct {
const char *data;
size_t datalen;
const char *expect;
} tbl[] = {
{
"", 0,
""
}, {
"a", 1,
"a",
}, {
"%22", 3,
"%2522"
}, {
"%%", 3,
"%25%25%00"
}, {
"\n \0BC\t", 6,
"\n %00BC\t"
}, { NULL, 0, NULL }
};
char *buf;
int i;
size_t len;
for (i=0; tbl[i].data; i++)
{
buf = percent_data_escape (tbl[i].data, tbl[i].datalen);
if (!buf)
{
fprintf (stderr, "out of core: %s\n", strerror (errno));
exit (2);
}
if (strcmp (buf, tbl[i].expect))
fail (i);
len = percent_plus_unescape_inplace (buf, 0);
if (len != tbl[i].datalen)
fail (i);
else if (memcmp (buf, tbl[i].data, tbl[i].datalen))
fail (i);
xfree (buf);
}
}
int int
main (int argc, char **argv) main (int argc, char **argv)
@ -109,6 +158,6 @@ main (int argc, char **argv)
/* FIXME: We escape_unescape is not tested - only /* FIXME: We escape_unescape is not tested - only
percent_plus_unescape. */ percent_plus_unescape. */
test_percent_plus_escape (); test_percent_plus_escape ();
test_percent_data_escape ();
return 0; return 0;
} }

View File

@ -201,6 +201,7 @@ char *hex2str_alloc (const char *hexstring, size_t *r_count);
/*-- percent.c --*/ /*-- percent.c --*/
char *percent_plus_escape (const char *string); char *percent_plus_escape (const char *string);
char *percent_data_escape (const void *data, size_t datalen);
char *percent_plus_unescape (const char *string, int nulrepl); char *percent_plus_unescape (const char *string, int nulrepl);
char *percent_unescape (const char *string, int nulrepl); char *percent_unescape (const char *string, int nulrepl);