Browse Source

json_add_string_escape: for escaping internally-generated strings.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
7f03e15e03
  1. 50
      common/json.c
  2. 9
      common/json.h
  3. 35
      common/test/run-json.c

50
common/json.c

@ -493,6 +493,56 @@ void json_add_string(struct json_result *result, const char *fieldname, const ch
result_append_fmt(result, "\"%s\"", escaped);
}
void json_add_string_escape(struct json_result *result, const char *fieldname,
const char *value)
{
/* Worst case: all \uXXXX */
char *escaped = tal_arr(result, char, strlen(value) * 6 + 1);
size_t i, n;
json_start_member(result, fieldname);
for (i = n = 0; value[i]; i++, n++) {
char esc = 0;
switch (value[i]) {
case '\n':
esc = 'n';
break;
case '\b':
esc = 'b';
break;
case '\f':
esc = 'f';
break;
case '\t':
esc = 't';
break;
case '\r':
esc = 'r';
break;
case '\\':
case '"':
esc = value[i];
break;
default:
if ((unsigned)value[i] < ' '
|| value[i] == 127) {
sprintf(escaped + n, "\\u%04X", value[i]);
n += 5;
continue;
}
}
if (esc) {
escaped[n++] = '\\';
escaped[n] = esc;
} else
escaped[n] = value[i];
}
escaped[n] = '\0';
result_append_fmt(result, "\"%s\"", escaped);
tal_free(escaped);
}
void json_add_bool(struct json_result *result, const char *fieldname, bool value)
{
json_start_member(result, fieldname);

9
common/json.h

@ -83,8 +83,15 @@ void json_object_end(struct json_result *ptr);
struct json_result *new_json_result(const tal_t *ctx);
/* '"fieldname" : "value"' or '"value"' if fieldname is NULL*/
/* '"fieldname" : "value"' or '"value"' if fieldname is NULL. Turns
* any unusual chars into ?.
*/
void json_add_string(struct json_result *result, const char *fieldname, const char *value);
/* Properly escapes any characters in @value */
void json_add_string_escape(struct json_result *result, const char *fieldname,
const char *value);
/* '"fieldname" : literal' or 'literal' if fieldname is NULL*/
void json_add_literal(struct json_result *result, const char *fieldname,
const char *literal, int len);

35
common/test/run-json.c

@ -37,8 +37,7 @@ static int test_json_tok_bitcoin_amount(void)
return 0;
}
static int test_json_escape(void)
static int test_json_filter(void)
{
struct json_result *result = new_json_result(NULL);
jsmntok_t *toks;
@ -78,9 +77,41 @@ static int test_json_escape(void)
return 0;
}
static void test_json_escape(void)
{
int i;
const char *str;
for (i = 1; i < 256; i++) {
char badstr[2];
struct json_result *result = new_json_result(NULL);
badstr[0] = i;
badstr[1] = 0;
json_object_start(result, NULL);
json_add_string_escape(result, "x", badstr);
json_object_end(result);
str = json_result_string(result);
if (i == '\\' || i == '"'
|| i == '\n' || i == '\r' || i == '\b'
|| i == '\t' || i == '\f')
assert(strstarts(str, "{ \"x\" : \"\\"));
else if (i < 32 || i == 127)
assert(strstarts(str, "{ \"x\" : \"\\u00"));
else {
char expect[] = "{ \"x\" : \"?\" }";
expect[9] = i;
assert(streq(str, expect));
}
tal_free(result);
}
}
int main(void)
{
test_json_tok_bitcoin_amount();
test_json_filter();
test_json_escape();
}

Loading…
Cancel
Save