Skip to content

fix(koa): handle Content-Length overflow and NaN#5952

Open
fengmk2 wants to merge 2 commits into
nextfrom
fix/koa-request-length-overflow
Open

fix(koa): handle Content-Length overflow and NaN#5952
fengmk2 wants to merge 2 commits into
nextfrom
fix/koa-request-length-overflow

Conversation

@fengmk2
Copy link
Copy Markdown
Member

@fengmk2 fengmk2 commented May 21, 2026

Summary

  • Port 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

  • 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.

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 Change Stack

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
Copilot AI review requested due to automatic review settings May 21, 2026 07:43
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 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: 03886239-a936-4c23-b1ad-504641aa34a8

📥 Commits

Reviewing files that changed from the base of the PR and between 95a3ad9 and 051e6cb.

📒 Files selected for processing (1)
  • packages/koa/src/response.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/koa/src/response.ts

📝 Walkthrough

Walkthrough

Request 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.

Changes

Content-Length Parsing Fix

Layer / File(s) Summary
Content-Length parsing with NaN handling and tests
packages/koa/src/request.ts, packages/koa/src/response.ts, packages/koa/test/request/length.test.ts
Request.length now parses Content-Length with Number.parseInt(len, 10) and returns undefined when the result is NaN. Response.length uses Number.parseInt(..., 10) with the same fallback behavior. Tests added for zero, large integers (2GB+, 10GB), decimal truncation, and invalid/empty inputs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 Base-ten hops down the log,
I parse each header like a conscientious frog.
No NaN in burrows, undefined on the trail,
From zero to terabytes, the tests prevail.
🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main changes: fixing Content-Length overflow handling and NaN returns in the koa request module.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/koa-request-length-overflow

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 21, 2026

Deploying egg with  Cloudflare Pages  Cloudflare Pages

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

View logs

@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.20%. Comparing base (0dec2c9) to head (051e6cb).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 21, 2026

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

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

View logs

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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-Length using Number.parseInt(len, 10) to force base-10 interpretation.
  • Return undefined instead of NaN when Content-Length is 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.

Comment thread packages/koa/src/request.ts
Comment thread packages/koa/test/request/length.test.ts
@fengmk2 fengmk2 requested a review from killagu May 21, 2026 07:51
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
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +331 to +332
const parsed = Number.parseInt(len, 10);
return Number.isNaN(parsed) ? undefined : parsed;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

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().

Suggested change
const parsed = Number.parseInt(len, 10);
return Number.isNaN(parsed) ? undefined : parsed;
const parsed = Number(len);
return Number.isNaN(parsed) ? undefined : Math.trunc(parsed);

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