This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 3020271a76a8670ff20d140778c7febaafba7040
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Sep 24 09:21:11 2026 +0800

    branch-4.1: [fix](function) Handle odd-byte IPv6 truncation #68109 (#68414)
    
    Cherry-picked from #68109
    
    Co-authored-by: Mryange <[email protected]>
---
 be/src/exec/common/format_ip.h              | 11 ++++++++---
 be/test/exprs/function/function_ip_test.cpp | 11 +++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/be/src/exec/common/format_ip.h b/be/src/exec/common/format_ip.h
index 42e6cc918f2..54a78e3eeca 100644
--- a/be/src/exec/common/format_ip.h
+++ b/be/src/exec/common/format_ip.h
@@ -234,7 +234,7 @@ inline void print_integer(char*& out, T value) {
   * bounds checking, unnecessary string copying and length calculation.
   * @param src         - pointer to IPv6 (16 bytes) stored in little-endian 
byte order
   * @param dst         - where to put format result bytes
-  * @param zeroed_tail_bytes_count - the parameter is currently not being used
+  * @param zeroed_tail_bytes_count - number of bytes to zero from the address 
tail
   */
 inline void format_ipv6(unsigned char* src, char*& dst, uint8_t 
zeroed_tail_bytes_count = 0) {
     struct {
@@ -251,8 +251,13 @@ inline void format_ipv6(unsigned char* src, char*& dst, 
uint8_t zeroed_tail_byte
     /** Preprocess:
         *    Copy the input (bytewise) array into a wordwise array.
         *    Find the longest run of 0x00's in src[] for :: shorthanding. */
-    for (size_t i = 0; i < (IPV6_BINARY_LENGTH - zeroed_tail_bytes_count); i 
+= 2) {
-        words[i / 2] = (uint16_t)(src[i] << 8) | src[i + 1];
+    const size_t remaining_bytes = IPV6_BINARY_LENGTH - 
zeroed_tail_bytes_count;
+    for (size_t i = 0; i + 1 < remaining_bytes; i += 2) {
+        words[i / 2] = static_cast<UInt16>((static_cast<UInt16>(src[i]) << 8) 
| src[i + 1]);
+    }
+    if (remaining_bytes % 2 != 0) {
+        words[remaining_bytes / 2] =
+                static_cast<UInt16>(static_cast<UInt16>(src[remaining_bytes - 
1]) << 8);
     }
 
     for (size_t i = 0; i < words.size(); i++) {
diff --git a/be/test/exprs/function/function_ip_test.cpp 
b/be/test/exprs/function/function_ip_test.cpp
index 4ac9671dfbd..1ee32398c1c 100644
--- a/be/test/exprs/function/function_ip_test.cpp
+++ b/be/test/exprs/function/function_ip_test.cpp
@@ -161,6 +161,17 @@ TEST(FunctionIpTest, FunctionCutIPv6Test) {
     InputTypeSet input_types = {PrimitiveType::TYPE_IPV6, 
PrimitiveType::TYPE_TINYINT,
                                 PrimitiveType::TYPE_TINYINT};
     static_cast<void>(check_function<DataTypeString, true>(func_name, 
input_types, data_set));
+
+    std::array<uint8_t, 16> ipv6_bytes {0xff, 0x12, 0xcd, 0xab, 0x04, 0x00, 
0x03, 0x00,
+                                        0x02, 0x00, 0x01, 0x00, 0xb8, 0x0d, 
0x01, 0x20};
+    IPv6 ipv6;
+    std::memcpy(&ipv6, &ipv6_bytes, sizeof(IPv6));
+    DataSet odd_bytes_data_set = {
+            {{ipv6, (int8_t)1, (int8_t)0}, 
std::string("2001:db8:1:2:3:4:abcd:1200")},
+            {{ipv6, (int8_t)3, (int8_t)0}, 
std::string("2001:db8:1:2:3:4:ab00:0")},
+            {{ipv6, (int8_t)15, (int8_t)0}, std::string("2000::")}};
+    static_cast<void>(
+            check_function<DataTypeString, true>(func_name, input_types, 
odd_bytes_data_set));
 }
 
 class MockIndexReader : public segment_v2::InvertedIndexReader {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to