Skip to content

Commit c4003f5

Browse files
authored
Specify comparison rules for strings (npgsql#3993)
Closes npgsql#3992
1 parent 4d59325 commit c4003f5

8 files changed

+22
-16
lines changed

.editorconfig

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ csharp_indent_switch_labels = false
5252

5353
# Reliability Rules
5454

55+
[src/Npgsql/**.cs]
56+
# CA1310: Specify StringComparison for correctness
57+
dotnet_diagnostic.CA1310.severity = error
58+
5559
# CA2016: Forward the 'CancellationToken' parameter to methods that take one
5660
dotnet_diagnostic.CA2016.severity = error
5761

src/Npgsql/BackendMessages/AuthenticationMessages.cs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using Npgsql.Internal;
34
using Npgsql.Logging;
45
using Npgsql.Util;
@@ -143,11 +144,11 @@ internal static AuthenticationSCRAMServerFirstMessage Load(byte[] bytes)
143144

144145
foreach (var part in data.Split(','))
145146
{
146-
if (part.StartsWith("r="))
147+
if (part.StartsWith("r=", StringComparison.Ordinal))
147148
nonce = part.Substring(2);
148-
else if (part.StartsWith("s="))
149+
else if (part.StartsWith("s=", StringComparison.Ordinal))
149150
salt = part.Substring(2);
150-
else if (part.StartsWith("i="))
151+
else if (part.StartsWith("i=", StringComparison.Ordinal))
151152
iteration = int.Parse(part.Substring(2));
152153
else
153154
Log.Debug("Unknown part in SCRAM server-first message:" + part);
@@ -196,7 +197,7 @@ internal static AuthenticationSCRAMServerFinalMessage Load(byte[] bytes)
196197

197198
foreach (var part in data.Split(','))
198199
{
199-
if (part.StartsWith("v="))
200+
if (part.StartsWith("v=", StringComparison.Ordinal))
200201
serverSignature = part.Substring(2);
201202
else
202203
Log.Debug("Unknown part in SCRAM server-first message:" + part);

src/Npgsql/Internal/NpgsqlConnector.Auth.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ async Task AuthenticateSASL(List<string> mechanisms, string username, bool async
168168
if (saslContinueMsg.AuthRequestType != AuthenticationRequestType.AuthenticationSASLContinue)
169169
throw new NpgsqlException("[SASL] AuthenticationSASLContinue message expected");
170170
var firstServerMsg = AuthenticationSCRAMServerFirstMessage.Load(saslContinueMsg.Payload);
171-
if (!firstServerMsg.Nonce.StartsWith(clientNonce))
171+
if (!firstServerMsg.Nonce.StartsWith(clientNonce, StringComparison.Ordinal))
172172
throw new NpgsqlException("[SCRAM] Malformed SCRAMServerFirst message: server nonce doesn't start with client nonce");
173173

174174
var saltBytes = Convert.FromBase64String(firstServerMsg.Salt);

src/Npgsql/NpgsqlCommandBuilder.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,10 @@ public override string UnquoteIdentifier(string quotedIdentifier)
303303

304304
var unquotedIdentifier = quotedIdentifier.Trim().Replace(QuotePrefix + QuotePrefix, QuotePrefix);
305305

306-
if (unquotedIdentifier.StartsWith(QuotePrefix))
306+
if (unquotedIdentifier.StartsWith(QuotePrefix, StringComparison.Ordinal))
307307
unquotedIdentifier = unquotedIdentifier.Remove(0, 1);
308308

309-
if (unquotedIdentifier.EndsWith(QuoteSuffix))
309+
if (unquotedIdentifier.EndsWith(QuoteSuffix, StringComparison.Ordinal))
310310
unquotedIdentifier = unquotedIdentifier.Remove(unquotedIdentifier.Length - 1, 1);
311311

312312
return unquotedIdentifier;

src/Npgsql/NpgsqlConnection.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ async Task<NpgsqlBinaryImporter> BeginBinaryImport(string copyFromCommand, bool
11461146
{
11471147
if (copyFromCommand == null)
11481148
throw new ArgumentNullException(nameof(copyFromCommand));
1149-
if (!copyFromCommand.TrimStart().ToUpper().StartsWith("COPY"))
1149+
if (!copyFromCommand.TrimStart().ToUpper().StartsWith("COPY", StringComparison.Ordinal))
11501150
throw new ArgumentException("Must contain a COPY FROM STDIN command!", nameof(copyFromCommand));
11511151

11521152
CheckReady();
@@ -1200,7 +1200,7 @@ async Task<NpgsqlBinaryExporter> BeginBinaryExport(string copyToCommand, bool as
12001200
{
12011201
if (copyToCommand == null)
12021202
throw new ArgumentNullException(nameof(copyToCommand));
1203-
if (!copyToCommand.TrimStart().ToUpper().StartsWith("COPY"))
1203+
if (!copyToCommand.TrimStart().ToUpper().StartsWith("COPY", StringComparison.Ordinal))
12041204
throw new ArgumentException("Must contain a COPY TO STDOUT command!", nameof(copyToCommand));
12051205

12061206
CheckReady();
@@ -1260,7 +1260,7 @@ async Task<TextWriter> BeginTextImport(string copyFromCommand, bool async, Cance
12601260
{
12611261
if (copyFromCommand == null)
12621262
throw new ArgumentNullException(nameof(copyFromCommand));
1263-
if (!copyFromCommand.TrimStart().ToUpper().StartsWith("COPY"))
1263+
if (!copyFromCommand.TrimStart().ToUpper().StartsWith("COPY", StringComparison.Ordinal))
12641264
throw new ArgumentException("Must contain a COPY FROM STDIN command!", nameof(copyFromCommand));
12651265

12661266
CheckReady();
@@ -1321,7 +1321,7 @@ async Task<TextReader> BeginTextExport(string copyToCommand, bool async, Cancell
13211321
{
13221322
if (copyToCommand == null)
13231323
throw new ArgumentNullException(nameof(copyToCommand));
1324-
if (!copyToCommand.TrimStart().ToUpper().StartsWith("COPY"))
1324+
if (!copyToCommand.TrimStart().ToUpper().StartsWith("COPY", StringComparison.Ordinal))
13251325
throw new ArgumentException("Must contain a COPY TO STDOUT command!", nameof(copyToCommand));
13261326

13271327
CheckReady();
@@ -1382,7 +1382,7 @@ async Task<NpgsqlRawCopyStream> BeginRawBinaryCopy(string copyCommand, bool asyn
13821382
{
13831383
if (copyCommand == null)
13841384
throw new ArgumentNullException(nameof(copyCommand));
1385-
if (!copyCommand.TrimStart().ToUpper().StartsWith("COPY"))
1385+
if (!copyCommand.TrimStart().ToUpper().StartsWith("COPY", StringComparison.Ordinal))
13861386
throw new ArgumentException("Must contain a COPY TO STDOUT OR COPY FROM STDIN command!", nameof(copyCommand));
13871387

13881388
CheckReady();

src/Npgsql/NpgsqlTypes/NpgsqlTsVector.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal NpgsqlTsVector(List<Lexeme> lexemes, bool noCheck = false)
2929

3030
// Culture-specific comparisons doesn't really matter for the backend. It's sorting on its own if it detects an unsorted collection.
3131
// Only when a .NET user wants to print the sort order.
32-
_lexemes.Sort((a, b) => a.Text.CompareTo(b.Text));
32+
_lexemes.Sort((a, b) => string.Compare(a.Text, b.Text, StringComparison.CurrentCulture));
3333

3434
var res = 0;
3535
var pos = 1;

src/Npgsql/PostgresErrorCodes.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
22

3+
using System;
34
using System.Linq;
45

56
namespace Npgsql
@@ -476,6 +477,6 @@ public static class PostgresErrorCodes
476477
};
477478

478479
internal static bool IsCriticalFailure(PostgresException e)
479-
=> CriticalFailureCodes.Any(x => e.SqlState.StartsWith(x));
480+
=> CriticalFailureCodes.Any(x => e.SqlState.StartsWith(x, StringComparison.Ordinal));
480481
}
481482
}

src/Npgsql/Schema/DbColumnSchemaGenerator.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ NpgsqlDbColumn LoadColumnDefinition(NpgsqlDataReader reader, NpgsqlDatabaseInfo
218218

219219
column.IsAutoIncrement =
220220
!oldQueryMode && reader.GetBoolean(reader.GetOrdinal("isidentity")) ||
221-
column.DefaultValue != null && column.DefaultValue.StartsWith("nextval(");
221+
column.DefaultValue != null && column.DefaultValue.StartsWith("nextval(", StringComparison.Ordinal);
222222

223223
ColumnPostConfig(column, reader.GetInt32(reader.GetOrdinal("typmod")));
224224

0 commit comments

Comments
 (0)