Skip to content

fix: sort RFC 2231 parameter continuations numerically - #13563

Open
TrueFurina wants to merge 1 commit into
aio-libs:masterfrom
TrueFurina:fix-13499
Open

fix: sort RFC 2231 parameter continuations numerically#13563
TrueFurina wants to merge 1 commit into
aio-libs:masterfrom
TrueFurina:fix-13499

Conversation

@TrueFurina

Copy link
Copy Markdown

Fixes #13499

Problem: content_disposition_filename() reassembles RFC 2231 continuations (filename0, filename1, ...) with a lexicographic sorted() over parameter names. String ordering puts filename10 between filename1 and filename*2, so the sequential-index check stops at the first mismatch and any filename split into 10+ sections is silently truncated to its first two.

Fix: sort by the numeric continuation index (extracted from the name), so segments are reassembled in order regardless of how many there are.

@TrueFurina
TrueFurina requested a review from asvetlov as a code owner August 28, 2026 02:56
@greptile-apps

greptile-apps Bot commented Aug 28, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

The malformed-parameter exception should be fixed before merging because remote Content-Disposition input can now make filename extraction fail.

The new sort key assumes every prefix-matching parameter has an integer suffix, although the parser can retain token-valid nonnumeric names, causing an uncaught ValueError on multipart and response metadata paths.

Files Needing Attention: aiohttp/multipart.py

Reviews (1): Last reviewed commit: "fix: sort RFC 2231 parameter continuatio..." | Re-trigger Greptile

Comment thread aiohttp/multipart.py
fnparams = sorted(
(key, value) for key, value in params.items() if key.startswith(name_suf)
((key, value) for key, value in params.items() if key.startswith(name_suf)),
key=lambda kv: int(kv[0].split("*", 1)[1].rstrip("*")),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Nonnumeric suffixes raise ValueError

When a Content-Disposition header contains a token-valid parameter such as filename*abc=foo, parse_content_disposition retains it and this sort key calls int("abc"), causing an uncaught ValueError when multipart filename or response content-disposition metadata is accessed.

Knowledge Base Used: Payloads, forms, and multipart bodies

Comment thread aiohttp/multipart.py
Comment on lines 206 to +208
fnparams = sorted(
(key, value) for key, value in params.items() if key.startswith(name_suf)
((key, value) for key, value in params.items() if key.startswith(name_suf)),
key=lambda kv: int(kv[0].split("*", 1)[1].rstrip("*")),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Continuation sorting lacks coverage

This changes RFC 2231 continuation ordering without adding focused tests for indices of 10 or greater and nonnumeric continuation-like names, leaving both the intended fix and malformed-input compatibility unprotected against regression.

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.02%. Comparing base (148205f) to head (9a33b37).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #13563   +/-   ##
=======================================
  Coverage   99.02%   99.02%           
=======================================
  Files         135      135           
  Lines       50481    50481           
  Branches     2650     2650           
=======================================
  Hits        49988    49988           
  Misses        370      370           
  Partials      123      123           
Flag Coverage Δ
Autobahn 22.03% <ø> (ø)
CI-GHA 98.91% <ø> (ø)
OS-Linux 98.69% <ø> (ø)
OS-Windows 97.09% <ø> (ø)
OS-macOS 97.96% <ø> (ø)
Py-3.10 98.12% <ø> (ø)
Py-3.11 98.35% <ø> (ø)
Py-3.12 98.43% <ø> (ø)
Py-3.13 98.42% <ø> (-0.01%) ⬇️
Py-3.14 98.45% <ø> (-0.01%) ⬇️
Py-3.14t 97.61% <ø> (ø)
Py-pypy-3.11 97.40% <ø> (ø)
VM-macos 97.96% <ø> (ø)
VM-ubuntu 98.69% <ø> (ø)
VM-windows 97.09% <ø> (ø)
cython-coverage 83.09% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@codspeed-hq

codspeed-hq Bot commented Aug 28, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 96 untouched benchmarks
⏩ 83 skipped benchmarks1


Comparing TrueFurina:fix-13499 (9a33b37) with master (148205f)

Open in CodSpeed

Footnotes

  1. 83 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

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.

content_disposition_filename() truncates filenames split into 10+ RFC 2231 continuation sections (lexicographic sort)

1 participant