diff --git a/common/json.c b/common/json.c index d1685c56f..67cc1e60e 100644 --- a/common/json.c +++ b/common/json.c @@ -41,6 +41,28 @@ bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str) return strncmp(buffer + tok->start, str, tok->end - tok->start) == 0; } +bool json_tok_startswith(const char *buffer, const jsmntok_t *tok, + const char *prefix) +{ + if (tok->type != JSMN_STRING) + return false; + if (tok->end - tok->start < strlen(prefix)) + return false; + return memcmp(buffer + tok->start, + prefix, strlen(prefix)) == 0; +} + +bool json_tok_endswith(const char *buffer, const jsmntok_t *tok, + const char *suffix) +{ + if (tok->type != JSMN_STRING) + return false; + if (tok->end - tok->start < strlen(suffix)) + return false; + return memcmp(buffer + tok->end - strlen(suffix), + suffix, strlen(suffix)) == 0; +} + char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) { return tal_strndup(ctx, buffer + tok->start, tok->end - tok->start); diff --git a/common/json.h b/common/json.h index c9c2f6613..19ce012a9 100644 --- a/common/json.h +++ b/common/json.h @@ -26,6 +26,14 @@ int json_tok_full_len(const jsmntok_t *t); /* Is this a string equal to str? */ bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str); +/* Does this string token start with prefix? */ +bool json_tok_startswith(const char *buffer, const jsmntok_t *tok, + const char *prefix); + +/* Does this string token end with suffix? */ +bool json_tok_endswith(const char *buffer, const jsmntok_t *tok, + const char *suffix); + /* Allocate a tal string copy */ char *json_strdup(const tal_t *ctx, const char *buffer, const jsmntok_t *tok); diff --git a/common/json_tok.c b/common/json_tok.c index 17d094032..2a5e5dbd4 100644 --- a/common/json_tok.c +++ b/common/json_tok.c @@ -313,41 +313,28 @@ struct command_result *param_feerate_val(struct command *cmd, const jsmntok_t *tok, u32 **feerate_per_kw) { - jsmntok_t base = *tok, suffix = *tok; + jsmntok_t base = *tok; enum feerate_style style; unsigned int num; - /* We have to split the number and suffix. */ - suffix.start = suffix.end; - while (suffix.start > base.start && !isdigit(buffer[suffix.start-1])) { - suffix.start--; - base.end--; - } + if (json_tok_endswith(buffer, tok, + feerate_style_name(FEERATE_PER_KBYTE))) { + style = FEERATE_PER_KBYTE; + base.end -= strlen(feerate_style_name(FEERATE_PER_KBYTE)); + } else if (json_tok_endswith(buffer, tok, + feerate_style_name(FEERATE_PER_KSIPA))) { + style = FEERATE_PER_KSIPA; + base.end -= strlen(feerate_style_name(FEERATE_PER_KSIPA)); + } else + style = FEERATE_PER_KBYTE; if (!json_to_number(buffer, &base, &num)) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%s' prefix should be an integer, not '%.*s'", + "'%s' should be an integer with optional perkw/perkb, not '%.*s'", name, base.end - base.start, buffer + base.start); } - if (suffix.end == suffix.start - || json_tok_streq(buffer, &suffix, - feerate_style_name(FEERATE_PER_KBYTE))) { - style = FEERATE_PER_KBYTE; - } else if (json_tok_streq(buffer, &suffix, - feerate_style_name(FEERATE_PER_KSIPA))) { - style = FEERATE_PER_KSIPA; - } else { - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%s' suffix should be '%s' or '%s', not '%.*s'", - name, - feerate_style_name(FEERATE_PER_KSIPA), - feerate_style_name(FEERATE_PER_KBYTE), - suffix.end - suffix.start, - buffer + suffix.start); - } - *feerate_per_kw = tal(cmd, u32); **feerate_per_kw = feerate_from_style(num, style); if (**feerate_per_kw < FEERATE_FLOOR)