Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
00f0205
fix: resolve SonarCloud issues in engine and data model
devin-ai-integration[bot] Jul 12, 2026
afad91d
fix: resolve SonarCloud issues in PayloadGenerator
devin-ai-integration[bot] Jul 12, 2026
e5b0b2c
Merge pull request #81: fix: resolve SonarCloud issues in engine and …
devin-ai-integration[bot] Jul 12, 2026
6eb3245
Merge pull request #82 from afonsoft/feature/devin-20260712-sonar-pay…
afonsoft Jul 12, 2026
1db24d9
fix: resolve SonarCloud issues in QRCode renderer
devin-ai-integration[bot] Jul 12, 2026
cae920b
Merge integration branch into renderers-core
devin-ai-integration[bot] Jul 12, 2026
9d11c35
fix: keep OneTimePassword fail-fast while suppressing S3877/S3928
devin-ai-integration[bot] Jul 12, 2026
46cef04
fix: resolve SonarCloud issues in core renderers and extensions
devin-ai-integration[bot] Jul 12, 2026
74a180b
fix: avoid StartsWith(char) for net48 compatibility
devin-ai-integration[bot] Jul 12, 2026
2b7d3a1
Merge pull request #84 from afonsoft/feature/devin-20260712-sonar-ren…
afonsoft Jul 12, 2026
1f79a2e
fix: resolve SonarCloud issues in remaining renderers
devin-ai-integration[bot] Jul 12, 2026
3efb71b
Merge pull request #85 from afonsoft/feature/devin-20260712-sonar-ren…
afonsoft Jul 12, 2026
e4c1756
fix: dispose SKPaint and SKBitmap in renderer icon/dot helpers
devin-ai-integration[bot] Jul 12, 2026
e8e1e3c
Merge pull request #86 from afonsoft/feature/devin-20260712-sonar-dis…
afonsoft Jul 12, 2026
240aa52
fix: add null guard in HexSKColorToByteArray to resolve S2259
devin-ai-integration[bot] Jul 12, 2026
522b1c8
Merge pull request #87 from afonsoft/feature/devin-20260712-sonar-nul…
afonsoft Jul 12, 2026
2a5db5c
fix(ArtQRCode): scale and dispose background image
devin-ai-integration[bot] Jul 12, 2026
375b7ca
test(ArtQRCode): update background image expected hash
devin-ai-integration[bot] Jul 12, 2026
5384c38
fix(ArtQRCode): avoid zero-dimension resize and leak on extreme aspec…
devin-ai-integration[bot] Jul 12, 2026
04829e5
Merge pull request #88 from afonsoft/feature/devin-20260712-sonar-res…
afonsoft Jul 12, 2026
f6308b3
fix: resolve CodeQL integer-overflow and obsolete warnings (#89)
devin-ai-integration[bot] Jul 12, 2026
c8951a0
ci: add Qodana baseline (qodana.sarif.json)
devin-ai-integration[bot] Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions QRCoder.Core.Tests/Generators/BestPracticesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,15 @@ public void Base64QRCode_GetGraphic_WithIcon_ShouldReturnBase64()
var b64 = new Base64QRCode(data);

var icon = new SKBitmap(10, 10);
var result = b64.GetGraphic(5, SKColors.Black, SKColors.White, icon, 15, 2);
var result = b64.GetGraphic(new Base64QRCodeGraphicOptions
{
PixelsPerModule = 5,
DarkSKColor = SKColors.Black,
LightSKColor = SKColors.White,
Icon = icon,
IconSizePercent = 15,
IconBorderWidth = 2
});
result.ShouldNotBeNullOrEmpty();
}

Expand Down Expand Up @@ -746,7 +754,14 @@ public void ArtQRCode_GetGraphic_WithCustomPixelSizeFactor_ShouldWork()
var data = gen.CreateQrCode("Art pixel", QRCodeGenerator.ECCLevel.H);
var art = new ArtQRCode(data);

var bmp = art.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, pixelSizeFactor: 0.5);
var bmp = art.GetGraphic(new ArtQRCodeGraphicOptions
{
PixelsPerModule = 10,
DarkSKColor = SKColors.Black,
LightSKColor = SKColors.White,
BackgroundSKColor = SKColors.Transparent,
PixelSizeFactor = 0.5
});
bmp.ShouldNotBeNull();
}

