mirror of
https://github.com/systemd/systemd
synced 2024-09-20 00:21:55 +00:00
Merge pull request #8924 from yuwata/fix-3682
resolve: allow whitespaces in the digest
This commit is contained in:
commit
2407ed7b63
|
@ -77,33 +77,69 @@ char *hexmem(const void *p, size_t l) {
|
|||
return r;
|
||||
}
|
||||
|
||||
int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
|
||||
_cleanup_free_ uint8_t *r = NULL;
|
||||
uint8_t *z;
|
||||
const char *x;
|
||||
static int unhex_next(const char **p, size_t *l) {
|
||||
int r;
|
||||
|
||||
assert(mem);
|
||||
assert(len);
|
||||
assert(p);
|
||||
assert(l);
|
||||
|
||||
/* Find the next non-whitespace character, and decode it. We
|
||||
* greedily skip all preceeding and all following whitespace. */
|
||||
|
||||
for (;;) {
|
||||
if (*l == 0)
|
||||
return -EPIPE;
|
||||
|
||||
if (!strchr(WHITESPACE, **p))
|
||||
break;
|
||||
|
||||
/* Skip leading whitespace */
|
||||
(*p)++, (*l)--;
|
||||
}
|
||||
|
||||
r = unhexchar(**p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (;;) {
|
||||
(*p)++, (*l)--;
|
||||
|
||||
if (*l == 0 || !strchr(WHITESPACE, **p))
|
||||
break;
|
||||
|
||||
/* Skip following whitespace */
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
|
||||
_cleanup_free_ uint8_t *buf = NULL;
|
||||
const char *x;
|
||||
uint8_t *z;
|
||||
|
||||
assert(ret);
|
||||
assert(ret_len);
|
||||
assert(p || l == 0);
|
||||
|
||||
if (l == (size_t) -1)
|
||||
l = strlen(p);
|
||||
|
||||
if (l % 2 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
z = r = malloc((l + 1) / 2 + 1);
|
||||
if (!r)
|
||||
/* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */
|
||||
buf = malloc((l + 1) / 2 + 1);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
for (x = p; x < p + l; x += 2) {
|
||||
for (x = p, z = buf;;) {
|
||||
int a, b;
|
||||
|
||||
a = unhexchar(x[0]);
|
||||
a = unhex_next(&x, &l);
|
||||
if (a == -EPIPE) /* End of string */
|
||||
break;
|
||||
if (a < 0)
|
||||
return a;
|
||||
|
||||
b = unhexchar(x[1]);
|
||||
b = unhex_next(&x, &l);
|
||||
if (b < 0)
|
||||
return b;
|
||||
|
||||
|
@ -112,8 +148,8 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
|
|||
|
||||
*z = 0;
|
||||
|
||||
*mem = TAKE_PTR(r);
|
||||
*len = (l + 1) / 2;
|
||||
*ret_len = (size_t) (z - buf);
|
||||
*ret = TAKE_PTR(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -181,7 +217,7 @@ char *base32hexmem(const void *p, size_t l, bool padding) {
|
|||
|
||||
for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
|
||||
/* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
|
||||
x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
|
||||
* x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
|
||||
*(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
|
||||
*(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
|
||||
*(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
|
||||
|
@ -281,7 +317,7 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
|
|||
}
|
||||
|
||||
/* a group of eight input bytes needs five output bytes, in case of
|
||||
padding we need to add some extra bytes */
|
||||
* padding we need to add some extra bytes */
|
||||
len = (l / 8) * 5;
|
||||
|
||||
switch (l % 8) {
|
||||
|
@ -309,7 +345,7 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
|
|||
|
||||
for (x = p; x < p + (l / 8) * 8; x += 8) {
|
||||
/* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
|
||||
e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
|
||||
* e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
|
||||
a = unbase32hexchar(x[0]);
|
||||
if (a < 0)
|
||||
return -EINVAL;
|
||||
|
@ -665,7 +701,7 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
|
|||
l = strlen(p);
|
||||
|
||||
/* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
|
||||
bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
|
||||
* bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
|
||||
len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0);
|
||||
|
||||
buf = malloc(len + 1);
|
||||
|
@ -733,9 +769,7 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
|
|||
|
||||
*z = 0;
|
||||
|
||||
if (ret_size)
|
||||
*ret_size = (size_t) (z - buf);
|
||||
|
||||
*ret_size = (size_t) (z - buf);
|
||||
*ret = TAKE_PTR(buf);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -656,14 +656,3 @@ int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t siz
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int deserialize_dhcp_option(void **data, size_t *data_len, const char *string) {
|
||||
assert(data);
|
||||
assert(data_len);
|
||||
assert(string);
|
||||
|
||||
if (strlen(string) % 2)
|
||||
return -EINVAL;
|
||||
|
||||
return unhexmem(string, strlen(string), (void **)data, data_len);
|
||||
}
|
||||
|
|
|
@ -78,5 +78,5 @@ struct sd_dhcp_route;
|
|||
void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size);
|
||||
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
|
||||
|
||||
/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
|
||||
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
|
||||
int deserialize_dhcp_option(void **data, size_t *data_len, const char *string);
|
||||
|
|
|
@ -1193,13 +1193,13 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||
}
|
||||
|
||||
if (client_id_hex) {
|
||||
r = deserialize_dhcp_option(&lease->client_id, &lease->client_id_len, client_id_hex);
|
||||
r = unhexmem(client_id_hex, (size_t) -1, &lease->client_id, &lease->client_id_len);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse client ID %s, ignoring: %m", client_id_hex);
|
||||
}
|
||||
|
||||
if (vendor_specific_hex) {
|
||||
r = deserialize_dhcp_option(&lease->vendor_specific, &lease->vendor_specific_len, vendor_specific_hex);
|
||||
r = unhexmem(vendor_specific_hex, (size_t) -1, &lease->vendor_specific, &lease->vendor_specific_len);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex);
|
||||
}
|
||||
|
@ -1211,7 +1211,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||
if (!options[i])
|
||||
continue;
|
||||
|
||||
r = deserialize_dhcp_option(&data, &len, options[i]);
|
||||
r = unhexmem(options[i], (size_t) -1, &data, &len);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to parse private DHCP option %s, ignoring: %m", options[i]);
|
||||
continue;
|
||||
|
|
|
@ -242,18 +242,18 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
|
|||
}
|
||||
|
||||
if (strcaseeq(type, "DS")) {
|
||||
_cleanup_free_ char *key_tag = NULL, *algorithm = NULL, *digest_type = NULL, *digest = NULL;
|
||||
_cleanup_free_ char *key_tag = NULL, *algorithm = NULL, *digest_type = NULL;
|
||||
_cleanup_free_ void *dd = NULL;
|
||||
uint16_t kt;
|
||||
int a, dt;
|
||||
size_t l;
|
||||
|
||||
r = extract_many_words(&p, NULL, 0, &key_tag, &algorithm, &digest_type, &digest, NULL);
|
||||
r = extract_many_words(&p, NULL, 0, &key_tag, &algorithm, &digest_type, NULL);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to parse DS parameters on line %s:%u: %m", path, line);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (r != 4) {
|
||||
if (r != 3) {
|
||||
log_warning("Missing DS parameters on line %s:%u", path, line);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -274,9 +274,14 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = unhexmem(digest, strlen(digest), &dd, &l);
|
||||
if (isempty(p)) {
|
||||
log_warning("Missing DS digest on line %s:%u", path, line);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = unhexmem(p, strlen(p), &dd, &l);
|
||||
if (r < 0) {
|
||||
log_warning("Failed to parse DS digest %s on line %s:%u", digest, path, line);
|
||||
log_warning("Failed to parse DS digest %s on line %s:%u", p, path, line);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -291,16 +296,16 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
|
|||
rr->ds.digest = TAKE_PTR(dd);
|
||||
|
||||
} else if (strcaseeq(type, "DNSKEY")) {
|
||||
_cleanup_free_ char *flags = NULL, *protocol = NULL, *algorithm = NULL, *key = NULL;
|
||||
_cleanup_free_ char *flags = NULL, *protocol = NULL, *algorithm = NULL;
|
||||
_cleanup_free_ void *k = NULL;
|
||||
uint16_t f;
|
||||
size_t l;
|
||||
int a;
|
||||
|
||||
r = extract_many_words(&p, NULL, 0, &flags, &protocol, &algorithm, &key, NULL);
|
||||
r = extract_many_words(&p, NULL, 0, &flags, &protocol, &algorithm, NULL);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to parse DNSKEY parameters on line %s:%u: %m", path, line);
|
||||
if (r != 4) {
|
||||
if (r != 3) {
|
||||
log_warning("Missing DNSKEY parameters on line %s:%u", path, line);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -328,9 +333,14 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = unbase64mem(key, strlen(key), &k, &l);
|
||||
if (isempty(p)) {
|
||||
log_warning("Missing DNSKEY key on line %s:%u", path, line);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = unbase64mem(p, strlen(p), &k, &l);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to parse DNSKEY key data %s on line %s:%u", key, path, line);
|
||||
return log_warning_errno(r, "Failed to parse DNSKEY key data %s on line %s:%u", p, path, line);
|
||||
|
||||
rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, domain);
|
||||
if (!rr)
|
||||
|
@ -347,11 +357,6 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!isempty(p)) {
|
||||
log_warning("Trailing garbage on line %s:%u, ignoring line.", path, line);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&d->positive_by_key, &dns_resource_key_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
|
|
@ -76,20 +76,40 @@ static void test_undecchar(void) {
|
|||
assert_se(undecchar('9') == 9);
|
||||
}
|
||||
|
||||
static void test_unhexmem(void) {
|
||||
const char *hex = "efa2149213";
|
||||
const char *hex_invalid = "efa214921o";
|
||||
_cleanup_free_ char *hex2 = NULL;
|
||||
static void test_unhexmem_one(const char *s, size_t l, int retval) {
|
||||
_cleanup_free_ char *hex = NULL;
|
||||
_cleanup_free_ void *mem = NULL;
|
||||
size_t len;
|
||||
|
||||
assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
|
||||
assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
|
||||
assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == -EINVAL);
|
||||
assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
|
||||
assert_se(unhexmem(s, l, &mem, &len) == retval);
|
||||
if (retval == 0) {
|
||||
char *answer;
|
||||
|
||||
assert_se((hex2 = hexmem(mem, len)));
|
||||
assert_se(streq(hex, hex2));
|
||||
if (l == (size_t) - 1)
|
||||
l = strlen(s);
|
||||
|
||||
assert_se((hex = hexmem(mem, len)));
|
||||
answer = strndupa(s, l);
|
||||
assert_se(streq(delete_chars(answer, WHITESPACE), hex));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_unhexmem(void) {
|
||||
const char *hex = "efa2149213";
|
||||
const char *hex_space = " e f a\n 2\r 14\n\r\t9\t2 \n1\r3 \r\r\t";
|
||||
const char *hex_invalid = "efa214921o";
|
||||
|
||||
test_unhexmem_one(NULL, 0, 0);
|
||||
test_unhexmem_one("", 0, 0);
|
||||
test_unhexmem_one("", (size_t) -1, 0);
|
||||
test_unhexmem_one(" \n \t\r \t\t \n\n\n", (size_t) -1, 0);
|
||||
test_unhexmem_one(hex_invalid, strlen(hex_invalid), -EINVAL);
|
||||
test_unhexmem_one(hex_invalid, (size_t) - 1, -EINVAL);
|
||||
test_unhexmem_one(hex, strlen(hex) - 1, -EPIPE);
|
||||
test_unhexmem_one(hex, strlen(hex), 0);
|
||||
test_unhexmem_one(hex, (size_t) -1, 0);
|
||||
test_unhexmem_one(hex_space, strlen(hex_space), 0);
|
||||
test_unhexmem_one(hex_space, (size_t) -1, 0);
|
||||
}
|
||||
|
||||
/* https://tools.ietf.org/html/rfc4648#section-10 */
|
||||
|
@ -167,94 +187,65 @@ static void test_base32hexmem(void) {
|
|||
free(b32);
|
||||
}
|
||||
|
||||
static void test_unbase32hexmem(void) {
|
||||
void *mem;
|
||||
static void test_unbase32hexmem_one(const char *hex, bool padding, int retval, const char *ans) {
|
||||
_cleanup_free_ void *mem = NULL;
|
||||
size_t len;
|
||||
|
||||
assert_se(unbase32hexmem("", STRLEN(""), true, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), ""));
|
||||
free(mem);
|
||||
assert_se(unbase32hexmem(hex, (size_t) -1, padding, &mem, &len) == retval);
|
||||
if (retval == 0) {
|
||||
char *str;
|
||||
|
||||
assert_se(unbase32hexmem("CO======", STRLEN("CO======"), true, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "f"));
|
||||
free(mem);
|
||||
str = strndupa(mem, len);
|
||||
assert_se(streq(str, ans));
|
||||
}
|
||||
}
|
||||
|
||||
assert_se(unbase32hexmem("CPNG====", STRLEN("CPNG===="), true, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "fo"));
|
||||
free(mem);
|
||||
static void test_unbase32hexmem(void) {
|
||||
test_unbase32hexmem_one("", true, 0, "");
|
||||
|
||||
assert_se(unbase32hexmem("CPNMU===", STRLEN("CPNMU==="), true, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "foo"));
|
||||
free(mem);
|
||||
test_unbase32hexmem_one("CO======", true, 0, "f");
|
||||
test_unbase32hexmem_one("CPNG====", true, 0, "fo");
|
||||
test_unbase32hexmem_one("CPNMU===", true, 0, "foo");
|
||||
test_unbase32hexmem_one("CPNMUOG=", true, 0, "foob");
|
||||
test_unbase32hexmem_one("CPNMUOJ1", true, 0, "fooba");
|
||||
test_unbase32hexmem_one("CPNMUOJ1E8======", true, 0, "foobar");
|
||||
|
||||
assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), true, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "foob"));
|
||||
free(mem);
|
||||
test_unbase32hexmem_one("A", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("A=======", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAA=====", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAAAA==", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AB======", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAB====", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAAB===", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAAAAB=", true, -EINVAL, NULL);
|
||||
|
||||
assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "fooba"));
|
||||
free(mem);
|
||||
test_unbase32hexmem_one("XPNMUOJ1", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CXNMUOJ1", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CPXMUOJ1", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CPNXUOJ1", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CPNMXOJ1", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CPNMUXJ1", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CPNMUOX1", true, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CPNMUOJX", true, -EINVAL, NULL);
|
||||
|
||||
assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), true, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "foobar"));
|
||||
free(mem);
|
||||
test_unbase32hexmem_one("", false, 0, "");
|
||||
test_unbase32hexmem_one("CO", false, 0, "f");
|
||||
test_unbase32hexmem_one("CPNG", false, 0, "fo");
|
||||
test_unbase32hexmem_one("CPNMU", false, 0, "foo");
|
||||
test_unbase32hexmem_one("CPNMUOG", false, 0, "foob");
|
||||
test_unbase32hexmem_one("CPNMUOJ1", false, 0, "fooba");
|
||||
test_unbase32hexmem_one("CPNMUOJ1E8", false, 0, "foobar");
|
||||
test_unbase32hexmem_one("CPNMUOG=", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("CPNMUOJ1E8======", false, -EINVAL, NULL);
|
||||
|
||||
assert_se(unbase32hexmem("A", STRLEN("A"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("A=======", STRLEN("A======="), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAA=====", STRLEN("AAA====="), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAAAA==", STRLEN("AAAAAA=="), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AB======", STRLEN("AB======"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAB====", STRLEN("AAAB===="), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAAB===", STRLEN("AAAAB==="), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAAAAB=", STRLEN("AAAAAAB="), true, &mem, &len) == -EINVAL);
|
||||
|
||||
assert_se(unbase32hexmem("XPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CXNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CPXMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CPNXUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CPNMXOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CPNMUXJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CPNMUOX1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CPNMUOJX", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
|
||||
|
||||
assert_se(unbase32hexmem("", STRLEN(""), false, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), ""));
|
||||
free(mem);
|
||||
|
||||
assert_se(unbase32hexmem("CO", STRLEN("CO"), false, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "f"));
|
||||
free(mem);
|
||||
|
||||
assert_se(unbase32hexmem("CPNG", STRLEN("CPNG"), false, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "fo"));
|
||||
free(mem);
|
||||
|
||||
assert_se(unbase32hexmem("CPNMU", STRLEN("CPNMU"), false, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "foo"));
|
||||
free(mem);
|
||||
|
||||
assert_se(unbase32hexmem("CPNMUOG", STRLEN("CPNMUOG"), false, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "foob"));
|
||||
free(mem);
|
||||
|
||||
assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), false, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "fooba"));
|
||||
free(mem);
|
||||
|
||||
assert_se(unbase32hexmem("CPNMUOJ1E8", STRLEN("CPNMUOJ1E8"), false, &mem, &len) == 0);
|
||||
assert_se(streq(strndupa(mem, len), "foobar"));
|
||||
free(mem);
|
||||
|
||||
assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAA", STRLEN("AAA"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAAAA", STRLEN("AAAAAA"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AB", STRLEN("AB"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAB", STRLEN("AAAB"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAAB", STRLEN("AAAAB"), false, &mem, &len) == -EINVAL);
|
||||
assert_se(unbase32hexmem("AAAAAAB", STRLEN("AAAAAAB"), false, &mem, &len) == -EINVAL);
|
||||
test_unbase32hexmem_one("A", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("A", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAA", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAAAA", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AB", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAB", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAAB", false, -EINVAL, NULL);
|
||||
test_unbase32hexmem_one("AAAAAAB", false, -EINVAL, NULL);
|
||||
}
|
||||
|
||||
/* https://tools.ietf.org/html/rfc4648#section-10 */
|
||||
|
|
Loading…
Reference in a new issue