diff options
author | Gergely Nagy <algernon@balabit.hu> | 2012-04-13 13:14:22 +0200 |
---|---|---|
committer | Gergely Nagy <algernon@balabit.hu> | 2012-04-13 13:14:22 +0200 |
commit | fb7693f412485cebc8d4a0cc2b2ace424d60d65d (patch) | |
tree | e39c60fa23f51157725a1d902980c344b4770a67 /lib/buffer.c | |
parent | d0d14fda7c98bab9f92e14f9578676bc70962d25 (diff) | |
download | libumberlog-fb7693f412485cebc8d4a0cc2b2ace424d60d65d.tar.gz libumberlog-fb7693f412485cebc8d4a0cc2b2ace424d60d65d.tar.xz libumberlog-fb7693f412485cebc8d4a0cc2b2ace424d60d65d.zip |
Implement string escaping.
With this patch, both JSON keys and values will be properly escaped.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
Diffstat (limited to 'lib/buffer.c')
-rw-r--r-- | lib/buffer.c | 139 |
1 files changed, 132 insertions, 7 deletions
diff --git a/lib/buffer.c b/lib/buffer.c index d538fda..4c6f0b7 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -33,6 +33,115 @@ #include <stdlib.h> #include <string.h> +static const unsigned char json_exceptions[] = + { + 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, + 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, + 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, + 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, + 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, + 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, + 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, + 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, + 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, + 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, + 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, + 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, + 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, + 0xff, '\0' + }; + +static inline char * +_ul_str_escape (const char *str) +{ + const unsigned char *p; + char *dest; + char *q; + static unsigned char exmap[256]; + static int exmap_inited; + + if (!str) + return NULL; + + p = (unsigned char *)str; + q = dest = malloc (strlen (str) * 6 + 1); + + if (!exmap_inited) + { + const unsigned char *e = json_exceptions; + + memset (exmap, 0, 256); + while (*e) + { + exmap[*e] = 1; + e++; + } + exmap_inited = 1; + } + + while (*p) + { + if (exmap[*p]) + *q++ = *p; + else + { + switch (*p) + { + case '\b': + *q++ = '\\'; + *q++ = 'b'; + break; + case '\f': + *q++ = '\\'; + *q++ = 'f'; + break; + case '\n': + *q++ = '\\'; + *q++ = 'n'; + break; + case '\r': + *q++ = '\\'; + *q++ = 'r'; + break; + case '\t': + *q++ = '\\'; + *q++ = 't'; + break; + case '\\': + *q++ = '\\'; + *q++ = '\\'; + break; + case '"': + *q++ = '\\'; + *q++ = '"'; + break; + default: + if ((*p < ' ') || (*p >= 0177)) + { + const char *json_hex_chars = "0123456789abcdef"; + + *q++ = '\\'; + *q++ = 'u'; + *q++ = '0'; + *q++ = '0'; + *q++ = json_hex_chars[(*p) >> 4]; + *q++ = json_hex_chars[(*p) & 0xf]; + } + else + *q++ = *p; + break; + } + } + p++; + } + + *q = 0; + return dest; +} + static inline ul_buffer_t * _ul_buffer_ensure_size (ul_buffer_t *buffer, size_t size) { @@ -58,24 +167,40 @@ ul_buffer_reset (ul_buffer_t *buffer) ul_buffer_t * ul_buffer_append (ul_buffer_t *buffer, const char *key, const char *value) { + char *k, *v; size_t lk, lv; - lk = strlen (key); - lv = strlen (value); + k = _ul_str_escape (key); + if (!k) + return NULL; + v = _ul_str_escape (value); + if (!v) + { + free (k); + return NULL; + } + + lk = strlen (k); + lv = strlen (v); buffer = _ul_buffer_ensure_size (buffer, buffer->len + lk + lv + 6); if (!buffer) - return NULL; - - /* FIXME: Escpae stuff here */ + { + free (k); + free (v); + return NULL; + } memcpy (buffer->msg + buffer->len, "\"", 1); - memcpy (buffer->msg + buffer->len + 1, key, lk); + memcpy (buffer->msg + buffer->len + 1, k, lk); memcpy (buffer->msg + buffer->len + 1 + lk, "\":\"", 3); - memcpy (buffer->msg + buffer->len + 1 + lk + 3, value, lv); + memcpy (buffer->msg + buffer->len + 1 + lk + 3, v, lv); memcpy (buffer->msg + buffer->len + 1 + lk + 3 + lv, "\",", 2); buffer->len += lk + lv + 6; + free (k); + free (v); + return buffer; } |