Expand All @@ -758,8 +773,14 @@ public void ArtQRCode_GetGraphic_FlatQuietZone_ShouldWork()
var data = gen.CreateQrCode("Art flat QZ", QRCodeGenerator.ECCLevel.H);
var art = new ArtQRCode(data);

var bmp = art.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent,
quietZoneRenderingStyle: ArtQRCode.QuietZoneStyle.Flat);
var bmp = art.GetGraphic(new ArtQRCodeGraphicOptions
{
PixelsPerModule = 10,
DarkSKColor = SKColors.Black,
LightSKColor = SKColors.White,
BackgroundSKColor = SKColors.Transparent,
QuietZoneRenderingStyle = ArtQRCode.QuietZoneStyle.Flat
});
bmp.ShouldNotBeNull();
}

Expand All @@ -772,7 +793,14 @@ public void ArtQRCode_PixelSizeFactor_GreaterThanOne_ShouldThrow()
var art = new ArtQRCode(data);

Should.Throw<ArgumentOutOfRangeException>(() =>
art.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, pixelSizeFactor: 1.5));
art.GetGraphic(new ArtQRCodeGraphicOptions
{
PixelsPerModule = 10,
DarkSKColor = SKColors.Black,
LightSKColor = SKColors.White,
BackgroundSKColor = SKColors.Transparent,
PixelSizeFactor = 1.5
}));
}

