common: New function decode_c_string.

* common/miscellaneous.c (decode_c_string): New.
--

This is basically a copy from the code we use in gpgme and gpa.

Signed-off-by: Werner Koch <wk@gnupg.org>
(cherry picked from commit 6ecedd0b25)
This commit is contained in:
Werner Koch 2019-01-30 08:28:56 +01:00
parent 5ed8e598fa
commit 17e2ec488f
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 77 additions and 0 deletions

View File

@ -328,6 +328,82 @@ make_printable_string (const void *p, size_t n, int delim )
}
/* Decode the C formatted string SRC and return the result in a newly
* allocated buffer. In error returns NULL and sets ERRNO. */
char *
decode_c_string (const char *src)
{
char *buffer, *dst;
int val;
/* The converted string will never be larger than the original
string. */
buffer = dst = xtrymalloc (strlen (src) + 1);
if (!buffer)
return NULL;
while (*src)
{
if (*src != '\\')
{
*dst++ = *src++;
continue;
}
#define DECODE_ONE(_m,_r) case _m: src += 2; *dst++ = _r; break;
switch (src[1])
{
DECODE_ONE ('n', '\n');
DECODE_ONE ('r', '\r');
DECODE_ONE ('f', '\f');
DECODE_ONE ('v', '\v');
DECODE_ONE ('b', '\b');
DECODE_ONE ('t', '\t');
DECODE_ONE ('\\', '\\');
DECODE_ONE ('\'', '\'');
DECODE_ONE ('\"', '\"');
case 'x':
val = hextobyte (src+2);
if (val == -1) /* Bad coding, keep as is. */
{
*dst++ = *src++;
*dst++ = *src++;
if (*src)
*dst++ = *src++;
if (*src)
*dst++ = *src++;
}
else if (!val)
{
/* A binary zero is not representable in a C string thus
* we keep the C-escaping. Note that this will also
* never be larger than the source string. */
*dst++ = '\\';
*dst++ = '0';
src += 4;
}
else
{
*(unsigned char *)dst++ = val;
src += 4;
}
break;
default: /* Bad coding; keep as is.. */
*dst++ = *src++;
*dst++ = *src++;
break;
}
#undef DECODE_ONE
}
*dst++ = 0;
return buffer;
}
/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed
* packet. LEN should be at least 6. */
static int

View File

@ -338,6 +338,7 @@ void print_hexstring (FILE *fp, const void *buffer, size_t length,
int reserved);
char *try_make_printable_string (const void *p, size_t n, int delim);
char *make_printable_string (const void *p, size_t n, int delim);
char *decode_c_string (const char *src);
int is_file_compressed (const char *s, int *ret_rc);