Skip to content

Commit

Permalink
bolt11: undo json encoding for description bytes.
Browse files Browse the repository at this point in the history
We don't handle \u, since we assume everyone sane is using UTF-8.  We'd
still have to reject '\u0000' and maybe other weird cases if we did.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Mar 26, 2018
1 parent 54431d2 commit 9f7d431
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 11 deletions.
44 changes: 44 additions & 0 deletions common/json_escaped.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,47 @@ struct json_escaped *json_escape(const tal_t *ctx, const char *str TAKES)
tal_free(str);
return esc;
}

/* By policy, we don't handle \u. Use UTF-8. */
const char *json_escaped_unescape(const tal_t *ctx,
const struct json_escaped *esc)
{
char *unesc = tal_arr(ctx, char, strlen(esc->s) + 1);
size_t i, n;

for (i = n = 0; esc->s[i]; i++, n++) {
if (esc->s[i] != '\\') {
unesc[n] = esc->s[i];
continue;
}

i++;
switch (esc->s[i]) {
case 'n':
unesc[n] = '\n';
break;
case 'b':
unesc[n] = '\b';
break;
case 'f':
unesc[n] = '\f';
break;
case 't':
unesc[n] = '\t';
break;
case 'r':
unesc[n] = '\r';
break;
case '/':
case '\\':
case '"':
unesc[n] = esc->s[i];
break;
default:
return tal_free(unesc);
}
}

unesc[n] = '\0';
return unesc;
}
3 changes: 3 additions & 0 deletions common/json_escaped.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ void json_add_escaped_string(struct json_result *result,
struct json_escaped *json_escaped_string_(const tal_t *ctx,
const void *bytes, size_t len);

/* Be very careful here! Can fail! Doesn't handle \u: use UTF-8 please. */
const char *json_escaped_unescape(const tal_t *ctx,
const struct json_escaped *esc);
#endif /* LIGHTNING_COMMON_JSON_ESCAPED_H */
2 changes: 1 addition & 1 deletion devtools/bolt11-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int main(int argc, char *argv[])
if (b11->msatoshi)
printf("msatoshi: %"PRIu64"\n", *b11->msatoshi);
if (b11->description)
printf("description: %s\n", b11->description);
printf("description: '%s'\n", b11->description);
if (b11->description_hash)
printf("description_hash: %s\n",
tal_hexstr(ctx, b11->description_hash,
Expand Down
35 changes: 25 additions & 10 deletions lightningd/invoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ static void json_invoice(struct command *cmd,
{
struct invoice invoice;
struct invoice_details details;
jsmntok_t *msatoshi, *label, *desc, *exp, *fallback;
jsmntok_t *msatoshi, *label, *desctok, *exp, *fallback;
u64 *msatoshi_val;
const struct json_escaped *label_val;
const struct json_escaped *label_val, *desc;
const char *desc_val;
enum address_parse_result fallback_parse;
struct json_result *response = new_json_result(cmd);
Expand All @@ -125,7 +125,7 @@ static void json_invoice(struct command *cmd,
if (!json_get_params(cmd, buffer, params,
"msatoshi", &msatoshi,
"label", &label,
"description", &desc,
"description", &desctok,
"?expiry", &exp,
"?fallback", &fallback,
NULL)) {
Expand Down Expand Up @@ -163,18 +163,31 @@ static void json_invoice(struct command *cmd,
INVOICE_MAX_LABEL_LEN);
return;
}

desc = json_tok_escaped_string(cmd, buffer, desctok);
if (!desc) {
command_fail(cmd, "description '%.*s' not a string",
desctok->end - desctok->start,
buffer + desctok->start);
return;
}
desc_val = json_escaped_unescape(cmd, desc);
if (!desc_val) {
command_fail(cmd, "description '%s' is invalid"
" (note: we don't allow \\u)",
desc->s);
return;
}
/* description */
if (desc->end - desc->start >= BOLT11_FIELD_BYTE_LIMIT) {
if (strlen(desc_val) >= BOLT11_FIELD_BYTE_LIMIT) {
command_fail(cmd,
"Descriptions greater than %d bytes "
"not yet supported "
"(description length %d)",
"(description length %zu)",
BOLT11_FIELD_BYTE_LIMIT,
desc->end - desc->start);
strlen(desc_val));
return;
}
desc_val = tal_strndup(cmd, buffer + desc->start,
desc->end - desc->start);
/* expiry */
if (exp && !json_tok_u64(buffer, exp, &expiry)) {
command_fail(cmd, "Expiry '%.*s' invalid seconds",
Expand Down Expand Up @@ -629,8 +642,10 @@ static void json_decodepay(struct command *cmd,
json_add_pubkey(response, "payee", &b11->receiver_id);
if (b11->msatoshi)
json_add_u64(response, "msatoshi", *b11->msatoshi);
if (b11->description)
json_add_string(response, "description", b11->description);
if (b11->description) {
struct json_escaped *esc = json_escape(NULL, b11->description);
json_add_escaped_string(response, "description", take(esc));
}
if (b11->description_hash)
json_add_hex(response, "description_hash",
b11->description_hash,
Expand Down

0 comments on commit 9f7d431

Please sign in to comment.