This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new b97d8040fec [fix](function) size from_base64/to_base64 output buffer
correctly on branch-4.1 (#65141)
b97d8040fec is described below
commit b97d8040fecc8f154411c2b578524b93fc7638ad
Author: Steven Pall <[email protected]>
AuthorDate: Fri Jul 3 05:42:17 2026 -0700
[fix](function) size from_base64/to_base64 output buffer correctly on
branch-4.1 (#65141)
On branch-4.1, `FromBase64Impl::vector` and `ToBase64Impl::vector` size
the output scratch buffer as `cipher_len = srclen / 2`. base64 decode
writes up to `srclen*3/4` bytes and encode writes up to
`4*ceil(srclen/3)`, both larger than `srclen/2`. When `srclen/2` falls
at or below `MAX_STACK_CIPHER_LEN` (64 KiB) while the real output
exceeds 64 KiB, the write overflows the 64 KiB `stack_buf` and corrupts
the stack frame, causing a delayed SIGSEGV inside
`StringOP::push_value_string` (the output `ColumnString` PODArray
reference is clobbered). It reproduces on valid, correctly padded base64
(input length a multiple of 4), so the length guard in #64788 does not
prevent it.
master is not affected. It was refactored to pre-reserve the output
column at the true size (`total_size += len/4*3` for decode,
`4*((len+2)/3)` for encode) and write directly, which removed the
`srclen/2` scratch path. That change is not in any released 4.1.x, and
the auto cherry-pick of #64788 to branch-4.1 is marked
`dev/4.1.x-conflict`. This PR is the minimal sizing fix for the 4.1
line.
Fix (matches `FromBase64BinaryImpl`, which already sizes correctly):
```cpp
// FromBase64Impl::vector
auto cipher_len = srclen / 4 * 3;
// ToBase64Impl::vector
auto cipher_len = (srclen + 2) / 3 * 4;
```
Verification: built stock be-4.1.2 with only this change and ran it in a
production disaggregated cluster. A query decoding a 120000-character
valid base64 value (90 KB output, inside the 64 KiB stack window)
crashed the BE before and returns correctly after. Confirmed across all
rows wider than 100 KB in a real table (19382 rows, max decode 612 KB)
with no BE restarts.
Repro on stock 4.1.2:
```sql
SELECT length(from_base64(v)) FROM t; -- v: a 120000-char base64 string of
a repeated byte
```
Signed-off-by: Steven Pall <[email protected]>
---
be/src/exprs/function/function_string.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/be/src/exprs/function/function_string.cpp
b/be/src/exprs/function/function_string.cpp
index b080f22622e..4ce5e484b86 100644
--- a/be/src/exprs/function/function_string.cpp
+++ b/be/src/exprs/function/function_string.cpp
@@ -1124,7 +1124,7 @@ struct ToBase64Impl {
continue;
}
- auto cipher_len = srclen / 2;
+ auto cipher_len = (srclen + 2) / 3 * 4;
char* dst = nullptr;
if (cipher_len <= stack_buf.size()) {
dst = stack_buf.data();
@@ -1167,7 +1167,7 @@ struct FromBase64Impl {
continue;
}
- auto cipher_len = srclen / 2;
+ auto cipher_len = srclen / 4 * 3;
char* dst = nullptr;
if (cipher_len <= stack_buf.size()) {
dst = stack_buf.data();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]