]> git.ozlabs.org Git - ccan/blobdiff - ccan/rune/coding.c
base64: fix for unsigned chars (e.g. ARM).
[ccan] / ccan / rune / coding.c
index 201553d8b5e65239cdfb1260b2a7d684cecce384..495d37c34e313e6a754f9e310f7d74a77f22e522 100644 (file)
@@ -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];