#endregion
Expand Down
56 changes: 28 additions & 28 deletions QRCoder.Core.Tests/Generators/PayloadGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,9 +1208,9 @@ public void bezahlcode_generator_can_generate_payload_singlepayment_minimal()
var bnc = "100205000";
var name = "Wikimedia Fördergesellschaft";
var amount = 10.00m;
#pragma warning disable CS0612
#pragma warning disable CS0618
var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount);
#pragma warning restore CS0612
#pragma warning restore CS0618
generator
.ToString()
.ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&amount=10,00&currency=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "");
Expand All @@ -1227,9 +1227,9 @@ public void bezahlcode_generator_can_generate_payload_singlepayment_full()
var amount = 10.00m;
var postingKey = 69;
Currency currency = Currency.USD;
#pragma warning disable CS0612
#pragma warning disable CS0618
var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account, bnc, amount, "", 0, null, null, reason, postingKey, currency, DateTime.Now);
#pragma warning restore CS0612
#pragma warning restore CS0618
generator
.ToString()
.ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&postingkey=69&amount=10,00&reason=Thanks%20for%20all%20your%20efforts&currency=USD&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "");
Expand All @@ -1246,9 +1246,9 @@ public void bezahlcode_generator_can_generate_payload_singledirectdebit()
var amount = 10.00m;
var postingKey = 69;
Currency currency = Currency.USD;
#pragma warning disable CS0612
#pragma warning disable CS0618
var generator = new PayloadGenerator.BezahlCode(AuthorityType.singledirectdebit, name, account, bnc, amount, "", 0, null, null, reason, postingKey, currency, DateTime.Now);
#pragma warning restore CS0612
#pragma warning restore CS0618
generator
.ToString()
.ShouldBe("bank://singledirectdebit?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&postingkey=69&amount=10,00&reason=Thanks%20for%20all%20your%20efforts&currency=USD&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "");
Expand All @@ -1269,9 +1269,9 @@ public void bezahlcode_generator_can_generate_payload_periodicsinglepayment()
var periodicFirstExecutionDate = DateTime.Now;
var periodicLastExecutionDate = DateTime.Now.AddMonths(3);
Currency currency = Currency.USD;
#pragma warning disable CS0612
#pragma warning disable CS0618
var generator = new PayloadGenerator.BezahlCode(AuthorityType.periodicsinglepayment, name, account, bnc, amount, periodicTimeunit, periodicTimeunitRotation, periodicFirstExecutionDate, periodicLastExecutionDate, reason, postingKey, currency, DateTime.Now);
#pragma warning restore CS0612
#pragma warning restore CS0618
generator
.ToString()
.ShouldBe("bank://periodicsinglepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&postingkey=69&amount=10,00&reason=Thanks%20for%20all%20your%20efforts&currency=USD&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "&periodictimeunit=W&periodictimeunitrotation=2&periodicfirstexecutiondate=" + periodicFirstExecutionDate.ToString("ddMMyyyy") + "&periodiclastexecutiondate=" + periodicLastExecutionDate.ToString("ddMMyyyy"));
Expand Down Expand Up @@ -1439,9 +1439,9 @@ public void bezahlcode_generator_should_handle_account_whitespaces()
var bnc = "100205000";
var name = "Wikimedia Fördergesellschaft";
var amount = 10.00m;
#pragma warning disable CS0612
#pragma warning disable CS0618
var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount);
#pragma warning restore CS0612
#pragma warning restore CS0618
generator
.ToString()
.ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=01194700&bnc=100205000&amount=10,00&currency=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "");
Expand All @@ -1455,9 +1455,9 @@ public void bezahlcode_generator_should_handle_bnc_whitespaces()
var bnc = "10020 5000";
var name = "Wikimedia Fördergesellschaft";
var amount = 10.00m;
#pragma warning disable CS0612
#pragma warning disable CS0618
var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount);
#pragma warning restore CS0612
#pragma warning restore CS0618
generator
.ToString()
.ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&amount=10,00&currency=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "");
Expand Down Expand Up @@ -1503,9 +1503,9 @@ public void bezahlcode_generator_should_add_decimals()
var bnc = "10020 5000";
var name = "Wikimedia Fördergesellschaft";
var amount = 10;
#pragma warning disable CS0612
#pragma warning disable CS0618
var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount);
#pragma warning restore CS0612
#pragma warning restore CS0618
generator
.ToString()
.ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&amount=10,00&currency=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "");
Expand All @@ -1518,9 +1518,9 @@ public void bezahlcode_generator_should_throw_wrong_contact_constructor_exceptio
var account = "0001194700";
var bnc = "10020 5000";
var name = "Wikimedia Fördergesellschaft";
#pragma warning disable CS0612
#pragma warning disable CS0618
var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account, bnc, "", "", "New business contact."));
#pragma warning restore CS0612
#pragma warning restore CS0618
Assert.NotNull(exception);
Assert.IsType<BezahlCodeException>(exception);
exception.Message.ShouldBe("The constructor without an amount may only ne used with authority types 'contact' and 'contact_v2'.");
Expand Down Expand Up @@ -1572,9 +1572,9 @@ public void bezahlcode_generator_should_throw_wrong_nonsepa_constructor_periodic
var periodicFirstExecutionDate = DateTime.Now;
var periodicLastExecutionDate = DateTime.Now.AddMonths(3);
Currency currency = Currency.USD;
#pragma warning disable CS0612
#pragma warning disable CS0618
var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.periodicsinglepayment, name, account, bnc, amount, periodicTimeunit, periodicTimeunitRotation, periodicFirstExecutionDate, periodicLastExecutionDate, reason, postingKey, currency, DateTime.Now));
#pragma warning restore CS0612
#pragma warning restore CS0618
Assert.NotNull(exception);
Assert.IsType<BezahlCodeException>(exception);
exception.Message.ShouldBe("When using 'periodicsinglepayment' as authority type, the parameters 'periodicTimeunit' and 'periodicTimeunitRotation' must be set.");
Expand All @@ -1588,9 +1588,9 @@ public void bezahlcode_generator_should_throw_wrong_sepa_constructor_exception()
var bic = "BFSWDE33BER";
var name = "Wikimedia Fördergesellschaft";
var amount = 10.00m;
#pragma warning disable CS0612
#pragma warning disable CS0618
var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, iban: iban, bic: bic, amount: amount));
#pragma warning restore CS0612
#pragma warning restore CS0618
Assert.NotNull(exception);
Assert.IsType<BezahlCodeException>(exception);
exception.Message.ShouldBe("The constructor with 'iban' and 'bic' may only be used with 'SEPA' authority types. Either choose another authority type or switch constructor.");
Expand Down Expand Up @@ -1660,9 +1660,9 @@ public void bezahlcode_generator_should_throw_invalid_account_exception()
var bnc = "100205000";
var name = "Wikimedia Fördergesellschaft";
var amount = 10.00m;
#pragma warning disable CS0612
#pragma warning disable CS0618
var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount));
#pragma warning restore CS0612
#pragma warning restore CS0618
Assert.NotNull(exception);
Assert.IsType<BezahlCodeException>(exception);
exception.Message.ShouldBe("The account entered isn't valid.");
Expand All @@ -1676,9 +1676,9 @@ public void bezahlcode_generator_should_throw_invalid_bnc_exception()
var bnc = "10020500023545626226262";
var name = "Wikimedia Fördergesellschaft";
var amount = 10.00m;
#pragma warning disable CS0612
#pragma warning disable CS0618
var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount));
#pragma warning restore CS0612
#pragma warning restore CS0618
Assert.NotNull(exception);
Assert.IsType<BezahlCodeException>(exception);
exception.Message.ShouldBe("The bnc entered isn't valid.");
Expand All @@ -1693,9 +1693,9 @@ public void bezahlcode_generator_should_throw_invalid_postingkey_exception()
var name = "Wikimedia Fördergesellschaft";
var postingKey = 101;
var amount = 10.00m;
#pragma warning disable CS0612
#pragma warning disable CS0618
var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount, postingKey: postingKey));
#pragma warning restore CS0612
#pragma warning restore CS0618
Assert.NotNull(exception);
Assert.IsType<BezahlCodeException>(exception);
exception.Message.ShouldBe("PostingKey must be within 0 and 99.");
Expand Down Expand Up @@ -1840,9 +1840,9 @@ public void bezahlcode_generator_should_throw_invalid_executiondate_exception()
var postingKey = 69;
var executionDate = new DateTime(2017, 1, 1);
Currency currency = Currency.USD;
#pragma warning disable CS0612
#pragma warning disable CS0618
var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account, bnc, amount, "", 0, null, null, reason, postingKey, currency, executionDate));
#pragma warning restore CS0612
#pragma warning restore CS0618
Assert.NotNull(exception);
Assert.IsType<BezahlCodeException>(exception);
exception.Message.ShouldBe("Execution date must be today or in future.");
Expand Down
29 changes: 25 additions & 4 deletions QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ public void can_create_standard_qrcode_graphic_with_custom_finder()
var gen = new QRCodeGenerator();
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
var finder = new SKBitmap(15, 15);
var bmp = new ArtQRCode(data).GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, finderPatternImage: finder);
var bmp = new ArtQRCode(data).GetGraphic(new ArtQRCodeGraphicOptions
{
PixelsPerModule = 10,
DarkSKColor = SKColors.Black,
LightSKColor = SKColors.White,
BackgroundSKColor = SKColors.Transparent,
FinderPatternImage = finder
});

