Skip to content

Backport(v1.19): time: fix parse_float with ten or more fractional digits (#5575) - #5580

Merged
Watson1978 merged 1 commit into
v1.19from
backport-to-v1.19/pr5575
Nov 1, 2026
Merged

Watson1978 merged 1 commit into
v1.19from
backport-to-v1.19/pr5575

Conversation

@github-actions

@github-actions github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

Which issue(s) this PR fixes:
Backport #5575

None — self-found while auditing NumericTimeParser#parse_float.

What this PR does / why we need it:

NumericTimeParser#parse_float (lib/fluent/time.rb) kept ten characters of the fractional part (nsec_s[0..9]), so a timestamp with ten or more decimal digits stored an nsec of 1_000_000_000 or more. EventTime assumes nsec fits inside a second: to_f/to_r report the wrong instant, to_time normalises into the next second, %N prints ten digits, and to_msgpack_ext forwards the oversized field as-is, so other fluentd nodes inherit it. Of fraction lengths 1..20, eleven produce an out-of-range nsec:

Fluent::NumericTimeParser.new(:float).parse("1700000000.1234567890").to_f
# => 1700000001.2345679   (should be 1700000000.123456789)

The fix: keep the first nine fraction digits (nsec_s[0, 9], sub-nanosecond digits dropped, which is what Time#nsec does). Padding and caching behaviour are untouched, so the hot path keeps its shape.

Per the review, the negative-timestamp adjustment introduced earlier in this PR was dropped again: it changed how negative values interact with existing formatting and MessagePack serialization, and EventTime is also defined in the Forward protocol, so changing its encoding needs a separate discussion. Negative values now parse exactly as before this PR.

Validation (Ruby 3.3.6, TZ=UTC):

check result
new test (test/test_time_parser.rb) 31 tests, 0 failures, 0 errors
regression slice: test_time_formatter 77, test_event_time 22, test_formatter 36, test_mixin 21, plugin/test_parser 23, plugin/test_parser_json 66, plugin/test_parser_apache 3, plugin_helper/test_compat_parameters 10, plugin/test_out_exec_filter 22 all 0 failures, 0 errors
rubocop 1.92.1 + rubocop-performance 1.27.0 no offenses

plugin/test_in_exec reports 2 failures (can handle non-ascii characters) that reproduce identically at f984d65 with the fix reverted — the flaky encoding tests pinned in #5562/#5572, unrelated to time parsing.

Docs Changes:

None needed.

Release Note:

time: fix parse_float with ten or more fractional digits

  • With time_type float, a time string with ten or more fractional digits was parsed into a wrong time. Digits beyond nanoseconds are now dropped.

**Which issue(s) this PR fixes**:

None — self-found while auditing `NumericTimeParser#parse_float`.

**What this PR does / why we need it**:

`NumericTimeParser#parse_float` (`lib/fluent/time.rb`) kept **ten**
characters of the fractional part (`nsec_s[0..9]`), so a timestamp with
ten or more decimal digits stored an `nsec` of `1_000_000_000` or more.
`EventTime` assumes `nsec` fits inside a second: `to_f`/`to_r` report
the wrong instant, `to_time` normalises into the next second, `%N`
prints ten digits, and `to_msgpack_ext` forwards the oversized field
as-is, so other fluentd nodes inherit it. Of fraction lengths 1..20,
eleven produce an out-of-range `nsec`:

```
Fluent::NumericTimeParser.new(:float).parse("1700000000.1234567890").to_f
# => 1700000001.2345679   (should be 1700000000.123456789)
```

**The fix**: keep the first nine fraction digits (`nsec_s[0, 9]`,
sub-nanosecond digits dropped, which is what `Time#nsec` does). Padding
and caching behaviour are untouched, so the hot path keeps its shape.

Per the review, the negative-timestamp adjustment introduced earlier in
this PR was dropped again: it changed how negative values interact with
existing formatting and MessagePack serialization, and `EventTime` is
also defined in the [Forward
protocol](https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v1#eventtime-ext-format),
so changing its encoding needs a separate discussion. Negative values
now parse exactly as before this PR.

**Validation** (Ruby 3.3.6, `TZ=UTC`):

| check | result |
| --- | --- |
| new test (`test/test_time_parser.rb`) | 31 tests, **0 failures, 0
errors** |
| regression slice: test_time_formatter 77, test_event_time 22,
test_formatter 36, test_mixin 21, plugin/test_parser 23,
plugin/test_parser_json 66, plugin/test_parser_apache 3,
plugin_helper/test_compat_parameters 10, plugin/test_out_exec_filter 22
| all **0 failures, 0 errors** |
| rubocop 1.92.1 + rubocop-performance 1.27.0 | no offenses |

`plugin/test_in_exec` reports 2 failures (`can handle non-ascii
characters`) that reproduce identically at `f984d65` with the fix
reverted — the flaky encoding tests pinned in #5562/#5572, unrelated to
time parsing.

**Docs Changes**:

None needed.

**Release Note**:

time: fix parse_float with ten or more fractional digits
* With `time_type float`, a time string with ten or more fractional
digits was parsed into a wrong time. Digits beyond nanoseconds are now
dropped.

---------

Signed-off-by: Qingyuan Wang <162230229@nuaa.edu.cn>
Signed-off-by: NUAAwqy <NUAAwqy@users.noreply.github.com>
Co-authored-by: NUAAwqy <NUAAwqy@users.noreply.github.com>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@Watson1978
Watson1978 merged commit 0a6d446 into v1.19 Nov 1, 2026
21 checks passed
@Watson1978
Watson1978 deleted the backport-to-v1.19/pr5575 branch November 1, 2026 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants