Skip to content

Commit 4d3186b

Browse files
Enable recommended analyzers; use invariant culture throughout (#640)
* Add recommended analyzers * Update * Update * update * update * update * do other projects too * update * Update QRCoder/ArtQRCode.cs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Fix exception message for pixelSizeFactor validation --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent 1faf65a commit 4d3186b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+247
-250
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,4 @@ dotnet_diagnostic.IDE0005.severity = warning
263263
# Enforce formatting https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#rule-id-ide0055-fix-formatting
264264
dotnet_diagnostic.IDE0055.severity = error
265265
dotnet_diagnostic.IDE1006.severity = error
266-
dotnet_diagnostic.IDE0022.severity = error
266+
dotnet_diagnostic.IDE0022.severity = none

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<GenerateDocumentationFile>true</GenerateDocumentationFile>
4141
<NoWarn>$(NoWarn);IDE0005</NoWarn>
4242
<EnableNETAnalyzers>True</EnableNETAnalyzers>
43-
<AnalysisMode>None</AnalysisMode>
43+
<AnalysisMode>Recommended</AnalysisMode>
4444
</PropertyGroup>
4545

4646
<!-- Include README for packable projects -->

QRCoder/ASCIIQRCode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public AsciiQRCode(QRCodeData data) : base(data) { }
3131
public string GetGraphic(int repeatPerModule, string darkColorString = "██", string whiteSpaceString = " ", bool drawQuietZones = true, string endOfLine = "\n")
3232
{
3333
if (repeatPerModule < 1)
34-
throw new Exception("The repeatPerModule-parameter must be 1 or greater.");
34+
throw new ArgumentOutOfRangeException(nameof(repeatPerModule), "The repeatPerModule parameter must be 1 or greater.");
3535
return string.Join(endOfLine, GetLineByLineGraphic(repeatPerModule, darkColorString, whiteSpaceString, drawQuietZones));
3636
}
3737

QRCoder/ArtQRCode.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
6363
BackgroundImageStyle backgroundImageStyle = BackgroundImageStyle.DataAreaOnly, Bitmap? finderPatternImage = null)
6464
{
6565
if (pixelSizeFactor > 1)
66-
throw new Exception("The parameter pixelSize must be between 0 and 1. (0-100%)");
66+
throw new ArgumentOutOfRangeException(nameof(pixelSizeFactor), "The parameter pixelSizeFactor must be between 0 and 1. (0-100%)");
6767
int pixelSize = (int)Math.Min(pixelsPerModule, Math.Floor(pixelsPerModule * pixelSizeFactor));
6868

6969
var numModules = QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8);
@@ -134,7 +134,7 @@ public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
134134
/// <param name="pixelSize">Size of the dots</param>
135135
/// <param name="brush">Color of the pixels</param>
136136
/// <returns></returns>
137-
private Bitmap MakeDotPixel(int pixelsPerModule, int pixelSize, SolidBrush brush)
137+
private static Bitmap MakeDotPixel(int pixelsPerModule, int pixelSize, SolidBrush brush)
138138
{
139139
// draw a dot
140140
var bitmap = new Bitmap(pixelSize, pixelSize);
@@ -168,7 +168,7 @@ private Bitmap MakeDotPixel(int pixelsPerModule, int pixelSize, SolidBrush brush
168168
/// <param name="y">Y position</param>
169169
/// <param name="numModules">Total number of modules per row</param>
170170
/// <returns>true, if position is part of quiet zone</returns>
171-
private bool IsPartOfQuietZone(int x, int y, int numModules)
171+
private static bool IsPartOfQuietZone(int x, int y, int numModules)
172172
{
173173
return
174174
x < 4 || //left
@@ -186,7 +186,7 @@ private bool IsPartOfQuietZone(int x, int y, int numModules)
186186
/// <param name="numModules">Total number of modules per row</param>
187187
/// <param name="offset">Offset in modules (usually depending on drawQuietZones parameter)</param>
188188
/// <returns>true, if position is part of any finder pattern</returns>
189-
private bool IsPartOfFinderPattern(int x, int y, int numModules, int offset)
189+
private static bool IsPartOfFinderPattern(int x, int y, int numModules, int offset)
190190
{
191191
var cornerSize = 11 - offset;
192192
var outerLimitLow = (numModules - cornerSize - 1);
@@ -204,7 +204,7 @@ private bool IsPartOfFinderPattern(int x, int y, int numModules, int offset)
204204
/// <param name="image"></param>
205205
/// <param name="newSize"></param>
206206
/// <returns>Resized image as bitmap</returns>
207-
private Bitmap Resize(Bitmap image, int newSize)
207+
private static Bitmap Resize(Bitmap image, int newSize)
208208
{
209209
float scale = Math.Min((float)newSize / image.Width, (float)newSize / image.Height);
210210
var scaledWidth = (int)(image.Width * scale);

QRCoder/Base64QRCode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
141141
#if NET6_0_OR_GREATER
142142
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
143143
#endif
144-
private string BitmapToBase64(Bitmap bmp, ImageType imgType)
144+
private static string BitmapToBase64(Bitmap bmp, ImageType imgType)
145145
{
146146
var iFormat = imgType switch
147147
{

QRCoder/BitmapByteQRCode.cs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public byte[] GetGraphic(int pixelsPerModule)
4141
/// <param name="lightColorHtmlHex">The color of the light modules in HTML hex format.</param>
4242
/// <returns>Returns the QR code graphic as a bitmap byte array.</returns>
4343
public byte[] GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex)
44-
=> GetGraphic(pixelsPerModule, HexColorToByteArray(darkColorHtmlHex), HexColorToByteArray(lightColorHtmlHex));
44+
=> GetGraphic(pixelsPerModule, darkColorHtmlHex.HexColorToByteArray(), lightColorHtmlHex.HexColorToByteArray());
4545

4646
/// <summary>
4747
/// Returns the QR code graphic as a bitmap byte array.
@@ -134,29 +134,13 @@ public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgb, byte[] lightC
134134
}
135135

136136

137-
/// <summary>
138-
/// Converts a hex color string to a byte array.
139-
/// </summary>
140-
/// <param name="colorString">The hex color string to convert.</param>
141-
/// <returns>Returns the color as a byte array.</returns>
142-
private byte[] HexColorToByteArray(string colorString)
143-
{
144-
if (colorString.StartsWith("#"))
145-
colorString = colorString.Substring(1);
146-
byte[] byteColor = new byte[colorString.Length / 2];
147-
for (int i = 0; i < byteColor.Length; i++)
148-
byteColor[i] = byte.Parse(colorString.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture);
149-
return byteColor;
150-
}
151-
152-
153137
/// <summary>
154138
/// Converts an integer to a 4 bytes and writes them to a byte array at given position
155139
/// </summary>
156140
/// <param name="inp">The integer to convert.</param>
157141
/// <param name="destinationIndex">Index of destinationArray where the converted bytes are written to</param>
158142
/// <param name="destinationArray">Destination byte array that receives the bytes</param>
159-
private void CopyIntAs4ByteToArray(int inp, int destinationIndex, byte[] destinationArray)
143+
private static void CopyIntAs4ByteToArray(int inp, int destinationIndex, byte[] destinationArray)
160144
{
161145
unchecked
162146
{

QRCoder/Extensions/StringExtensions.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,30 @@ public static bool IsNullOrWhiteSpace(
2929
return string.IsNullOrWhiteSpace(value);
3030
#endif
3131
}
32+
33+
/// <summary>
34+
/// Converts a hex color string to a byte array.
35+
/// </summary>
36+
/// <param name="colorString">Color in HEX format like #ffffff.</param>
37+
/// <returns>Returns the color as a byte array.</returns>
38+
internal static byte[] HexColorToByteArray(this string colorString)
39+
{
40+
var offset = 0;
41+
if (colorString.StartsWith("#", StringComparison.Ordinal))
42+
offset = 1;
43+
byte[] byteColor = new byte[(colorString.Length - offset) / 2];
44+
for (int i = 0; i < byteColor.Length; i++)
45+
#if HAS_SPAN
46+
byteColor[i] = byte.Parse(colorString.AsSpan(i * 2 + offset, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
47+
#else
48+
byteColor[i] = byte.Parse(colorString.Substring(i * 2 + offset, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
49+
#endif
50+
return byteColor;
51+
}
52+
53+
#if NETSTANDARD1_3
54+
/// <inheritdoc cref="char.ToString()"/>
55+
internal static string ToString(this char c, CultureInfo _)
56+
=> c.ToString();
57+
#endif
3258
}

QRCoder/Extensions/StringValueAttribute.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace QRCoder.Extensions;
77
/// Used to represent a string value for a value in an enum
88
/// </summary>
99
[Obsolete("This attribute will be removed in a future version of QRCoder.")]
10+
[AttributeUsage(AttributeTargets.Field)]
1011
public class StringValueAttribute : Attribute
1112
{
1213

QRCoder/PayloadGenerator.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,24 @@ public static partial class PayloadGenerator
1717
private static bool IsValidIban(string iban)
1818
{
1919
//Clean IBAN
20-
var ibanCleared = iban.ToUpper().Replace(" ", "").Replace("-", "");
20+
var ibanCleared = iban.ToUpperInvariant().Replace(" ", "").Replace("-", "");
2121

2222
//Check for general structure
2323
var structurallyValid = Regex.IsMatch(ibanCleared, @"^[a-zA-Z]{2}[0-9]{2}([a-zA-Z0-9]?){16,30}$");
2424

2525
//Check IBAN checksum
2626
var checksumValid = false;
27-
var sum = $"{ibanCleared.Substring(4)}{ibanCleared.Substring(0, 4)}".ToCharArray().Aggregate("", (current, c) => current + (char.IsLetter(c) ? (c - 55).ToString() : c.ToString()));
27+
var sum = $"{ibanCleared.Substring(4)}{ibanCleared.Substring(0, 4)}".ToCharArray().Aggregate("", (current, c) => current + (char.IsLetter(c) ? (c - 55).ToString(CultureInfo.InvariantCulture) : c.ToString(CultureInfo.InvariantCulture)));
2828
int m = 0;
2929
for (int i = 0; i < (int)Math.Ceiling((sum.Length - 2) / 7d); i++)
3030
{
3131
var offset = (i == 0 ? 0 : 2);
3232
var start = i * 7 + offset;
33+
#if NET5_0_OR_GREATER
34+
var n = string.Concat(i == 0 ? "" : m.ToString(CultureInfo.InvariantCulture), sum.AsSpan(start, Math.Min(9 - offset, sum.Length - start)));
35+
#else
3336
var n = (i == 0 ? "" : m.ToString()) + sum.Substring(start, Math.Min(9 - offset, sum.Length - start));
37+
#endif
3438
if (!int.TryParse(n, NumberStyles.Any, CultureInfo.InvariantCulture, out m))
3539
break;
3640
m %= 97;
@@ -49,8 +53,8 @@ private static bool IsValidQRIban(string iban)
4953
var foundQrIid = false;
5054
try
5155
{
52-
var ibanCleared = iban.ToUpper().Replace(" ", "").Replace("-", "");
53-
var possibleQrIid = Convert.ToInt32(ibanCleared.Substring(4, 5));
56+
var ibanCleared = iban.ToUpperInvariant().Replace(" ", "").Replace("-", "");
57+
var possibleQrIid = Convert.ToInt32(ibanCleared.Substring(4, 5), CultureInfo.InvariantCulture);
5458
foundQrIid = possibleQrIid >= 30000 && possibleQrIid <= 31999;
5559
}
5660
catch { }

QRCoder/PayloadGenerator/BezahlCode.cs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
123123
}
124124
else if (internalMode == 2)
125125
{
126-
#pragma warning disable CS0612
126+
#pragma warning disable CS0618
127127
if (authority != AuthorityType.periodicsinglepayment && authority != AuthorityType.singledirectdebit && authority != AuthorityType.singlepayment)
128128
throw new BezahlCodeException("The constructor with 'account' and 'bnc' may only be used with 'non SEPA' authority types. Either choose another authority type or switch constructor.");
129129
if (authority == AuthorityType.periodicsinglepayment && (string.IsNullOrEmpty(periodicTimeunit) || periodicTimeunitRotation == 0))
130130
throw new BezahlCodeException("When using 'periodicsinglepayment' as authority type, the parameters 'periodicTimeunit' and 'periodicTimeunitRotation' must be set.");
131-
#pragma warning restore CS0612
131+
#pragma warning restore CS0618
132132
}
133133
else if (internalMode == 3)
134134
{
@@ -155,17 +155,17 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
155155
_reason = reason;
156156

157157
//Non-SEPA payment types
158-
#pragma warning disable CS0612
158+
#pragma warning disable CS0618
159159
if (authority == AuthorityType.periodicsinglepayment || authority == AuthorityType.singledirectdebit || authority == AuthorityType.singlepayment || authority == AuthorityType.contact || (authority == AuthorityType.contact_v2 && oldWayFilled))
160160
{
161-
#pragma warning restore CS0612
161+
#pragma warning restore CS0618
162162

163163
if (!Regex.IsMatch(account.Replace(" ", ""), @"^[0-9]{1,9}$"))
164164
throw new BezahlCodeException("The account entered isn't valid.");
165-
_account = account.Replace(" ", "").ToUpper();
165+
_account = account.Replace(" ", "").ToUpperInvariant();
166166
if (!Regex.IsMatch(bnc.Replace(" ", ""), @"^[0-9]{1,9}$"))
167167
throw new BezahlCodeException("The bnc entered isn't valid.");
168-
_bnc = bnc.Replace(" ", "").ToUpper();
168+
_bnc = bnc.Replace(" ", "").ToUpperInvariant();
169169

170170
if (authority != AuthorityType.contact && authority != AuthorityType.contact_v2)
171171
{
@@ -180,10 +180,10 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
180180
{
181181
if (!IsValidIban(iban))
182182
throw new BezahlCodeException("The IBAN entered isn't valid.");
183-
_iban = iban.Replace(" ", "").ToUpper();
183+
_iban = iban.Replace(" ", "").ToUpperInvariant();
184184
if (!IsValidBic(bic))
185185
throw new BezahlCodeException("The BIC entered isn't valid.");
186-
_bic = bic.Replace(" ", "").ToUpper();
186+
_bic = bic.Replace(" ", "").ToUpperInvariant();
187187

188188
if (authority != AuthorityType.contact_v2)
189189
{
@@ -205,7 +205,7 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
205205
//Checks for all payment types
206206
if (authority != AuthorityType.contact && authority != AuthorityType.contact_v2)
207207
{
208-
if (amount.ToString().Replace(",", ".").Contains(".") && amount.ToString().Replace(",", ".").Split('.')[1].TrimEnd('0').Length > 2)
208+
if (amount.ToString(CultureInfo.InvariantCulture).Contains('.') && amount.ToString(CultureInfo.InvariantCulture).Split('.')[1].TrimEnd('0').Length > 2)
209209
throw new BezahlCodeException("Amount must have less than 3 digits after decimal point.");
210210
if (amount < 0.01m || amount > 999999999.99m)
211211
throw new BezahlCodeException("Amount has to at least 0.01 and must be smaller or equal to 999999999.99.");
@@ -221,11 +221,11 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
221221
throw new BezahlCodeException("Execution date must be today or in future.");
222222
_executionDate = (DateTime)executionDate;
223223
}
224-
#pragma warning disable CS0612
224+
#pragma warning disable CS0618
225225
if (authority == AuthorityType.periodicsinglepayment || authority == AuthorityType.periodicsinglepaymentsepa)
226-
#pragma warning restore CS0612
226+
#pragma warning restore CS0618
227227
{
228-
if (periodicTimeunit.ToUpper() != "M" && periodicTimeunit.ToUpper() != "W")
228+
if (periodicTimeunit.ToUpperInvariant() != "M" && periodicTimeunit.ToUpperInvariant() != "W")
229229
throw new BezahlCodeException("The periodicTimeunit must be either 'M' (monthly) or 'W' (weekly).");
230230
_periodicTimeunit = periodicTimeunit;
231231
if (periodicTimeunitRotation < 1 || periodicTimeunitRotation > 52)
@@ -253,9 +253,9 @@ public override string ToString()
253253
if (_authority != AuthorityType.contact && _authority != AuthorityType.contact_v2)
254254
{
255255
//Handle what is same for all payments
256-
#pragma warning disable CS0612
256+
#pragma warning disable CS0618
257257
if (_authority == AuthorityType.periodicsinglepayment || _authority == AuthorityType.singledirectdebit || _authority == AuthorityType.singlepayment)
258-
#pragma warning restore CS0612
258+
#pragma warning restore CS0618
259259
{
260260
bezahlCodePayload += $"account={_account}&";
261261
bezahlCodePayload += $"bnc={_bnc}&";
@@ -277,26 +277,26 @@ public override string ToString()
277277
if (!string.IsNullOrEmpty(_mandateId))
278278
bezahlCodePayload += $"mandateid={Uri.EscapeDataString(_mandateId)}&";
279279
if (_dateOfSignature != DateTime.MinValue)
280-
bezahlCodePayload += $"dateofsignature={_dateOfSignature.ToString("ddMMyyyy")}&";
280+
bezahlCodePayload += $"dateofsignature={_dateOfSignature.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
281281
}
282282
}
283-
bezahlCodePayload += $"amount={_amount:0.00}&".Replace(".", ",");
283+
bezahlCodePayload += string.Format(CultureInfo.InvariantCulture, "amount={0:0.00}&", _amount).Replace(".", ",");
284284

285285
if (!string.IsNullOrEmpty(_reason))
286286
bezahlCodePayload += $"reason={Uri.EscapeDataString(_reason)}&";
287287
bezahlCodePayload += $"currency={_currency}&";
288-
bezahlCodePayload += $"executiondate={_executionDate.ToString("ddMMyyyy")}&";
289-
#pragma warning disable CS0612
288+
bezahlCodePayload += $"executiondate={_executionDate.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
289+
#pragma warning disable CS0618
290290
if (_authority == AuthorityType.periodicsinglepayment || _authority == AuthorityType.periodicsinglepaymentsepa)
291291
{
292292
bezahlCodePayload += $"periodictimeunit={_periodicTimeunit}&";
293293
bezahlCodePayload += $"periodictimeunitrotation={_periodicTimeunitRotation}&";
294294
if (_periodicFirstExecutionDate != DateTime.MinValue)
295-
bezahlCodePayload += $"periodicfirstexecutiondate={_periodicFirstExecutionDate.ToString("ddMMyyyy")}&";
295+
bezahlCodePayload += $"periodicfirstexecutiondate={_periodicFirstExecutionDate.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
296296
if (_periodicLastExecutionDate != DateTime.MinValue)
297-
bezahlCodePayload += $"periodiclastexecutiondate={_periodicLastExecutionDate.ToString("ddMMyyyy")}&";
297+
bezahlCodePayload += $"periodiclastexecutiondate={_periodicLastExecutionDate.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
298298
}
299-
#pragma warning restore CS0612
299+
#pragma warning restore CS0618
300300
}
301301
else
302302
{
@@ -1047,6 +1047,7 @@ public enum Currency
10471047
}
10481048

10491049

1050+
#pragma warning disable CA1707 // Underscore in identifier
10501051
/// <summary>
10511052
/// Operation modes of the BezahlCode
10521053
/// </summary>
@@ -1055,7 +1056,7 @@ public enum AuthorityType
10551056
/// <summary>
10561057
/// Single payment (Überweisung)
10571058
/// </summary>
1058-
[Obsolete]
1059+
[Obsolete("Use singlepaymentsepa instead for SEPA-compliant payments")]
10591060
singlepayment,
10601061
/// <summary>
10611062
/// Single SEPA payment (SEPA-Überweisung)
@@ -1064,7 +1065,7 @@ public enum AuthorityType
10641065
/// <summary>
10651066
/// Single debit (Lastschrift)
10661067
/// </summary>
1067-
[Obsolete]
1068+
[Obsolete("Use singledirectdebitsepa instead for SEPA-compliant payments")]
10681069
singledirectdebit,
10691070
/// <summary>
10701071
/// Single SEPA debit (SEPA-Lastschrift)
@@ -1073,7 +1074,7 @@ public enum AuthorityType
10731074
/// <summary>
10741075
/// Periodic payment (Dauerauftrag)
10751076
/// </summary>
1076-
[Obsolete]
1077+
[Obsolete("Use periodicsinglepaymentsepa instead for SEPA-compliant payments")]
10771078
periodicsinglepayment,
10781079
/// <summary>
10791080
/// Periodic SEPA payment (SEPA-Dauerauftrag)
@@ -1088,6 +1089,7 @@ public enum AuthorityType
10881089
/// </summary>
10891090
contact_v2
10901091
}
1092+
#pragma warning restore CA1707 // Underscore in identifier
10911093

10921094
/// <summary>
10931095
/// Exception class for BezahlCode errors.

0 commit comments

Comments
 (0)