Skip to content

fix: dispose SKPaint and SKBitmap in renderer icon/dot helpers#86

Merged
afonsoft merged 1 commit into
feature/devin-20260712-sonar-qualityfrom
feature/devin-20260712-sonar-dispose-fix
Jul 12, 2026
Merged

fix: dispose SKPaint and SKBitmap in renderer icon/dot helpers#86
afonsoft merged 1 commit into
feature/devin-20260712-sonar-qualityfrom
feature/devin-20260712-sonar-dispose-fix

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

All Submissions:

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

New Feature Submissions:

  1. Does your submission pass tests?
  2. Have you lint your code locally prior to submission?

Changes to Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

fix: dispose SKPaint and SKBitmap in renderer icon/dot helpers

This PR addresses a Devin Review finding on the renderer phase:

  • QRCode.DrawIcon: the custom icon background SKPaint was allocated when a background color was supplied but never disposed. The method now wraps it in a using block and falls back to the shared lightBrush when no background color is provided.
  • ArtQRCode.MakeDotPixel: the temporary source SKBitmap created to draw the dot is now disposed before returning the cropped bitmap.
  • ArtQRCode.RenderGraphicCore: the dark and light module pixel SKBitmap instances created by MakeDotPixel are now disposed after the final QR code is rendered.

Build and dotnet test QRCoder.Core.Tests/ -f net10.0 --configuration Release pass locally (502 tests).

Link to Devin session: https://app.devin.ai/sessions/20c92a1bad724f63b8be89a9e195e664
Requested by: @afonsoft


Open in Devin Review

Co-Authored-By: Afonso Dutra Nogueira Filho <afonsoft@gmail.com>
@afonsoft afonsoft self-assigned this Jul 12, 2026
@afonsoft
afonsoft self-requested a review July 12, 2026 17:50
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@afonsoft
afonsoft merged commit e8e1e3c into feature/devin-20260712-sonar-quality Jul 12, 2026
4 of 5 checks passed
@afonsoft
afonsoft deleted the feature/devin-20260712-sonar-dispose-fix branch July 12, 2026 17:50
@sonarqubecloud

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

Open in Devin Review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🔍 Pre-existing resource leak and logic bug in Resize method not addressed by this PR

The Resize method at QRCoder.Core/Renderers/ArtQRCode.cs:322-347 creates a scaledImage bitmap (line 332) that is:

  1. Never populated from the input image parameter — it's an empty bitmap drawn onto the output canvas, meaning background images will always render as blank.
  2. Never disposed — a resource leak of the same kind this PR is fixing elsewhere.

Since this PR's theme is fixing resource leaks in these renderers, this is a missed opportunity. The logic bug (drawing an empty bitmap instead of the actual input image) is also pre-existing and means the background image feature in ArtQRCode likely doesn't work correctly.

(Refers to lines 332-343)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +225 to +231
using (var iconBgBrush = iconBackgroundSKColor != null ? new SKPaint { Color = (SKColor)iconBackgroundSKColor } : null)
{
using (var iconPath = CreateRoundedSKRectIPath(centerDest, iconBorderWidth * 2))
if (iconBorderWidth > 0)
{
gfx.DrawPath(iconPath, iconBgBrush);
using (var iconPath = CreateRoundedSKRectIPath(centerDest, iconBorderWidth * 2))
{
gfx.DrawPath(iconPath, iconBgBrush ?? lightBrush);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

📝 Info: Behavioral equivalence of DrawIcon refactoring relies on C# using-with-null semantics

The old code assigned lightBrush directly to iconBgBrush when iconBackgroundSKColor was null, making iconBgBrush always non-null. The new code sets iconBgBrush to null in that case and uses iconBgBrush ?? lightBrush at the call site. This is behaviorally equivalent because:

  • using (var x = null) is a no-op in C# (no dispose call)
  • The ?? operator provides the same fallback brush
  • lightBrush is managed by the caller and should NOT be disposed here (which the new code correctly avoids)

This is a correct and safe transformation.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant