fix(koa): handle Content-Length overflow and NaN#5952
Conversation
Add explicit radix 10 to Number.parseInt and return undefined for non-numeric Content-Length values, matching the documented `number | undefined` contract. Add regression tests for >2GB, 10GB, decimal, non-numeric, and empty-string headers. Ref: koajs/koa#1961
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughRequest and Response Content-Length parsing now use base-10 Number.parseInt; Request.length returns undefined for non-numeric or empty headers. Tests add edge cases: zero, very large values, decimal-like truncation, and invalid inputs. ChangesContent-Length Parsing Fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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. Comment |
Deploying egg with
|
| Latest commit: |
051e6cb
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d6998bf4.egg-cci.pages.dev |
| Branch Preview URL: | https://fix-koa-request-length-overf.egg-cci.pages.dev |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## next #5952 +/- ##
==========================================
- Coverage 85.21% 85.20% -0.01%
==========================================
Files 669 669
Lines 19304 19305 +1
Branches 3787 3788 +1
==========================================
Hits 16449 16449
- Misses 2463 2464 +1
Partials 392 392 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Deploying egg-v3 with
|
| Latest commit: |
051e6cb
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://b735470c.egg-v3.pages.dev |
| Branch Preview URL: | https://fix-koa-request-length-overf.egg-v3.pages.dev |
There was a problem hiding this comment.
Pull request overview
Ports an upstream Koa fix into @eggjs/koa to make ctx.request.length (Content-Length parsing) safer and better aligned with its number | undefined contract, especially for non-numeric values and large payload sizes.
Changes:
- Parse
Content-LengthusingNumber.parseInt(len, 10)to force base-10 interpretation. - Return
undefinedinstead ofNaNwhenContent-Lengthis not parseable as a number. - Add regression tests covering zero, >2GB, 10GB, decimal truncation, non-numeric, and empty-string headers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/koa/src/request.ts | Updates request length getter to parse base-10 and normalize NaN to undefined. |
| packages/koa/test/request/length.test.ts | Adds regression tests for large/edge-case Content-Length values and invalid inputs. |
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
There was a problem hiding this comment.
Code Review
This pull request updates the Content-Length parsing in packages/koa/src/request.ts to include a radix and handle NaN values, alongside adding several test cases for edge cases like large values and invalid strings. The reviewer suggests using Number() and Math.trunc() instead of Number.parseInt to ensure stricter parsing and prevent partial matches of non-numeric strings, aligning with upstream Koa implementations.
| const parsed = Number.parseInt(len, 10); | ||
| return Number.isNaN(parsed) ? undefined : parsed; |
There was a problem hiding this comment.
While Number.parseInt with a radix is an improvement, it is more lenient than the standard HTTP parsing expected for Content-Length. For example, Number.parseInt('10abc', 10) returns 10, whereas a strictly non-numeric value should ideally result in undefined. Additionally, if this.get returns an array of strings (which can happen in Node.js if multiple headers are present), Number.parseInt will stringify the array (e.g., '10,20') and return the first value, which is incorrect.
To align with the upstream Koa fix (koajs/koa#1961) and ensure stricter parsing, consider using Number() combined with Math.trunc().
| const parsed = Number.parseInt(len, 10); | |
| return Number.isNaN(parsed) ? undefined : parsed; | |
| const parsed = Number(len); | |
| return Number.isNaN(parsed) ? undefined : Math.trunc(parsed); |
Summary
@eggjs/koa.10toNumber.parseIntsoContent-Lengthis always parsed as base 10.undefined(instead ofNaN) for non-numericContent-Lengthvalues, matching the documentednumber | undefinedcontract.Why
The upstream koa bug was
~~lentruncating to a signed 32-bit integer, silently producing wrong sizes for payloads > 2GB. Our fork already moved off~~toNumber.parseInt, but two gaps remained:0/0xinputs.NaNto callers instead ofundefined.Test plan
npx vitest run packages/koa/test/request/length.test.ts— 8/8 passingSummary by CodeRabbit