• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aio-libs / multidict / 36144372153
87%

Build:
DEFAULT BRANCH: master
Ran 25 Sep 2026 01:59PM UTC
Jobs 1
Files 43
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

25 Sep 2026 01:58PM UTC coverage: 87.098% (+0.04%) from 87.057%
36144372153

push

github

web-flow
Hold refs across lower() when copying keys from another source (#1582)

<!-- Thank you for your contribution! -->

## What do these changes do?

A `str` subclass key's `lower()` runs Python code that can clear or grow
the source while a `CIMultiDict` copies keys out of it. On the
cross-type path, `md_update_from_ht()` kept pointers into the source's
entry table across that call, and `md_update_from_dict()` held only a
borrowed reference to the value, so both read freed memory.

The cross-type loop now holds its own references to the key and value
while computing the identity, then reloads the entry table and clamps
the entry count. The dict loop increfs the value alongside the key and
passes that reference on to `md_add_with_hash_steal_refs()` instead of
taking a second one. The same-type path runs no Python code and is
unchanged. The pure-Python implementation is not affected.

## Are there changes in behavior for the user?

No, apart from the crash being gone.

## Is it a substantial burden for the maintainers to support this?

No.

## Related issue number

Fixes #1581

## Checklist

- [x] I think the code is well written
- [x] Unit tests for the changes exist
- [x] Documentation reflects the changes (N/A)
- [ ] If you provide code modification, please add yourself to
`CONTRIBUTORS.txt` (N/A)
- [x] Add a new news fragment into the `CHANGES/` folder
- [x] `make doc-spelling` passes and any new technical words are added
to `docs/spelling_wordlist.txt`

Drafted with Claude Code (Claude Opus 5.5); reviewed by @asvetlov.

<details>
<summary>Agent run details (optional, for reviewers)</summary>

Tests:

* ASan GIL 3.14.7 (`MULTIDICT_DEBUG_BUILD=1 MULTIDICT_ASAN_BUILD=1
MULTIDICT_NO_FREELIST=1`, `PYTHONMALLOC=malloc`, `-k "not test_leak and
not test_freed_blocks_are_reused"`): 2733 passed, 167 skipped. Without
the fix, all 8 `test_key_lower_mutates_source` `c-` cases report
heap-use-after-free (`md_update_from_ht` at `bulk_update.h:364` for
multidict sourc... (continued)

779 of 1558 branches covered (50.0%)

Branch coverage included in aggregate %.

39 of 40 new or added lines in 1 file covered. (97.5%)

8058 of 8588 relevant lines covered (93.83%)

1.88 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
96.94
0.03% tests/test_mutable_multidict.py
Jobs
ID Job ID Ran Files Coverage
1 MyPy - 36144372153.1 25 Sep 2026 01:59PM UTC 86
87.1
GitHub Action Run
Source Files on build 36144372153
  • Tree
  • List 43
  • Changed 3
  • Source Changed 1
  • Coverage Changed 3
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #36144372153
  • cd031103 on github
  • Prev Build on master (#36133675941)
  • Next Build on master (#36147951162)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc