X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Frune%2Fcoding.c;h=495d37c34e313e6a754f9e310f7d74a77f22e522;hb=HEAD;hp=201553d8b5e65239cdfb1260b2a7d684cecce384;hpb=8275faaf2fa6989829c976a54da120def4cfeda8;p=ccan diff --git a/ccan/rune/coding.c b/ccan/rune/coding.c index 201553d8..495d37c3 100644 --- a/ccan/rune/coding.c +++ b/ccan/rune/coding.c @@ -98,7 +98,7 @@ static void rune_altern_encode(const struct rune_altern *altern, break; esc[1] = p[len]; cb(esc, 2, arg); - p++; + p += len + 1; } } @@ -184,7 +184,7 @@ static bool pull_char(const char **data, size_t *len, char *c) return true; } -static bool is_valid_cond(enum rune_condition cond) +bool rune_condition_is_valid(enum rune_condition cond) { switch (cond) { case RUNE_COND_IF_MISSING: @@ -203,31 +203,35 @@ static bool is_valid_cond(enum rune_condition cond) return false; } +size_t rune_altern_fieldname_len(const char *alternstr, size_t alternstrlen) +{ + for (size_t i = 0; i < alternstrlen; i++) { + if (cispunct(alternstr[i]) && alternstr[i] != '_') + return i; + } + return alternstrlen; +} + /* Sets *more on success: true if another altern follows */ static struct rune_altern *rune_altern_decode(const tal_t *ctx, const char **data, size_t *len, bool *more) { struct rune_altern *alt = tal(ctx, struct rune_altern); - const char *strstart = *data; char *value; - size_t strlen = 0; + size_t strlen; char c; - /* Swallow field up to conditional */ - for (;;) { - if (!pull_char(data, len, &c)) - return tal_free(alt); - if (cispunct(c)) - break; - strlen++; - } + /* Swallow field up to possible conditional */ + strlen = rune_altern_fieldname_len(*data, *len); + alt->fieldname = tal_strndup(alt, *data, strlen); + *data += strlen; + *len -= strlen; - alt->fieldname = tal_strndup(alt, strstart, strlen); - if (!is_valid_cond(c)) { - pull_invalid(data, len); + /* Grab conditional */ + if (!pull_char(data, len, &c) || !rune_condition_is_valid(c)) return tal_free(alt); - } + alt->condition = c; /* Assign worst case. */ @@ -306,9 +310,9 @@ static struct rune *from_string(const tal_t *ctx, } struct rune_restr *rune_restr_from_string(const tal_t *ctx, - const char *str) + const char *str, + size_t len) { - size_t len = strlen(str); struct rune_restr *restr; restr = rune_restr_decode(NULL, &str, &len); @@ -334,26 +338,26 @@ static void to_string(struct wbuf *wbuf, const struct rune *rune, u8 *hash32) to_wbuf("", 1, wbuf); } -struct rune *rune_from_base64(const tal_t *ctx, const char *str) +struct rune *rune_from_base64n(const tal_t *ctx, const char *str, size_t len) { - size_t len; + size_t blen; u8 *data; struct rune *rune; - data = tal_arr(NULL, u8, base64_decoded_length(strlen(str)) + 1); + data = tal_arr(NULL, u8, base64_decoded_length(len) + 1); - len = base64_decode_using_maps(&base64_maps_urlsafe, + blen = base64_decode_using_maps(&base64_maps_urlsafe, (char *)data, tal_bytelen(data), - str, strlen(str)); - if (len == -1) + str, len); + if (blen == -1) goto fail; - - if (len < 32) + + if (blen < 32) goto fail; - data[len] = '\0'; + data[blen] = '\0'; /* Sanity check that it's a valid string! */ - if (strlen((char *)data + 32) != len - 32) + if (strlen((char *)data + 32) != blen - 32) goto fail; rune = from_string(ctx, (const char *)data + 32, data); @@ -365,6 +369,11 @@ fail: return NULL; } +struct rune *rune_from_base64(const tal_t *ctx, const char *str) +{ + return rune_from_base64n(ctx, str, strlen(str)); +} + char *rune_to_base64(const tal_t *ctx, const struct rune *rune) { u8 hash32[32];