Repository navigation
Commit c7a24f4
committed
fix(extractor): an IMemoryOwner whose .Memory is handed off escapes the owner (mined ImageSharp; CodeQL-validated)
Cross-tool oracle (scripts/oracle_compare.py) on SixLabors/ImageSharp surfaced this: our
flow-locals detector flagged `Image.WrapMemory`'s `memoryManager` (a `ByteMemoryManager :
IMemoryOwner`) as an undisposed-local leak, but CodeQL (interprocedural) does NOT — the
manager's `.Memory` is handed to `MemoryGroup.Wrap(...)` and lives on in the returned `Image`.
A `Memory<T>` keeps its `IMemoryOwner` alive (it IS the backing), so passing `owner.Memory` as
an argument transfers the owner's lifetime to the consumer; disposing it at method scope would
be premature, and not disposing it here is not a leak.
The flow escape-exclusion now untracks a local when its `.Memory` view is passed as an argument,
scoped tightly: only `IMemoryOwner.Memory` (not any `local.Member`, so a `FileStream` whose
`.Length` is read still leaks), and only for non-pool / non-`using` owners (a MemoryPool/`using`
owner keeps its dangling-borrow tracking — OWN002 — intact). Mirrors the existing #80
escaping-ctor transfer and the D5 "ambiguous handoff -> conservatively exclude" rule.
Regression sample MemoryOwnerEscapeSample.cs (--flow-locals): an IMemoryOwner whose `.Memory`
is handed to a consumer stays silent ('handedOwner'); one whose `.Memory` is only read locally
and never disposed still warns ('leakedOwner').
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED1 parent b787ffc commit c7a24f4
3 files changed
Lines changed: 61 additions & 2 deletions
File tree
- .github/workflows
- frontend/roslyn
- OwnSharp.Extractor
- samples
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
458 | 458 | | |
459 | 459 | | |
460 | 460 | | |
461 | | - | |
| 461 | + | |
| 462 | + | |
462 | 463 | | |
463 | 464 | | |
464 | 465 | | |
| |||
564 | 565 | | |
565 | 566 | | |
566 | 567 | | |
567 | | - | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
568 | 575 | | |
569 | 576 | | |
570 | 577 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2578 | 2578 | | |
2579 | 2579 | | |
2580 | 2580 | | |
| 2581 | + | |
| 2582 | + | |
| 2583 | + | |
| 2584 | + | |
| 2585 | + | |
| 2586 | + | |
| 2587 | + | |
| 2588 | + | |
| 2589 | + | |
| 2590 | + | |
| 2591 | + | |
| 2592 | + | |
| 2593 | + | |
2581 | 2594 | | |
2582 | 2595 | | |
2583 | 2596 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
0 commit comments