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);
|
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)
|
void json_add_bool(struct json_result *result, const char *fieldname, bool value)
|
||||||
{
|
{
|
||||||
json_start_member(result, fieldname);
|
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);
|
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);
|
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*/
|
/* '"fieldname" : literal' or 'literal' if fieldname is NULL*/
|
||||||
void json_add_literal(struct json_result *result, const char *fieldname,
|
void json_add_literal(struct json_result *result, const char *fieldname,
|
||||||
const char *literal, int len);
|
const char *literal, int len);
|
||||||
|
|
|
@ -37,8 +37,7 @@ static int test_json_tok_bitcoin_amount(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_json_filter(void)
|
||||||
static int test_json_escape(void)
|
|
||||||
{
|
{
|
||||||
struct json_result *result = new_json_result(NULL);
|
struct json_result *result = new_json_result(NULL);
|
||||||
jsmntok_t *toks;
|
jsmntok_t *toks;
|
||||||
|
@ -78,9 +77,41 @@ static int test_json_escape(void)
|
||||||
return 0;
|
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)
|
int main(void)
|
||||||
{
|
{
|
||||||
test_json_tok_bitcoin_amount();
|
test_json_tok_bitcoin_amount();
|
||||||
|
test_json_filter();
|
||||||
test_json_escape();
|
test_json_escape();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue