mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
json_add_string_escape: for escaping internally-generated strings.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
6112df3a90
commit
7f03e15e03
3 changed files with 91 additions and 3 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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…
Add table
Reference in a new issue