CCAN: update to get latest rune decode fix.
We didn't handle \ in fields properly, unless they were one-char long. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
897245e3b7
commit
1f9730748c
@@ -1,3 +1,3 @@
|
||||
CCAN imported from http://ccodearchive.net.
|
||||
|
||||
CCAN version: init-2545-g7b11e744
|
||||
CCAN version: init-2548-gab87e56b
|
||||
|
||||
@@ -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]))
|
||||
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. */
|
||||
|
||||
@@ -376,4 +376,25 @@ char *rune_to_string(const tal_t *ctx, const struct rune *rune);
|
||||
struct rune_restr *rune_restr_from_string(const tal_t *ctx,
|
||||
const char *str,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* rune_condition_is_valid: is this a valid condition?
|
||||
* @cond: potential condition character.
|
||||
*
|
||||
* Returns true if it's one of enum rune_condition.
|
||||
*/
|
||||
bool rune_condition_is_valid(enum rune_condition cond);
|
||||
|
||||
/**
|
||||
* rune_altern_fieldname_len: how much of this string is condition?
|
||||
* @alternstr: potential alternative string
|
||||
* @alternstrlen: length
|
||||
*
|
||||
* This helps parsing your own runes.
|
||||
*
|
||||
* Returns the first possible condition (check with rune_condition_is_valid)
|
||||
* or alternstrlen if none found.
|
||||
*/
|
||||
size_t rune_altern_fieldname_len(const char *alternstr, size_t alternstrlen);
|
||||
|
||||
#endif /* CCAN_RUNE_RUNE_H */
|
||||
|
||||
37
ccan/ccan/rune/test/run-altern-escape.c
Normal file
37
ccan/ccan/rune/test/run-altern-escape.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <ccan/rune/rune.c>
|
||||
#include <ccan/rune/coding.c>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/tap/tap.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static const u8 secret_zero[16];
|
||||
struct rune *rune;
|
||||
struct rune_restr *restr;
|
||||
const tal_t *ctx = tal(NULL, char);
|
||||
|
||||
plan_tests(9);
|
||||
restr = rune_restr_from_string(ctx, "desc=@tipjar\\|jb55@sendsats.lol",
|
||||
strlen("desc=@tipjar\\|jb55@sendsats.lol"));
|
||||
ok1(tal_count(restr->alterns) == 1);
|
||||
ok1(restr->alterns[0]->condition == '=');
|
||||
ok1(streq(restr->alterns[0]->fieldname, "desc"));
|
||||
ok1(streq(restr->alterns[0]->value, "@tipjar|jb55@sendsats.lol"));
|
||||
|
||||
rune = rune_new(ctx, secret_zero, sizeof(secret_zero), NULL);
|
||||
rune_add_restr(rune, take(restr));
|
||||
|
||||
/* Converting via base64 should not change it! */
|
||||
rune = rune_from_base64(ctx, rune_to_base64(ctx, rune));
|
||||
ok1(tal_count(rune->restrs) == 1);
|
||||
restr = rune->restrs[0];
|
||||
ok1(tal_count(restr->alterns) == 1);
|
||||
ok1(restr->alterns[0]->condition == '=');
|
||||
ok1(streq(restr->alterns[0]->fieldname, "desc"));
|
||||
ok1(streq(restr->alterns[0]->value, "@tipjar|jb55@sendsats.lol"));
|
||||
|
||||
tal_free(ctx);
|
||||
/* This exits depending on whether all tests passed */
|
||||
return exit_status();
|
||||
}
|
||||
@@ -83,12 +83,12 @@ int main(void)
|
||||
ok1(rune_is_derived_anyversion(rune1, rune2) == NULL);
|
||||
|
||||
restr = rune_restr_new(NULL);
|
||||
for (size_t i = 4; parts[i]; i+=3) {
|
||||
for (size_t j = 4; parts[j]; j+=3) {
|
||||
struct rune_altern *alt;
|
||||
alt = rune_altern_new(NULL,
|
||||
parts[i],
|
||||
parts[i+1][0],
|
||||
parts[i+2]);
|
||||
parts[j],
|
||||
parts[j+1][0],
|
||||
parts[j+2]);
|
||||
rune_restr_add_altern(restr, take(alt));
|
||||
}
|
||||
rune_add_restr(rune1, take(restr));
|
||||
|
||||
@@ -777,7 +777,7 @@ void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
|
||||
(void)taken(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!adjust_size(&nbytes, n)) {
|
||||
if (taken(p))
|
||||
tal_free(p);
|
||||
|
||||
Reference in New Issue
Block a user