aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-json.c
diff options
context:
space:
mode:
authorJakub Zawadzki <darkjames-ws@darkjames.pl>2012-10-07 19:57:21 +0000
committerJakub Zawadzki <darkjames-ws@darkjames.pl>2012-10-07 19:57:21 +0000
commitac4419071bc3af06f6c28e049d7a95d78f03465c (patch)
treeee75d544becebcaa22984123bcd6a5abfece3aa3 /epan/dissectors/packet-json.c
parentcb12df2ca8708198e5d8c96794ad583cee202c68 (diff)
Unescape JSON strings.
svn path=/trunk/; revision=45373
Diffstat (limited to 'epan/dissectors/packet-json.c')
-rw-r--r--epan/dissectors/packet-json.c90
1 files changed, 82 insertions, 8 deletions
diff --git a/epan/dissectors/packet-json.c b/epan/dissectors/packet-json.c
index c3d594d465..e2579bbb0b 100644
--- a/epan/dissectors/packet-json.c
+++ b/epan/dissectors/packet-json.c
@@ -210,6 +210,85 @@ static void after_array(void *tvbparse_data, const void *wanted_data _U_, tvbpar
ep_stack_pop(data->stack);
}
+static char *json_string_unescape(tvbparse_elem_t *tok)
+{
+ char *str = ep_alloc(tok->len - 1);
+ int i, j;
+
+ j = 0;
+ for (i = 1; i < tok->len - 1; i++) {
+ guint8 ch = tvb_get_guint8(tok->tvb, tok->offset + i);
+
+ if (ch == '\\') {
+ i++;
+
+ ch = tvb_get_guint8(tok->tvb, tok->offset + i);
+ switch (ch) {
+ case '\"':
+ case '\\':
+ case '/':
+ default:
+ str[j++] = ch;
+ break;
+
+ case 'b':
+ str[j++] = '\b';
+ break;
+ case 'f':
+ str[j++] = '\f';
+ break;
+ case 'n':
+ str[j++] = '\n';
+ break;
+ case 'r':
+ str[j++] = '\r';
+ break;
+ case 't':
+ str[j++] = '\t';
+ break;
+
+ case 'u':
+ {
+ guint16 unicode_hex = 0;
+ gboolean valid = TRUE;
+ int k;
+
+ for (k = 0; k < 4; k++) {
+ i++;
+ unicode_hex <<= 4;
+
+ ch = tvb_get_guint8(tok->tvb, tok->offset + i);
+ if (ch >= '0' && ch <= '9')
+ unicode_hex |= (ch - '0');
+ else if (ch >= 'a' && ch <= 'f')
+ unicode_hex |= (ch - 'a');
+ else if (ch >= 'A' && ch <= 'F')
+ unicode_hex |= (ch - 'A');
+ else {
+ valid = FALSE;
+ break;
+ }
+ }
+
+ if (valid) {
+ /* \uXXXX => 6 bytes */
+ int charlen = g_unichar_to_utf8(unicode_hex, &str[j]);
+ j += charlen;
+ } else
+ str[j++] = '?';
+ break;
+ }
+ }
+
+ } else
+ str[j++] = ch;
+
+ }
+ str[j] = '\0';
+
+ return str;
+}
+
static void after_value(void *tvbparse_data, const void *wanted_data _U_, tvbparse_elem_t *tok) {
json_parser_data_t *data = (json_parser_data_t *) tvbparse_data;
@@ -221,14 +300,9 @@ static void after_value(void *tvbparse_data, const void *wanted_data _U_, tvbpar
switch (value_id) {
case JSON_TOKEN_STRING:
- if (tok->len >= 2) {
- char *str = ep_alloc(tok->len - 1);
-
- /* XXX, for now only strip quotes, later we can unescape string */
- tvb_memcpy(tok->tvb, str, tok->offset + 1, tok->len - 2);
- str[tok->len - 2] = '\0';
- proto_tree_add_string(tree, hf_json_value_string, tok->tvb, tok->offset, tok->len, str);
- } else
+ if (tok->len >= 2)
+ proto_tree_add_unicode_string(tree, hf_json_value_string, tok->tvb, tok->offset, tok->len, json_string_unescape(tok));
+ else
proto_tree_add_item(tree, hf_json_value_string, tok->tvb, tok->offset, tok->len, ENC_ASCII|ENC_NA);
break;