This is an automated email from the ASF dual-hosted git repository.
Mryange pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 8016b3ef9cb [fix](function) Reject overflowing IPv6 uint128 strings
(#68334)
8016b3ef9cb is described below
commit 8016b3ef9cb6d1ff930229083f5977b7985516ce
Author: Mryange <[email protected]>
AuthorDate: Thu Sep 24 09:52:10 2026 +0800
[fix](function) Reject overflowing IPv6 uint128 strings (#68334)
Problem Summary: `ipv6_from_uint128_string_or_null` accepted empty
strings and decimal values larger than `uint128`, causing digit-by-digit
parsing to wrap around and produce an incorrect IPv6 value. Root cause:
the parser performed unchecked multiplication and addition. This change
rejects empty input and checks the value before each decimal
accumulation so invalid input is converted to NULL by the existing
nullable function path.
### Release note
None
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [ ] Regression test
- [ ] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason <!-- Add your reason? -->
- Behavior changed:
- [ ] No.
- [ ] Yes. <!-- Explain the behavior change -->
- Does this need documentation?
- [ ] No.
- [ ] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR
should merge into -->
---
be/src/core/value/ipv6_value.h | 15 ++++++++++++++-
be/test/exprs/function/function_ip_test.cpp | 18 ++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/be/src/core/value/ipv6_value.h b/be/src/core/value/ipv6_value.h
index 394ea7aad14..3a354ba6346 100644
--- a/be/src/core/value/ipv6_value.h
+++ b/be/src/core/value/ipv6_value.h
@@ -17,6 +17,7 @@
#pragma once
+#include <limits>
#include <regex>
#include <sstream>
#include <string>
@@ -43,12 +44,24 @@ public:
bool from_string(const std::string& ipv6_str) { return from_string(_value,
ipv6_str); }
static bool from_uint128_string(IPv6& value, const char* ipv6_str, size_t
len) {
+ if (len == 0) {
+ return false;
+ }
+
+ constexpr IPv6 max_value = std::numeric_limits<IPv6>::max();
+ constexpr IPv6 max_value_div_10 = max_value / 10;
+ constexpr IPv6 max_value_mod_10 = max_value % 10;
value = 0;
for (size_t i = 0; i < len; ++i) {
if (ipv6_str[i] < '0' || ipv6_str[i] > '9') {
return false; // illegal character for uint128
}
- value = value * 10 + (ipv6_str[i] - '0');
+ const auto digit = static_cast<IPv6>(ipv6_str[i] - '0');
+ if (value > max_value_div_10 ||
+ (value == max_value_div_10 && digit > max_value_mod_10)) {
+ return false;
+ }
+ value = value * 10 + digit;
}
return true;
}
diff --git a/be/test/exprs/function/function_ip_test.cpp
b/be/test/exprs/function/function_ip_test.cpp
index 2de8c1eb852..29da803ffec 100644
--- a/be/test/exprs/function/function_ip_test.cpp
+++ b/be/test/exprs/function/function_ip_test.cpp
@@ -80,6 +80,24 @@ TEST(FunctionIpTest, StringToNumRejectsEmbeddedNullTail) {
check_function_all_arg_comb<DataTypeString, true>("inet6_aton",
input_types, ipv6_null_data);
}
+TEST(FunctionIpTest, IPv6FromUInt128StringRejectsEmptyAndOverflow) {
+ const std::string max_uint128 = "340282366920938463463374607431768211455";
+ IPv6 max_value = 0;
+ EXPECT_TRUE(IPv6Value::from_uint128_string(max_value, max_uint128.data(),
max_uint128.size()));
+ EXPECT_EQ(max_value, static_cast<IPv6>(-1));
+
+ for (const auto& value :
+ {std::string("340282366920938463463374607431768211456"),
+ std::string("680564733841876926926749214863536422913"),
std::string()}) {
+ IPv6 parsed = 0;
+ EXPECT_FALSE(IPv6Value::from_uint128_string(parsed, value.data(),
value.size()));
+ }
+
+ IPv6 parsed = 0;
+ EXPECT_TRUE(IPv6Value::from_uint128_string(parsed, "1", 1));
+ EXPECT_EQ(parsed, static_cast<IPv6>(1));
+}
+
TEST(FunctionIpTest, StringToIPv6AcceptsLongIPv4Spellings) {
std::string mapped_ipv4_zero(IPV6_BINARY_LENGTH, '\0');
mapped_ipv4_zero[10] = static_cast<char>(0xff);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]