var result = HelperFunctions.BitmapToHash(bmp);
result.ShouldBe("442648a1087f78955773c261b45665c9");
Expand All @@ -43,7 +50,14 @@ public void can_create_standard_qrcode_graphic_without_quietzone()
{
var gen = new QRCodeGenerator();
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
var bmp = new ArtQRCode(data).GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, drawQuietZones: false);
var bmp = new ArtQRCode(data).GetGraphic(new ArtQRCodeGraphicOptions
{
PixelsPerModule = 10,
DarkSKColor = SKColors.Black,
LightSKColor = SKColors.White,
BackgroundSKColor = SKColors.Transparent,
DrawQuietZones = false
});

var result = HelperFunctions.BitmapToHash(bmp);
result.ShouldBe("4bbf0a58f3dc2c82cae0ad874da92028");
Expand All @@ -60,7 +74,7 @@ public void can_create_standard_qrcode_graphic_with_background()

var result = HelperFunctions.BitmapToHash(bmp);

result.ShouldBe("b9ecef2ee7e769d17f5e00914c7452bb");
result.ShouldBe("0ee19045007db3c29f2fc75f33906e49");
}

[Fact]
Expand All @@ -71,7 +85,14 @@ public void should_throw_pixelfactor_oor_exception()
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
var aCode = new ArtQRCode(data);

var exception = Record.Exception(() => aCode.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, pixelSizeFactor: 2));
var exception = Record.Exception(() => aCode.GetGraphic(new ArtQRCodeGraphicOptions
{
PixelsPerModule = 10,
DarkSKColor = SKColors.Black,
LightSKColor = SKColors.White,
BackgroundSKColor = SKColors.Transparent,
PixelSizeFactor = 2
}));
Assert.NotNull(exception);
Assert.IsType<System.ArgumentOutOfRangeException>(exception);
exception.Message.ShouldContain("pixelSizeFactor");
Expand Down
Loading
Loading