diff options
author | Werner Koch <wk@gnupg.org> | 2019-01-30 08:28:56 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2019-01-30 08:28:56 +0100 |
commit | 6ecedd0b25b6b1a33be63b99f2a8256370000521 (patch) | |
tree | d7f7363d870736f8c1a29b8e51ce8e68895a11b9 /common/miscellaneous.c | |
parent | doc: Fix typo (diff) | |
download | gnupg2-6ecedd0b25b6b1a33be63b99f2a8256370000521.tar.xz gnupg2-6ecedd0b25b6b1a33be63b99f2a8256370000521.zip |
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>
Diffstat (limited to 'common/miscellaneous.c')
-rw-r--r-- | common/miscellaneous.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 0b374e6c8..260552828 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -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 |