Skip to content

utils: fix integer divide-by-zero on Windows x64 in bytes_to_human_readable_size#11727

Merged
edsiper merged 1 commit intofluent:masterfrom
ashinde-ai:fix/divide-by-zero-win64-v2
Apr 20, 2026
Merged

utils: fix integer divide-by-zero on Windows x64 in bytes_to_human_readable_size#11727
edsiper merged 1 commit intofluent:masterfrom
ashinde-ai:fix/divide-by-zero-win64-v2

Conversation

@ashinde-ai
Copy link
Copy Markdown
Contributor

@ashinde-ai ashinde-ai commented Apr 20, 2026

Summary

Fix an INTEGER_DIVIDE_BY_ZERO crash (exception 0xC0000094) on Windows x64 in
flb_utils_bytes_to_human_readable_size().

Root Cause

On Windows x64, the LLP64 data model makes unsigned long 32 bits (unlike LP64 on
Linux where it is 64 bits). The divisor variable u starts at 1024 and is multiplied
by 1024 each loop iteration. After three iterations (reaching the GB unit boundary),
the next multiplication (1024^4 = 1,099,511,627,776) overflows a 32-bit unsigned
long to zero, causing a divide-by-zero crash on the next bytes / u operation.

This is triggered every 5 seconds by the storage metrics timer
(cb_storage_metrics_collect in flb_storage.c) whenever any input buffer exceeds ~1 GB,
which is common with high-volume inputs using filesystem-backed storage.

Fix

Change unsigned long to uint64_t for both the loop counter i and divisor u,
guaranteeing 64-bit arithmetic on all platforms.

Testing

  • Verified on Windows x64 with a winevtlog input producing >1 GB of buffered data.
    Before the fix, Fluent Bit crashes every ~5 seconds at the metrics timer. After the
    fix, the formatter correctly displays sizes in GB/TB without overflow.

Signed-off-by: Amit Shinde ashinde@databahn.ai

Summary by CodeRabbit

  • Refactor
    • Updated internal variable types within a utility function to improve type consistency and reliability. No functional or user-visible behavior changes; existing formatting and output remain unchanged.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b69ca058-5ab8-4f44-8abc-c5ae0f16bd20

📥 Commits

Reviewing files that changed from the base of the PR and between 5c984ac and 2caa52d.

📒 Files selected for processing (1)
  • src/flb_utils.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/flb_utils.c

📝 Walkthrough

Walkthrough

The loop/index variables in flb_utils_bytes_to_human_readable_size were changed from unsigned long to uint64_t; no control flow, API, or output formatting logic was modified.

Changes

Cohort / File(s) Summary
Type refinement
src/flb_utils.c
Updated local loop/index variable types (i, u) from unsigned long to uint64_t inside flb_utils_bytes_to_human_readable_size(...). No behavioral changes to the function's formatting or control flow.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Suggested reviewers

  • edsiper

Poem

🐰 I hopped from long to sixty-four,

nibbling bits on the binary floor.
Small paws, big range, no overflow fright,
I crunch bytes by moonlit night.
A tiny hop — the types feel right. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main fix: changing integer types to prevent divide-by-zero on Windows x64 in the bytes_to_human_readable_size function.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/flb_utils.c (1)

815-827: ⚠️ Potential issue | 🟠 Major

Prevent the divisor from overflowing at EiB.

Changing u to uint64_t fixes the Windows x64 GiB case, but the loop can still wrap u to zero when bytes >= 1024^6 because line 826 attempts 1024^7, then the next iteration divides by zero. Track the current unit divisor instead of the next threshold.

🐛 Proposed fix
-    uint64_t i;
-    uint64_t u = 1024;
+    uint64_t i;
+    uint64_t u = 1;
@@
-    for (i = 0; __units[i] != NULL; i++) {
-        if ((bytes / u) == 0) {
-            break;
-        }
+    for (i = 0; __units[i + 1] != NULL && (bytes / u) >= 1024; i++) {
         u *= 1024;
     }
     if (!i) {
         snprintf(out_buf, size, "%lu%s", (long unsigned int) bytes, __units[0]);
     }
     else {
-        float fsize = (float) ((double) bytes / (u / 1024));
+        float fsize = (float) ((double) bytes / u);
         snprintf(out_buf, size, "%.1f%s", fsize, __units[i]);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/flb_utils.c` around lines 815 - 827, The loop uses u as the
next-threshold divisor and multiplies it until overflow (causing divide-by-zero
when bytes >= 1024^6); update the logic in the function around the __units loop
so you track the current unit divisor (e.g., a variable like div starting at 1)
and advance units while bytes / div >= 1024 (and the next unit exists), instead
of pre-multiplying u to the next threshold; also guard the multiplication by
checking for potential overflow (or compare bytes/div to 1024) before
multiplying u so you never wrap u to zero — adjust references to u and the unit
selection accordingly in this loop that iterates over __units.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/flb_utils.c`:
- Around line 815-827: The loop uses u as the next-threshold divisor and
multiplies it until overflow (causing divide-by-zero when bytes >= 1024^6);
update the logic in the function around the __units loop so you track the
current unit divisor (e.g., a variable like div starting at 1) and advance units
while bytes / div >= 1024 (and the next unit exists), instead of pre-multiplying
u to the next threshold; also guard the multiplication by checking for potential
overflow (or compare bytes/div to 1024) before multiplying u so you never wrap u
to zero — adjust references to u and the unit selection accordingly in this loop
that iterates over __units.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c943b772-dd6c-4740-9ad7-7726069ced56

📥 Commits

Reviewing files that changed from the base of the PR and between 856d762 and 5c984ac.

📒 Files selected for processing (1)
  • src/flb_utils.c

…adable_size

On Windows x64, `unsigned long` is 32 bits (LLP64 data model), unlike
Linux x64 where it is 64 bits (LP64). In flb_utils_bytes_to_human_readable_size(),
the divisor `u` starts at 1024 and is multiplied by 1024 each iteration. After
three iterations (reaching the GB unit), the next multiplication overflows a
32-bit unsigned long to zero, causing an integer divide-by-zero crash
(exception code 0xc0000094).

This crash is triggered whenever the storage metrics timer (every 5 seconds)
calls the formatter with a buffer size exceeding ~1 GB, which is common with
high-volume inputs using filesystem-backed storage.

Change `unsigned long` to `uint64_t` for both the loop counter and the
divisor, guaranteeing 64-bit arithmetic on all platforms.

Signed-off-by: Amit Shinde <ashinde@databahn.ai>
Made-with: Cursor
Copy link
Copy Markdown
Contributor

@cosmo0920 cosmo0920 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a pitfall of Windows LLP64.
So, we really need for this fix.

@edsiper edsiper merged commit 29deec9 into fluent:master Apr 20, 2026
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants