Skip to content

Commit ec847d6

Browse files
Merge pull request ClickHouse#83086 from ClickHouse/backport/25.6/83020
Backport ClickHouse#83020 to 25.6: Fix uninitialized memory in formatDateTime
2 parents c276eb5 + 8bfec28 commit ec847d6

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

src/Functions/formatDateTime.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -581,11 +581,17 @@ class FunctionFormatDateTimeImpl : public IFunction
581581
fractional_second /= 10;
582582
}
583583

584-
for (UInt32 i = scale; i > 0 && fractional_second > 0; --i)
584+
size_t writes = 0;
585+
for (UInt32 i = scale; i > 0; --i)
585586
{
586-
dest[i - 1] += fractional_second % 10;
587+
dest[i - 1] = '0' + (fractional_second % 10);
587588
fractional_second /= 10;
589+
++writes;
588590
}
591+
592+
for (UInt32 i = writes; i < 6; ++i)
593+
dest[i] = '0';
594+
589595
return 6;
590596
}
591597

@@ -1217,11 +1223,11 @@ class FunctionFormatDateTimeImpl : public IFunction
12171223
};
12181224

12191225
Pos pos = format.data();
1220-
Pos const end = format.data() + format.size();
1226+
const Pos end = format.data() + format.size();
12211227

12221228
while (true)
12231229
{
1224-
Pos const percent_pos = find_first_symbols<'%'>(pos, end);
1230+
const Pos percent_pos = find_first_symbols<'%'>(pos, end);
12251231

12261232
if (percent_pos < end)
12271233
{
@@ -1356,16 +1362,18 @@ class FunctionFormatDateTimeImpl : public IFunction
13561362
// Fractional seconds
13571363
case 'f':
13581364
{
1359-
/// If the time data type has no fractional part, we print (default) '000000' or (deprecated) '0' as fractional part.
13601365
if (mysql_f_prints_single_zero)
13611366
{
1367+
/// If the time data type has no fractional part, print '0' as fractional part.
1368+
/// Legacy behavior.
13621369
Instruction<T> instruction;
13631370
instruction.setMysqlFunc(&Instruction<T>::mysqlFractionalSecondSingleZero);
13641371
instructions.push_back(std::move(instruction));
13651372
out_template += String(scale == 0 ? 1 : scale, '0');
13661373
}
13671374
else
13681375
{
1376+
/// If the time data type has no fractional part, print '000000' as fractional part.
13691377
if (mysql_f_prints_scale_number_of_digits)
13701378
{
13711379
/// Print as many digits as specified by scale. Legacy behavior.
@@ -1376,7 +1384,8 @@ class FunctionFormatDateTimeImpl : public IFunction
13761384
}
13771385
else
13781386
{
1379-
/// Unconditionally print six digits (independent of scale). This is what MySQL does, may it live long and prosper.
1387+
/// Unconditionally print six digits (independent of scale).
1388+
/// This is what MySQL does, may it live long and prosper.
13801389
Instruction<T> instruction;
13811390
instruction.setMysqlFunc(&Instruction<T>::mysqlFractionalSecond);
13821391
instructions.push_back(std::move(instruction));
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
12:January:00.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- %M is a variable-size formatter. This triggered a bug in %f which forgot to write to all of its 6 output characters.
2+
-- This caused ClickHouse to output whatever happened to be in DRAM in these places.
3+
-- The problem occurs also with a single %f, I just added lots of them to make the issue more likely to occur.
4+
select formatDateTime(Date('2026-01-02'),'%h:%M:%s.%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f');

0 commit comments

Comments
 (0)