mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
bolt11: undo json encoding for description bytes.
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 <rusty@rustcorp.com.au>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
@@ -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)) {
|
||||
@@ -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",
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user