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]