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 42bbfeecf0d [fix](function) Handle odd-byte IPv6 truncation (#68109)
42bbfeecf0d is described below

commit 42bbfeecf0d80208930f1416a2e248954848f613
Author: Mryange <[email protected]>
AuthorDate: Wed Sep 23 10:30:26 2026 +0800

    [fix](function) Handle odd-byte IPv6 truncation (#68109)
    
    `cut_ipv6` did not zero the requested number of trailing bytes when the
    IPv6 truncation count was odd. Root cause: the formatter copied the
    address in 16-bit words, so the final iteration also copied one byte
    that belonged to the truncated tail. This change preserves the existing
    word-wise path and handles a remaining single byte separately, ensuring
    that every requested trailing byte is zeroed.
    
    ### 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/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 fa309a321bb..303353130e2 100644
--- a/be/src/exec/common/format_ip.h
+++ b/be/src/exec/common/format_ip.h
@@ -218,7 +218,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 {
@@ -235,8 +235,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 a3f1f431de0..2de8c1eb852 100644
--- a/be/test/exprs/function/function_ip_test.cpp
+++ b/be/test/exprs/function/function_ip_test.cpp
@@ -263,6 +263,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