Repository navigation
fix: request.length overflows on Content-Length > 2GB - #1961
Merged
Merged
Conversation
- Replace ~~len (32-bit truncation) with Number.parseInt(len, 10) - Handles arbitrarily large Content-Length values up to Number.MAX_SAFE_INTEGER - Preserves existing behavior for values under 2GB, including zero - Add comprehensive test cases for overflow boundaries and edge cases Fixes integer overflow where ~~'2147483648' returned -2147483648 instead of the correct value. Now correctly parses large file uploads and returns undefined for unparseable values, consistent with existing patterns.
- Replace ~~len (32-bit truncation) with Number.parseInt(len, 10) - Handles arbitrarily large Content-Length values up to Number.MAX_SAFE_INTEGER - Preserves existing behavior for values under 2GB, including zero - Add comprehensive test cases for overflow boundaries and edge cases Fixes integer overflow where ~~'2147483648' returned -2147483648 instead of the correct value. Now correctly parses large file uploads and returns undefined for unparseable values, consistent with existing patterns.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1961 +/- ##
=======================================
Coverage 99.90% 99.90%
=======================================
Files 9 9
Lines 2105 2106 +1
=======================================
+ Hits 2103 2104 +1
Misses 2 2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Contributor
Author
|
@olleolleolle |
olleolleolle
approved these changes
May 20, 2026
olleolleolle
left a comment
Contributor
There was a problem hiding this comment.
As a non-maintainer, and having read this patch only, I think it looks good. I recommend its merging.
Contributor
Author
|
Thank you so much for the approval. Could please tell me who approves for the merge, so that I may address the issue to them specifically. |
Contributor
Author
|
Thank you so much to all the maintainers and contributors for the opportunity. Regards, |
1 of 2 tasks
fengmk2
added a commit
to eggjs/egg
that referenced
this pull request
May 21, 2026
Mirror the Request.length fix on the Response sibling getter to keep the fork aligned with upstream koa. Preserves the existing `|| 0` fallback so the behavior for non-numeric headers is unchanged. Ref: koajs/koa#1961
killagu
pushed a commit
to eggjs/egg
that referenced
this pull request
Jun 28, 2026
## Summary - Port [koajs/koa#1961](koajs/koa#1961) into our maintained `@eggjs/koa`. - Add explicit radix `10` to `Number.parseInt` so `Content-Length` is always parsed as base 10. - Return `undefined` (instead of `NaN`) for non-numeric `Content-Length` values, matching the documented `number | undefined` contract. ## Why The upstream koa bug was `~~len` truncating to a signed 32-bit integer, silently producing wrong sizes for payloads > 2GB. Our fork already moved off `~~` to `Number.parseInt`, but two gaps remained: 1. No explicit radix — surprising parsing for leading `0`/`0x` inputs. 2. Non-numeric headers leaked `NaN` to callers instead of `undefined`. ## Test plan - [x] `npx vitest run packages/koa/test/request/length.test.ts` — 8/8 passing - [ ] Ported all six regression cases from upstream: zero, 2GB+, 10GB, decimal truncation, non-numeric, empty string. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Content-Length parsing now returns undefined for invalid or non-numeric values instead of NaN, and consistently parses numeric values using a fixed decimal radix for more predictable behavior. * **Tests** * Expanded length parsing tests to cover zero, very large values, decimal-like truncation, empty and non-numeric inputs. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/eggjs/egg/pull/5952?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ctx.request.lengthuses~~len(double bitwise NOT) to parse the Content-Length header, which truncates values to a signed 32-bit integer. For Content-Length values exceeding 2,147,483,647 bytes (~2GB), the result silently wraps to incorrect values:This affects any middleware using
ctx.request.lengthfor upload size enforcement, rate limiting, or request body pre-allocation. In the era of large file uploads and video processing APIs, this is a realistic scenario.Solution
Replace
~~lenwithNumber.parseInt(len, 10):Fixes integer overflow where ~~'2147483648' returned -2147483648 instead of the correct value. Now correctly parses large file uploads and returns undefined for unparseable values, consistent with existing patterns.
Test Coverage
Added 6 comprehensive test cases covering:
All existing tests pass (439/439). No breaking changes.
Checklist