Change sodium_ip2bin to take the ip length

This commit is contained in:
Frank Denis
2026-01-06 15:42:08 +01:00
parent 7df634f2c5
commit 7fcc982618
4 changed files with 78 additions and 45 deletions
+2 -2
View File
@@ -93,8 +93,8 @@ int sodium_base642bin(unsigned char *const bin, const size_t bin_maxlen, const c
const char **const b64_end, const int variant) __attribute__((nonnull(1)));
SODIUM_EXPORT
int sodium_ip2bin(unsigned char out[16], const char *src) __attribute__((warn_unused_result))
__attribute__((nonnull));
int sodium_ip2bin(unsigned char out[16], const char *src, size_t src_len)
__attribute__((warn_unused_result)) __attribute__((nonnull));
SODIUM_EXPORT
char *sodium_bin2ip(char *dst, size_t dst_len, const unsigned char in[16])
+6 -5
View File
@@ -474,17 +474,18 @@ parse_ipv6(const char *src, const char *end, unsigned char out[16])
}
int
sodium_ip2bin(unsigned char out[16], const char *src)
sodium_ip2bin(unsigned char out[16], const char *src, size_t src_len)
{
const char *src_end = src + src_len;
const char *end;
const char *z;
unsigned char v4[4];
for (end = src; *end != 0 && *end != '%'; end++) {
for (end = src; end < src_end && *end != 0 && *end != '%'; end++) {
/* empty */
}
if (*end == '%') {
for (z = end + 1; *z != 0; z++) {
if (end < src_end && *end == '%') {
for (z = end + 1; z < src_end && *z != 0; z++) {
if (isspace((unsigned char) *z)) {
return -1;
}
@@ -496,7 +497,7 @@ sodium_ip2bin(unsigned char out[16], const char *src)
if (memchr(src, ':', (size_t) (end - src)) != NULL) {
return parse_ipv6(src, end, out) != 0 ? 0 : -1;
}
if (*end == '%') {
if (end < src_end && *end == '%') {
return -1;
}
if (parse_ipv4(src, end, v4) == 0) {
+68 -38
View File
@@ -253,7 +253,7 @@ main(void)
unsigned char ip_expected[16];
char ip_str[46];
assert(sodium_ip2bin(ip_bytes, "192.168.1.1") == 0);
assert(sodium_ip2bin(ip_bytes, "192.168.1.1", strlen("192.168.1.1")) == 0);
memset(ip_expected, 0, 10);
ip_expected[10] = 0xff;
ip_expected[11] = 0xff;
@@ -264,23 +264,23 @@ main(void)
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
printf("ip2bytes(192.168.1.1): OK\n");
assert(sodium_ip2bin(ip_bytes, "0.0.0.0") == 0);
assert(sodium_ip2bin(ip_bytes, "255.255.255.255") == 0);
assert(sodium_ip2bin(ip_bytes, "127.0.0.1") == 0);
assert(sodium_ip2bin(ip_bytes, "0.0.0.0", strlen("0.0.0.0")) == 0);
assert(sodium_ip2bin(ip_bytes, "255.255.255.255", strlen("255.255.255.255")) == 0);
assert(sodium_ip2bin(ip_bytes, "127.0.0.1", strlen("127.0.0.1")) == 0);
printf("ip2bytes IPv4 basic: OK\n");
assert(sodium_ip2bin(ip_bytes, "256.1.1.1") == -1);
assert(sodium_ip2bin(ip_bytes, "1.999.1.1") == -1);
assert(sodium_ip2bin(ip_bytes, "192.168.1") == -1);
assert(sodium_ip2bin(ip_bytes, "192.168.1.1.1") == -1);
assert(sodium_ip2bin(ip_bytes, "") == -1);
assert(sodium_ip2bin(ip_bytes, ".1.2.3") == -1);
assert(sodium_ip2bin(ip_bytes, "1.2.3.") == -1);
assert(sodium_ip2bin(ip_bytes, "1..2.3") == -1);
assert(sodium_ip2bin(ip_bytes, "1.2.a.3") == -1);
assert(sodium_ip2bin(ip_bytes, "256.1.1.1", strlen("256.1.1.1")) == -1);
assert(sodium_ip2bin(ip_bytes, "1.999.1.1", strlen("1.999.1.1")) == -1);
assert(sodium_ip2bin(ip_bytes, "192.168.1", strlen("192.168.1")) == -1);
assert(sodium_ip2bin(ip_bytes, "192.168.1.1.1", strlen("192.168.1.1.1")) == -1);
assert(sodium_ip2bin(ip_bytes, "", 0) == -1);
assert(sodium_ip2bin(ip_bytes, ".1.2.3", strlen(".1.2.3")) == -1);
assert(sodium_ip2bin(ip_bytes, "1.2.3.", strlen("1.2.3.")) == -1);
assert(sodium_ip2bin(ip_bytes, "1..2.3", strlen("1..2.3")) == -1);
assert(sodium_ip2bin(ip_bytes, "1.2.a.3", strlen("1.2.a.3")) == -1);
printf("ip2bytes IPv4 invalid: OK\n");
assert(sodium_ip2bin(ip_bytes, "2001:db8:85a3:0:0:8a2e:370:7334") == 0);
assert(sodium_ip2bin(ip_bytes, "2001:db8:85a3:0:0:8a2e:370:7334", strlen("2001:db8:85a3:0:0:8a2e:370:7334")) == 0);
ip_expected[0] = 0x20; ip_expected[1] = 0x01;
ip_expected[2] = 0x0d; ip_expected[3] = 0xb8;
ip_expected[4] = 0x85; ip_expected[5] = 0xa3;
@@ -292,34 +292,34 @@ main(void)
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
printf("ip2bytes(2001:db8:85a3:0:0:8a2e:370:7334): OK\n");
assert(sodium_ip2bin(ip_bytes, "::1") == 0);
assert(sodium_ip2bin(ip_bytes, "::1", strlen("::1")) == 0);
memset(ip_expected, 0, 16);
ip_expected[15] = 1;
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
assert(sodium_ip2bin(ip_bytes, "::") == 0);
assert(sodium_ip2bin(ip_bytes, "::", strlen("::")) == 0);
memset(ip_expected, 0, 16);
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
assert(sodium_ip2bin(ip_bytes, "2001:db8::1") == 0);
assert(sodium_ip2bin(ip_bytes, "fe80::1") == 0);
assert(sodium_ip2bin(ip_bytes, "2001:db8::1", strlen("2001:db8::1")) == 0);
assert(sodium_ip2bin(ip_bytes, "fe80::1", strlen("fe80::1")) == 0);
printf("ip2bytes IPv6 compressed: OK\n");
assert(sodium_ip2bin(ip_bytes, "fe80::1%eth0") == 0);
assert(sodium_ip2bin(ip_bytes, "fe80::1%15") == 0);
assert(sodium_ip2bin(ip_bytes, "fe80::1%eth0", strlen("fe80::1%eth0")) == 0);
assert(sodium_ip2bin(ip_bytes, "fe80::1%15", strlen("fe80::1%15")) == 0);
printf("ip2bytes IPv6 zone: OK\n");
assert(sodium_ip2bin(ip_bytes, "2001:::1") == -1);
assert(sodium_ip2bin(ip_bytes, "2001::1::1") == -1);
assert(sodium_ip2bin(ip_bytes, "1:2:3:4:5:6:7:8:9") == -1);
assert(sodium_ip2bin(ip_bytes, "12345:1:1:1:1:1:1:1") == -1);
assert(sodium_ip2bin(ip_bytes, "2001:db8:g:1:1:1:1:1") == -1);
assert(sodium_ip2bin(ip_bytes, ":2001:db8::1") == -1);
assert(sodium_ip2bin(ip_bytes, "2001:db8:1:") == -1);
assert(sodium_ip2bin(ip_bytes, "fe80::1%") == -1);
assert(sodium_ip2bin(ip_bytes, "2001:::1", strlen("2001:::1")) == -1);
assert(sodium_ip2bin(ip_bytes, "2001::1::1", strlen("2001::1::1")) == -1);
assert(sodium_ip2bin(ip_bytes, "1:2:3:4:5:6:7:8:9", strlen("1:2:3:4:5:6:7:8:9")) == -1);
assert(sodium_ip2bin(ip_bytes, "12345:1:1:1:1:1:1:1", strlen("12345:1:1:1:1:1:1:1")) == -1);
assert(sodium_ip2bin(ip_bytes, "2001:db8:g:1:1:1:1:1", strlen("2001:db8:g:1:1:1:1:1")) == -1);
assert(sodium_ip2bin(ip_bytes, ":2001:db8::1", strlen(":2001:db8::1")) == -1);
assert(sodium_ip2bin(ip_bytes, "2001:db8:1:", strlen("2001:db8:1:")) == -1);
assert(sodium_ip2bin(ip_bytes, "fe80::1%", strlen("fe80::1%")) == -1);
printf("ip2bytes IPv6 invalid: OK\n");
assert(sodium_ip2bin(ip_bytes, "::ffff:192.168.1.1") == 0);
assert(sodium_ip2bin(ip_bytes, "::ffff:192.168.1.1", strlen("::ffff:192.168.1.1")) == 0);
memset(ip_expected, 0, 10);
ip_expected[10] = 0xff;
ip_expected[11] = 0xff;
@@ -390,28 +390,28 @@ main(void)
assert(sodium_bin2ip(ip_str, 2, ip_bytes) == NULL);
printf("bytes2ip buffer size: OK\n");
assert(sodium_ip2bin(ip_bytes, "10.20.30.40") == 0);
assert(sodium_ip2bin(ip_bytes, "10.20.30.40", strlen("10.20.30.40")) == 0);
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
assert(strcmp(ip_str, "10.20.30.40") == 0);
assert(sodium_ip2bin(ip_bytes, "::1") == 0);
assert(sodium_ip2bin(ip_bytes, "::1", strlen("::1")) == 0);
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
assert(strcmp(ip_str, "::1") == 0);
assert(sodium_ip2bin(ip_bytes, "2001:db8::1") == 0);
assert(sodium_ip2bin(ip_bytes, "2001:db8::1", strlen("2001:db8::1")) == 0);
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
assert(strcmp(ip_str, "2001:db8::1") == 0);
assert(sodium_ip2bin(ip_bytes, "2001:db8:85a3:1234:5678:8a2e:370:7334") == 0);
assert(sodium_ip2bin(ip_bytes, "2001:db8:85a3:1234:5678:8a2e:370:7334", strlen("2001:db8:85a3:1234:5678:8a2e:370:7334")) == 0);
assert(sodium_bin2ip(ip_str, sizeof(ip_str), ip_bytes) != NULL);
assert(strcmp(ip_str, "2001:db8:85a3:1234:5678:8a2e:370:7334") == 0);
printf("ip round-trip: OK\n");
{
unsigned char lower[16], upper[16], mixed[16];
assert(sodium_ip2bin(lower, "abcd:ef01:2345:6789:abcd:ef01:2345:6789") == 0);
assert(sodium_ip2bin(upper, "ABCD:EF01:2345:6789:ABCD:EF01:2345:6789") == 0);
assert(sodium_ip2bin(mixed, "AbCd:eF01:2345:6789:aBcD:Ef01:2345:6789") == 0);
assert(sodium_ip2bin(lower, "abcd:ef01:2345:6789:abcd:ef01:2345:6789", strlen("abcd:ef01:2345:6789:abcd:ef01:2345:6789")) == 0);
assert(sodium_ip2bin(upper, "ABCD:EF01:2345:6789:ABCD:EF01:2345:6789", strlen("ABCD:EF01:2345:6789:ABCD:EF01:2345:6789")) == 0);
assert(sodium_ip2bin(mixed, "AbCd:eF01:2345:6789:aBcD:Ef01:2345:6789", strlen("AbCd:eF01:2345:6789:aBcD:Ef01:2345:6789")) == 0);
assert(memcmp(lower, upper, 16) == 0);
assert(memcmp(lower, mixed, 16) == 0);
}
@@ -419,11 +419,41 @@ main(void)
{
unsigned char direct[16], mapped[16];
assert(sodium_ip2bin(direct, "192.168.1.1") == 0);
assert(sodium_ip2bin(mapped, "::ffff:192.168.1.1") == 0);
assert(sodium_ip2bin(direct, "192.168.1.1", strlen("192.168.1.1")) == 0);
assert(sodium_ip2bin(mapped, "::ffff:192.168.1.1", strlen("::ffff:192.168.1.1")) == 0);
assert(memcmp(direct, mapped, 16) == 0);
}
printf("ip IPv4-mapped equivalence: OK\n");
{
unsigned char ip1[16], ip2[16];
assert(sodium_ip2bin(ip1, "192.168.1.1", 100) == 0);
assert(sodium_ip2bin(ip2, "192.168.1.1", strlen("192.168.1.1")) == 0);
assert(memcmp(ip1, ip2, 16) == 0);
assert(sodium_ip2bin(ip1, "::1", 100) == 0);
assert(sodium_ip2bin(ip2, "::1", strlen("::1")) == 0);
assert(memcmp(ip1, ip2, 16) == 0);
assert(sodium_ip2bin(ip1, "fe80::1%eth0", 100) == 0);
assert(sodium_ip2bin(ip2, "fe80::1%eth0", strlen("fe80::1%eth0")) == 0);
assert(memcmp(ip1, ip2, 16) == 0);
}
printf("ip src_len larger than string: OK\n");
{
unsigned char ip_bytes[16], ip_expected[16];
assert(sodium_ip2bin(ip_bytes, "192.168.1.1", 3) == -1);
assert(sodium_ip2bin(ip_bytes, "192.168.1.1", 10) == -1);
assert(sodium_ip2bin(ip_bytes, "2001:db8::1", 5) == -1);
assert(sodium_ip2bin(ip_bytes, "::1", 2) == 0);
memset(ip_expected, 0, 16);
assert(memcmp(ip_bytes, ip_expected, 16) == 0);
}
printf("ip src_len shorter than IP: OK\n");
}
return 0;
+2
View File
@@ -43,3 +43,5 @@ bytes2ip buffer size: OK
ip round-trip: OK
ip case insensitive: OK
ip IPv4-mapped equivalence: OK
ip src_len larger than string: OK
ip src_len shorter than IP: OK