-
Notifications
You must be signed in to change notification settings - Fork 0
fix(extractor): IMemoryOwner.Memory handoff escapes the owner (oracle-driven, CodeQL-validated) #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| using System; | ||
| using System.Buffers; | ||
|
|
||
| namespace Own.Samples; | ||
|
|
||
| // P-016 escape-via-projection (mined: ImageSharp Image.WrapMemory; CodeQL agrees — no leak). | ||
| // | ||
| // An IMemoryOwner's `.Memory` view passed as an ARGUMENT hands the OWNER off: the Memory keeps | ||
| // the owner alive (it IS the backing), so a consumer that stores it takes over the lifetime — | ||
| // the owner is not leaked at method scope. Contrast: an owner whose `.Memory` is only READ | ||
| // locally and never disposed IS a leak. Exercised with --flow-locals. | ||
|
|
||
| internal sealed class PixelOwner : IMemoryOwner<byte> | ||
| { | ||
| private readonly byte[] data = new byte[16]; | ||
|
|
||
| public Memory<byte> Memory => this.data; | ||
|
|
||
| public void Dispose() { } | ||
| } | ||
|
|
||
| internal static class MemoryOwnerEscape | ||
| { | ||
| private static void Store(Memory<byte> m) { } | ||
|
|
||
| // owner.Memory handed to a consumer (ambiguous transfer) -> owner escapes -> SILENT. | ||
| public static void Transferred() | ||
| { | ||
| var handedOwner = new PixelOwner(); | ||
| Store(handedOwner.Memory); // .Memory passed as an arg -> ownership handed off | ||
| } | ||
|
|
||
| // owner.Memory only READ locally (a length); owner never disposed -> real leak -> must WARN. | ||
| public static int ReadOnlyLeak() | ||
| { | ||
| var leakedOwner = new PixelOwner(); | ||
Check warningCode scanning / Own.NET owned resource not released on all paths (possible leak) Warning
IDisposable local 'leakedOwner' is never disposed (leak) [resource: disposable]
|
||
|
|
||
| return leakedOwner.Memory.Length; // a local read, NOT a handoff | ||
| } | ||
|
|
||
| // A MemoryPool RENTAL (not a `new`'d owner) keeps its dangling-borrow tracking through a | ||
| // `.Memory` handoff: projection-escape is scoped to `new`'d owners only, so using `pooled.Memory` | ||
| // after Dispose still trips OWN002 — the rule must NOT silence it (Codex/CodeRabbit P1). | ||
| public static void PoolOwnerNotEscaped() | ||
| { | ||
| var pooled = MemoryPool<byte>.Shared.Rent(16); | ||
Check warningCode scanning / Own.NET use after release Warning
IDisposable local 'pooled' is used after it is disposed [resource: disposable]
|
||
|
|
||
| pooled.Dispose(); | ||
| Store(pooled.Memory); // use of .Memory AFTER Dispose -> OWN002, must NOT be silenced | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.