From 5766a9acd30319e572dd67384ed373b26040cd7b Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 5 Jan 2026 23:09:32 +0100 Subject: [PATCH] Change sodium_ip2bin to take the ip length --- src/libsodium/include/sodium/utils.h | 4 +- src/libsodium/sodium/codecs.c | 11 +-- test/default/codecs.c | 106 +++++++++++++++++---------- test/default/codecs.exp | 2 + 4 files changed, 78 insertions(+), 45 deletions(-) diff --git a/src/libsodium/include/sodium/utils.h b/src/libsodium/include/sodium/utils.h index 9825911f..175ac573 100644 --- a/src/libsodium/include/sodium/utils.h +++ b/src/libsodium/include/sodium/utils.h @@ -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]) diff --git a/src/libsodium/sodium/codecs.c b/src/libsodium/sodium/codecs.c index 6f2f0ccf..fb33e99c 100644 --- a/src/libsodium/sodium/codecs.c +++ b/src/libsodium/sodium/codecs.c @@ -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) { diff --git a/test/default/codecs.c b/test/default/codecs.c index e36ed685..6119e28f 100644 --- a/test/default/codecs.c +++ b/test/default/codecs.c @@ -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; diff --git a/test/default/codecs.exp b/test/default/codecs.exp index e5a504ae..cbeb914a 100644 --- a/test/default/codecs.exp +++ b/test/default/codecs.exp @@ -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