From fb45a09d7ae8f05fd18d5518f08c7efdca042d48 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 28 Mar 2025 15:11:00 +0100 Subject: [PATCH 01/21] C#: Add cs/invalid-string-formatting to the codeql quality suite. --- csharp/ql/src/codeql-suites/csharp-code-quality.qls | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/ql/src/codeql-suites/csharp-code-quality.qls b/csharp/ql/src/codeql-suites/csharp-code-quality.qls index a7cfd44d7348..64a100acda22 100644 --- a/csharp/ql/src/codeql-suites/csharp-code-quality.qls +++ b/csharp/ql/src/codeql-suites/csharp-code-quality.qls @@ -13,3 +13,4 @@ - cs/useless-gethashcode-call - cs/non-short-circuit - cs/useless-assignment-to-local + - cs/invalid-string-formatting From 629817d1d1b1a8f4a4ae7e850a0c3bddef01722f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 3 Apr 2025 15:00:04 +0200 Subject: [PATCH 02/21] C#: Convert testing of cs/invalid-string-formatting to inline expectations and adjust some of the testcases. --- .../API Abuse/FormatInvalid/FormatInvalid.cs | 102 ++++++------ .../FormatInvalid/FormatInvalid.expected | 150 +++++++++--------- .../FormatInvalid/FormatInvalid.qlref | 3 +- .../FormatInvalid/FormatInvalidBad.cs | 2 +- .../FormatInvalid/FormatMissingArgument.cs | 10 +- .../FormatInvalid/FormatMissingArgumentBad.cs | 4 +- .../FormatInvalid/FormatUnusedArgument.cs | 14 +- .../FormatInvalid/FormatUnusedArgumentBad.cs | 6 +- 8 files changed, 144 insertions(+), 147 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs index 4789da9cf6b5..d65870f3a32d 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs @@ -24,38 +24,38 @@ void FormatStringTests() String.Format("{0, -10 :0.000}", 1); // BAD: Invalid format string - String.Format("{ 0}", 1); + String.Format("{ 0}", 1); // $ Alert // BAD: Invalid format string - String.Format("{0,--1}", 1); + String.Format("{0,--1}", 1); // $ Alert // BAD: Invalid format string - String.Format("{0:{}}", 1); + String.Format("{0:{}}", 1); // $ Alert // BAD: Invalid format string - String.Format("%d", 1); + String.Format("%d", 1); // $ Alert Sink // BAD: } { in the middle. - String.Format("{{0}-{1}}", 0, 1); + String.Format("{{0}-{1}}", 0, 1); // $ Alert // BAD: This is invalid - String.Format("{0}}", 0, 1); + String.Format("{0}}", 0, 1); // $ Alert // BAD: Invalid - string.Format("{foo{0}}", 0); + string.Format("{foo{0}}", 0); // $ Alert // GOOD: {{ is output as { - String.Format("{{sdc}}", 0); + String.Format("{{sdc}}{0}", 0); // BAD: Invalid: Stray } - String.Format("}", 0); + String.Format("}{0}", 0); // $ Alert // GOOD: {{ output as { - String.Format("new {0} ({1} => {{", 0); + String.Format("new {0} ({1} => {{", 0, 1); // GOOD: Literal {{ and }} - String.Format("{{", ""); - String.Format("{{{{}}", ""); + String.Format("{0}{{", 0); + String.Format("{0}{{{{}}", 0); } IFormatProvider fp; @@ -72,49 +72,49 @@ void FormatMethodTests() Format("}", 0); // BAD: All of these are format methods with an invalid string. - String.Format("}", 0); - String.Format("}", ps); - String.Format(fp, "}", ps); - String.Format("}", 0, 1); - String.Format("}", 0, 1, 2); - String.Format("}", 0, 1, 2, 3); - - sb.AppendFormat("}", 0); - sb.AppendFormat("}", ps); - sb.AppendFormat(fp, "}", ps); - sb.AppendFormat("}", 0, 1); - sb.AppendFormat("}", 0, 1, 2); - sb.AppendFormat("}", 0, 1, 2, 3); - - Console.WriteLine("}", 0); - Console.WriteLine("}", ps); - Console.WriteLine("}", 0, 1); - Console.WriteLine("}", 0, 1, 2); - Console.WriteLine("}", 0, 1, 2, 3); - - tw.WriteLine("}", 0); - tw.WriteLine("}", ps); - tw.WriteLine("}", 0, 1); - tw.WriteLine("}", 0, 1, 2); - tw.WriteLine("}", 0, 1, 2, 3); - - System.Diagnostics.Debug.WriteLine("}", ps); - System.Diagnostics.Trace.TraceError("}", 0); - System.Diagnostics.Trace.TraceInformation("}", 0); - System.Diagnostics.Trace.TraceWarning("}", 0); - ts.TraceInformation("}", 0); - - Console.Write("}", 0); - Console.Write("}", 0, 1); - Console.Write("}", 0, 1, 2); - Console.Write("}", 0, 1, 2, 3); + String.Format("}", 0); // $ Alert + String.Format("}", ps); // $ Alert + String.Format(fp, "}", ps); // $ Alert + String.Format("}", 0, 1); // $ Alert + String.Format("}", 0, 1, 2); // $ Alert + String.Format("}", 0, 1, 2, 3); // $ Alert + + sb.AppendFormat("}", 0); // $ Alert + sb.AppendFormat("}", ps); // $ Alert + sb.AppendFormat(fp, "}", ps); // $ Alert + sb.AppendFormat("}", 0, 1); // $ Alert + sb.AppendFormat("}", 0, 1, 2); // $ Alert + sb.AppendFormat("}", 0, 1, 2, 3); // $ Alert + + Console.WriteLine("}", 0); // $ Alert + Console.WriteLine("}", ps); // $ Alert + Console.WriteLine("}", 0, 1); // $ Alert + Console.WriteLine("}", 0, 1, 2); // $ Alert + Console.WriteLine("}", 0, 1, 2, 3); // $ Alert + + tw.WriteLine("}", 0); // $ Alert + tw.WriteLine("}", ps); // $ Alert + tw.WriteLine("}", 0, 1); // $ Alert + tw.WriteLine("}", 0, 1, 2); // $ Alert + tw.WriteLine("}", 0, 1, 2, 3); // $ Alert + + System.Diagnostics.Debug.WriteLine("}", ps); // $ Alert + System.Diagnostics.Trace.TraceError("}", 0); // $ Alert + System.Diagnostics.Trace.TraceInformation("}", 0); // $ Alert + System.Diagnostics.Trace.TraceWarning("}", 0); // $ Alert + ts.TraceInformation("}", 0); // $ Alert + + Console.Write("}", 0); // $ Alert + Console.Write("}", 0, 1); // $ Alert + Console.Write("}", 0, 1, 2); // $ Alert + Console.Write("}", 0, 1, 2, 3); // $ Alert System.Diagnostics.Debug.WriteLine("}", ""); // GOOD System.Diagnostics.Debug.Write("}", ""); // GOOD - System.Diagnostics.Debug.Assert(true, "Error", "}", ps); - sw.Write("}", 0); - System.Diagnostics.Debug.Print("}", ps); + System.Diagnostics.Debug.Assert(true, "Error", "}", ps); // $ Alert + sw.Write("}", 0); // $ Alert + System.Diagnostics.Debug.Print("}", ps); // $ Alert Console.WriteLine("}"); // GOOD } diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index a1c5e9254370..b23ee42559b9 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -1,3 +1,72 @@ +#select +| FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:27:9:27:32 | call to method Format | this | FormatInvalid.cs:27:9:27:32 | call to method Format | this | +| FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:30:9:30:35 | call to method Format | this | FormatInvalid.cs:30:9:30:35 | call to method Format | this | +| FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:33:9:33:34 | call to method Format | this | FormatInvalid.cs:33:9:33:34 | call to method Format | this | +| FormatInvalid.cs:36:9:36:30 | call to method Format | FormatInvalid.cs:36:23:36:26 | "%d" | FormatInvalid.cs:36:23:36:26 | "%d" | The $@ ignores $@. | FormatInvalid.cs:36:23:36:26 | "%d" | format string | FormatInvalid.cs:36:29:36:29 | (...) ... | this supplied value | +| FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:39:9:39:40 | call to method Format | this | FormatInvalid.cs:39:9:39:40 | call to method Format | this | +| FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this | FormatInvalid.cs:42:9:42:35 | call to method Format | this | +| FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this | FormatInvalid.cs:45:9:45:36 | call to method Format | this | +| FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:32 | call to method Format | this | FormatInvalid.cs:51:9:51:32 | call to method Format | this | +| FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:29 | call to method Format | this | FormatInvalid.cs:75:9:75:29 | call to method Format | this | +| FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:30 | call to method Format | this | FormatInvalid.cs:76:9:76:30 | call to method Format | this | +| FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:34 | call to method Format | this | FormatInvalid.cs:77:9:77:34 | call to method Format | this | +| FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:32 | call to method Format | this | FormatInvalid.cs:78:9:78:32 | call to method Format | this | +| FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:35 | call to method Format | this | FormatInvalid.cs:79:9:79:35 | call to method Format | this | +| FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:38 | call to method Format | this | FormatInvalid.cs:80:9:80:38 | call to method Format | this | +| FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | +| FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | +| FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | +| FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | +| FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | +| FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | +| FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | +| FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | +| FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | +| FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | +| FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | +| FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | +| FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | +| FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | +| FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | +| FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | +| FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | +| FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | +| FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | +| FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | +| FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | +| FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:29 | call to method Write | this | FormatInvalid.cs:107:9:107:29 | call to method Write | this | +| FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:32 | call to method Write | this | FormatInvalid.cs:108:9:108:32 | call to method Write | this | +| FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:35 | call to method Write | this | FormatInvalid.cs:109:9:109:35 | call to method Write | this | +| FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:38 | call to method Write | this | FormatInvalid.cs:110:9:110:38 | call to method Write | this | +| FormatInvalid.cs:115:56:115:58 | "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | +| FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:116:9:116:24 | call to method Write | this | FormatInvalid.cs:116:9:116:24 | call to method Write | this | +| FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:47 | call to method Print | this | FormatInvalid.cs:117:9:117:47 | call to method Print | this | +| FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | +| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | +| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | format string | FormatMissingArgument.cs:11:30:11:30 | (...) ... | this supplied value | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:34:14:34 | (...) ... | this supplied value | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:37:14:37 | (...) ... | this supplied value | +| FormatMissingArgument.cs:25:9:25:32 | call to method WriteLine | FormatMissingArgument.cs:25:27:25:31 | "{0}" | FormatMissingArgument.cs:25:27:25:31 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | +| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | +| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | format string | FormatMissingArgument.cs:31:31:31:31 | (...) ... | this supplied value | +| FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | +| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | +| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | The $@ ignores $@. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | format string | FormatMissingArgumentBad.cs:8:44:8:48 | access to parameter first | this supplied value | +| FormatUnusedArgument.cs:11:9:11:29 | call to method Format | FormatUnusedArgument.cs:11:23:11:25 | "X" | FormatUnusedArgument.cs:11:23:11:25 | "X" | The $@ ignores $@. | FormatUnusedArgument.cs:11:23:11:25 | "X" | format string | FormatUnusedArgument.cs:11:28:11:28 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:14:9:14:34 | call to method Format | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | The $@ ignores $@. | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | format string | FormatUnusedArgument.cs:14:33:14:33 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:17:9:17:38 | call to method Format | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | The $@ ignores $@. | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:17:37:17:37 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:20:9:20:38 | call to method Format | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | The $@ ignores $@. | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:20:34:20:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:34:23:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:37:23:37 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:40:23:40 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:26:9:26:35 | call to method Format | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:26:34:26:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:38:9:38:33 | call to method Format | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | format string | FormatUnusedArgument.cs:38:32:38:32 | (...) ... | this supplied value | +| FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value | +| FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value | +| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value | +| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value | edges | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:24:28:29 | format : String | provenance | | | FormatMissingArgument.cs:28:24:28:29 | format : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | provenance | | @@ -15,11 +84,11 @@ nodes | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | semmle.label | "{{0}-{1}}" | | FormatInvalid.cs:42:23:42:28 | "{0}}" | semmle.label | "{0}}" | | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | semmle.label | "{foo{0}}" | -| FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | -| FormatInvalid.cs:51:23:51:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:48:23:48:34 | "{{sdc}}{0}" | semmle.label | "{{sdc}}{0}" | +| FormatInvalid.cs:51:23:51:28 | "}{0}" | semmle.label | "}{0}" | | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | semmle.label | "new {0} ({1} => {{" | -| FormatInvalid.cs:57:23:57:26 | "{{" | semmle.label | "{{" | -| FormatInvalid.cs:58:23:58:30 | "{{{{}}" | semmle.label | "{{{{}}" | +| FormatInvalid.cs:57:23:57:29 | "{0}{{" | semmle.label | "{0}{{" | +| FormatInvalid.cs:58:23:58:33 | "{0}{{{{}}" | semmle.label | "{0}{{{{}}" | | FormatInvalid.cs:75:23:75:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:76:23:76:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:77:27:77:29 | "}" | semmle.label | "}" | @@ -85,76 +154,3 @@ nodes | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | subpaths -#select -| FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:27:9:27:32 | call to method Format | this | FormatInvalid.cs:27:9:27:32 | call to method Format | this | -| FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:30:9:30:35 | call to method Format | this | FormatInvalid.cs:30:9:30:35 | call to method Format | this | -| FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:33:9:33:34 | call to method Format | this | FormatInvalid.cs:33:9:33:34 | call to method Format | this | -| FormatInvalid.cs:36:9:36:30 | call to method Format | FormatInvalid.cs:36:23:36:26 | "%d" | FormatInvalid.cs:36:23:36:26 | "%d" | The $@ ignores $@. | FormatInvalid.cs:36:23:36:26 | "%d" | format string | FormatInvalid.cs:36:29:36:29 | (...) ... | this supplied value | -| FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:39:9:39:40 | call to method Format | this | FormatInvalid.cs:39:9:39:40 | call to method Format | this | -| FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this | FormatInvalid.cs:42:9:42:35 | call to method Format | this | -| FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this | FormatInvalid.cs:45:9:45:36 | call to method Format | this | -| FormatInvalid.cs:48:9:48:35 | call to method Format | FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | The $@ ignores $@. | FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | format string | FormatInvalid.cs:48:34:48:34 | (...) ... | this supplied value | -| FormatInvalid.cs:51:23:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:29 | call to method Format | this | FormatInvalid.cs:51:9:51:29 | call to method Format | this | -| FormatInvalid.cs:54:9:54:46 | call to method Format | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | Argument '{1}' has not been supplied to $@ format string. | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | this | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | this | -| FormatInvalid.cs:57:9:57:31 | call to method Format | FormatInvalid.cs:57:23:57:26 | "{{" | FormatInvalid.cs:57:23:57:26 | "{{" | The $@ ignores $@. | FormatInvalid.cs:57:23:57:26 | "{{" | format string | FormatInvalid.cs:57:29:57:30 | "" | this supplied value | -| FormatInvalid.cs:58:9:58:35 | call to method Format | FormatInvalid.cs:58:23:58:30 | "{{{{}}" | FormatInvalid.cs:58:23:58:30 | "{{{{}}" | The $@ ignores $@. | FormatInvalid.cs:58:23:58:30 | "{{{{}}" | format string | FormatInvalid.cs:58:33:58:34 | "" | this supplied value | -| FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:29 | call to method Format | this | FormatInvalid.cs:75:9:75:29 | call to method Format | this | -| FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:30 | call to method Format | this | FormatInvalid.cs:76:9:76:30 | call to method Format | this | -| FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:34 | call to method Format | this | FormatInvalid.cs:77:9:77:34 | call to method Format | this | -| FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:32 | call to method Format | this | FormatInvalid.cs:78:9:78:32 | call to method Format | this | -| FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:35 | call to method Format | this | FormatInvalid.cs:79:9:79:35 | call to method Format | this | -| FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:38 | call to method Format | this | FormatInvalid.cs:80:9:80:38 | call to method Format | this | -| FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | -| FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | -| FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | -| FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | -| FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | -| FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | -| FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | -| FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | -| FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | -| FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | -| FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | -| FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | -| FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | -| FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | -| FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | -| FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | -| FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | -| FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | -| FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | -| FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | -| FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | -| FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:29 | call to method Write | this | FormatInvalid.cs:107:9:107:29 | call to method Write | this | -| FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:32 | call to method Write | this | FormatInvalid.cs:108:9:108:32 | call to method Write | this | -| FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:35 | call to method Write | this | FormatInvalid.cs:109:9:109:35 | call to method Write | this | -| FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:38 | call to method Write | this | FormatInvalid.cs:110:9:110:38 | call to method Write | this | -| FormatInvalid.cs:115:56:115:58 | "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | -| FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:116:9:116:24 | call to method Write | this | FormatInvalid.cs:116:9:116:24 | call to method Write | this | -| FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:47 | call to method Print | this | FormatInvalid.cs:117:9:117:47 | call to method Print | this | -| FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | -| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | -| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | format string | FormatMissingArgument.cs:11:30:11:30 | (...) ... | this supplied value | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:34:14:34 | (...) ... | this supplied value | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:37:14:37 | (...) ... | this supplied value | -| FormatMissingArgument.cs:25:9:25:32 | call to method WriteLine | FormatMissingArgument.cs:25:27:25:31 | "{0}" | FormatMissingArgument.cs:25:27:25:31 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | -| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | -| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | format string | FormatMissingArgument.cs:31:31:31:31 | (...) ... | this supplied value | -| FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | -| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | -| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | The $@ ignores $@. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | format string | FormatMissingArgumentBad.cs:8:44:8:48 | access to parameter first | this supplied value | -| FormatUnusedArgument.cs:11:9:11:29 | call to method Format | FormatUnusedArgument.cs:11:23:11:25 | "X" | FormatUnusedArgument.cs:11:23:11:25 | "X" | The $@ ignores $@. | FormatUnusedArgument.cs:11:23:11:25 | "X" | format string | FormatUnusedArgument.cs:11:28:11:28 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:14:9:14:34 | call to method Format | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | The $@ ignores $@. | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | format string | FormatUnusedArgument.cs:14:33:14:33 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:17:9:17:38 | call to method Format | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | The $@ ignores $@. | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:17:37:17:37 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:20:9:20:38 | call to method Format | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | The $@ ignores $@. | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:20:34:20:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:34:23:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:37:23:37 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:40:23:40 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:26:9:26:35 | call to method Format | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:26:34:26:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:38:9:38:33 | call to method Format | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | format string | FormatUnusedArgument.cs:38:32:38:32 | (...) ... | this supplied value | -| FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value | -| FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value | -| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value | -| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value | diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.qlref b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.qlref index 75f1d04fe147..9c660b69de53 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.qlref +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.qlref @@ -1 +1,2 @@ -API Abuse/FormatInvalid.ql \ No newline at end of file +query: API Abuse/FormatInvalid.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs index ec3df72655de..424781b80bc7 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs @@ -4,6 +4,6 @@ class Bad1 { string GenerateEmptyClass(string c) { - return string.Format("class {0} { }", "C"); + return string.Format("class {0} { }", "C"); // $ Alert } } diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs index 94201c0ddf8e..fa046a6fc7c6 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs @@ -8,10 +8,10 @@ void TestFormatMissingArgument() String.Format("{0}", 0); // BAD: Missing {1} - String.Format("{1}", 0); + String.Format("{1}", 0); // $ Alert Sink // BAD: Missing {2} and {3} - String.Format("{2} {3}", 0, 1); + String.Format("{2} {3}", 0, 1); // $ Alert Sink // GOOD: An array has been supplied. String.Format("{0} {1} {2}", args); @@ -19,16 +19,16 @@ void TestFormatMissingArgument() // GOOD: All arguments supplied to params String.Format("{0} {1} {2} {3}", 0, 1, 2, 3); - helper("{1}"); + helper("{1}"); // $ Source // BAD: Missing {0} - Console.WriteLine("{0}"); + Console.WriteLine("{0}"); // $ Alert Sink } void helper(string format) { // BAD: Missing {1} - String.Format(format, 0); + String.Format(format, 0); // $ Alert Sink } object[] args; diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentBad.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentBad.cs index a66eea4cf323..a3614a881b9a 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentBad.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentBad.cs @@ -4,7 +4,7 @@ class Bad3 { void Hello(string first, string last) { - Console.WriteLine("Hello {0} {1}", first); - Console.WriteLine("Hello {1} {2}", first, last); + Console.WriteLine("Hello {0} {1}", first); // $ Alert Sink + Console.WriteLine("Hello {1} {2}", first, last); // $ Alert Sink } } diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs index 81842d1e19de..61f691840870 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs @@ -8,22 +8,22 @@ void FormatTests() String.Format("{0} {1} {2}", 0, 1, 2); // BAD: Missing arg {0} - String.Format("X", 1); + String.Format("X", 1); // $ Alert Sink // BAD: Missing {1} - String.Format("{0}", 1, 2); + String.Format("{0}", 1, 2); // $ Alert Sink // BAD: Missing {1} - String.Format("{0} {0}", 1, 2); + String.Format("{0} {0}", 1, 2); // $ Alert Sink // BAD: Missing {0} - String.Format("{1} {1}", 1, 2); + String.Format("{1} {1}", 1, 2); // $ Alert Sink // BAD: Missing {0}, {1} and {2} - String.Format("abcdefg", 0, 1, 2); + String.Format("abcdefg", 0, 1, 2); // $ Alert Sink // BAD: {0} is unused - String.Format("{{sdc}}", 0); + String.Format("{{sdc}}", 0); // $ Alert Sink // GOOD: {0} is used String.Format("{{{0:D}}}", 0); @@ -35,7 +35,7 @@ void FormatTests() String.Format("{0} {1} {2}", ps); // BAD: Would display "{0}" - String.Format("{{0}}", 1); + String.Format("{{0}}", 1); // $ Alert Sink // GOOD: Ignore the empty string as it's often used as the default value // of GetResource(). diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgumentBad.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgumentBad.cs index 25bce1a742e9..5a951efa4320 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgumentBad.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgumentBad.cs @@ -4,8 +4,8 @@ class Bad2 { void M(Exception ex) { - Console.WriteLine("Error processing file: {0}", ex, ex.HResult); - Console.WriteLine("Error processing file: {1} ({1})", ex, ex.HResult); - Console.WriteLine("Error processing file: %s (%d)", ex, ex.HResult); + Console.WriteLine("Error processing file: {0}", ex, ex.HResult); // $ Alert Sink + Console.WriteLine("Error processing file: {1} ({1})", ex, ex.HResult); // $ Alert Sink + Console.WriteLine("Error processing file: %s (%d)", ex, ex.HResult); // $ Alert Sink } } From 8c5ab8a6ec79fe8b2821991a023bcaa1de4e7ae7 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 4 Apr 2025 12:59:17 +0200 Subject: [PATCH 03/21] C#: Re-factor FormatMethod. --- .../semmle/code/csharp/frameworks/Format.qll | 122 +++++++++++------- 1 file changed, 73 insertions(+), 49 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index f54476b9e4fc..4fd273014eb8 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -8,67 +8,91 @@ private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.Text /** A method that formats a string, for example `string.Format()`. */ -class FormatMethod extends Method { - FormatMethod() { - exists(Class declType | declType = this.getDeclaringType() | +abstract class FormatMethod extends Method { + /** + * Gets the argument containing the format string. For example, the argument of + * `string.Format(IFormatProvider, String, Object)` is `1`. + */ + abstract int getFormatArgument(); +} + +private class StringAndStringBuilderFormatMethods extends FormatMethod { + StringAndStringBuilderFormatMethods() { + ( this.getParameter(0).getType() instanceof SystemIFormatProviderInterface and - this.getParameter(1).getType() instanceof StringType and + this.getParameter(1).getType() instanceof StringType + or + this.getParameter(0).getType() instanceof StringType + ) and + ( + this = any(SystemStringClass c).getFormatMethod() + or + this = any(SystemTextStringBuilderClass c).getAppendFormatMethod() + ) + } + + override int getFormatArgument() { + if this.getParameter(0).getType() instanceof SystemIFormatProviderInterface + then result = 1 + else result = 0 + } +} + +private class SystemConsoleAndSystemIoTextWriterFormatMethods extends FormatMethod { + SystemConsoleAndSystemIoTextWriterFormatMethods() { + this.getParameter(0).getType() instanceof StringType and + exists(Class declType | declType = this.getDeclaringType() | + this.hasName(["Write", "WriteLine"]) and ( - this = any(SystemStringClass c).getFormatMethod() + declType.hasFullyQualifiedName("System", "Console") or - this = any(SystemTextStringBuilderClass c).getAppendFormatMethod() + declType.hasFullyQualifiedName("System.IO", "TextWriter") ) - or - this.getParameter(0).getType() instanceof StringType and + ) + } + + override int getFormatArgument() { result = 0 } +} + +private class SystemDiagnosticsDebugAssert extends FormatMethod { + SystemDiagnosticsDebugAssert() { + this.hasName("Assert") and + this.getDeclaringType().hasFullyQualifiedName("System.Diagnostics", "Debug") and + this.getNumberOfParameters() = 4 + } + + override int getFormatArgument() { result = 2 } +} + +private class SystemDiagnosticsFormatMethods extends FormatMethod { + SystemDiagnosticsFormatMethods() { + this.getParameter(0).getType() instanceof StringType and + exists(Class declType | + declType = this.getDeclaringType() and + declType.getNamespace().getFullName() = "System.Diagnostics" + | + declType.hasName("Trace") and ( - this = any(SystemStringClass c).getFormatMethod() - or - this = any(SystemTextStringBuilderClass c).getAppendFormatMethod() - or - (this.hasName("Write") or this.hasName("WriteLine")) and - ( - declType.hasFullyQualifiedName("System", "Console") - or - declType.hasFullyQualifiedName("System.IO", "TextWriter") - or - declType.hasFullyQualifiedName("System.Diagnostics", "Debug") and - this.getParameter(1).getType() instanceof ArrayType - ) + this.hasName("TraceError") or - declType.hasFullyQualifiedName("System.Diagnostics", "Trace") and - ( - this.hasName("TraceError") or - this.hasName("TraceInformation") or - this.hasName("TraceWarning") - ) + this.hasName("TraceInformation") or - this.hasName("TraceInformation") and - declType.hasFullyQualifiedName("System.Diagnostics", "TraceSource") - or - this.hasName("Print") and - declType.hasFullyQualifiedName("System.Diagnostics", "Debug") + this.hasName("TraceWarning") ) or - this.hasName("Assert") and - declType.hasFullyQualifiedName("System.Diagnostics", "Debug") and - this.getNumberOfParameters() = 4 + declType.hasName("TraceSource") and this.hasName("TraceInformation") + or + declType.hasName("Debug") and + ( + this.hasName("Print") + or + this.hasName(["Write", "WriteLine"]) and + this.getParameter(1).getType() instanceof ArrayType + ) ) } - /** - * Gets the argument containing the format string. For example, the argument of - * `string.Format(IFormatProvider, String, Object)` is `1`. - */ - int getFormatArgument() { - if this.getParameter(0).getType() instanceof SystemIFormatProviderInterface - then result = 1 - else - if - this.hasName("Assert") and - this.getDeclaringType().hasFullyQualifiedName("System.Diagnostics", "Debug") - then result = 2 - else result = 0 - } + override int getFormatArgument() { result = 0 } } pragma[nomagic] From 29e1c9739351a61fb1869529033f8d0991bece2b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 4 Apr 2025 15:48:43 +0200 Subject: [PATCH 04/21] C#: Add more format testcases. --- .../API Abuse/FormatInvalid/FormatInvalid.cs | 15 ++ .../FormatInvalid/FormatInvalid.expected | 158 ++++++++++++------ 2 files changed, 119 insertions(+), 54 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs index d65870f3a32d..4072dfbd6881 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs @@ -72,6 +72,7 @@ void FormatMethodTests() Format("}", 0); // BAD: All of these are format methods with an invalid string. + String.Format("}"); // $ Alert String.Format("}", 0); // $ Alert String.Format("}", ps); // $ Alert String.Format(fp, "}", ps); // $ Alert @@ -79,6 +80,7 @@ void FormatMethodTests() String.Format("}", 0, 1, 2); // $ Alert String.Format("}", 0, 1, 2, 3); // $ Alert + sb.AppendFormat("}"); // $ Alert sb.AppendFormat("}", 0); // $ Alert sb.AppendFormat("}", ps); // $ Alert sb.AppendFormat(fp, "}", ps); // $ Alert @@ -117,6 +119,19 @@ void FormatMethodTests() System.Diagnostics.Debug.Print("}", ps); // $ Alert Console.WriteLine("}"); // GOOD + + // The Following methods are not recognised as format methods. + Console.WriteLine("{0}"); // GOOD + Console.Write("{0}"); // GOOD + tw.WriteLine("{0}"); // GOOD + tw.Write("{0}"); // GOOD + System.Diagnostics.Debug.Print("{0}"); // GOOD + System.Diagnostics.Debug.WriteLine("{0}"); // GOOD + System.Diagnostics.Debug.Write("{0}"); // GOOD + System.Diagnostics.Trace.TraceError("{0}"); // GOOD + System.Diagnostics.Trace.TraceInformation("{0}"); // GOOD + System.Diagnostics.Trace.TraceWarning("{0}"); // GOOD + ts.TraceInformation("{0}"); // GOOD } System.IO.StringWriter sw; diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index b23ee42559b9..4a7730a26e8f 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -7,40 +7,49 @@ | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this | FormatInvalid.cs:42:9:42:35 | call to method Format | this | | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this | FormatInvalid.cs:45:9:45:36 | call to method Format | this | | FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:32 | call to method Format | this | FormatInvalid.cs:51:9:51:32 | call to method Format | this | -| FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:29 | call to method Format | this | FormatInvalid.cs:75:9:75:29 | call to method Format | this | -| FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:30 | call to method Format | this | FormatInvalid.cs:76:9:76:30 | call to method Format | this | -| FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:34 | call to method Format | this | FormatInvalid.cs:77:9:77:34 | call to method Format | this | -| FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:32 | call to method Format | this | FormatInvalid.cs:78:9:78:32 | call to method Format | this | -| FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:35 | call to method Format | this | FormatInvalid.cs:79:9:79:35 | call to method Format | this | -| FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:38 | call to method Format | this | FormatInvalid.cs:80:9:80:38 | call to method Format | this | -| FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | -| FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | -| FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | -| FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | -| FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | -| FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | -| FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | -| FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | -| FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | -| FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | -| FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | -| FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | -| FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | -| FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | -| FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | -| FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | -| FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | -| FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | -| FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | -| FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | -| FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | -| FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:29 | call to method Write | this | FormatInvalid.cs:107:9:107:29 | call to method Write | this | -| FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:32 | call to method Write | this | FormatInvalid.cs:108:9:108:32 | call to method Write | this | -| FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:35 | call to method Write | this | FormatInvalid.cs:109:9:109:35 | call to method Write | this | -| FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:38 | call to method Write | this | FormatInvalid.cs:110:9:110:38 | call to method Write | this | -| FormatInvalid.cs:115:56:115:58 | "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | -| FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:116:9:116:24 | call to method Write | this | FormatInvalid.cs:116:9:116:24 | call to method Write | this | -| FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:47 | call to method Print | this | FormatInvalid.cs:117:9:117:47 | call to method Print | this | +| FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:29 | call to method Format | this | FormatInvalid.cs:76:9:76:29 | call to method Format | this | +| FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:30 | call to method Format | this | FormatInvalid.cs:77:9:77:30 | call to method Format | this | +| FormatInvalid.cs:78:27:78:29 | "}" | FormatInvalid.cs:78:27:78:29 | "}" | FormatInvalid.cs:78:27:78:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:34 | call to method Format | this | FormatInvalid.cs:78:9:78:34 | call to method Format | this | +| FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:32 | call to method Format | this | FormatInvalid.cs:79:9:79:32 | call to method Format | this | +| FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:35 | call to method Format | this | FormatInvalid.cs:80:9:80:35 | call to method Format | this | +| FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:81:9:81:38 | call to method Format | this | FormatInvalid.cs:81:9:81:38 | call to method Format | this | +| FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:31 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:31 | call to method AppendFormat | this | +| FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:32 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:32 | call to method AppendFormat | this | +| FormatInvalid.cs:86:29:86:31 | "}" | FormatInvalid.cs:86:29:86:31 | "}" | FormatInvalid.cs:86:29:86:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:36 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:36 | call to method AppendFormat | this | +| FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:34 | call to method AppendFormat | this | FormatInvalid.cs:87:9:87:34 | call to method AppendFormat | this | +| FormatInvalid.cs:88:25:88:27 | "}" | FormatInvalid.cs:88:25:88:27 | "}" | FormatInvalid.cs:88:25:88:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:88:9:88:37 | call to method AppendFormat | this | FormatInvalid.cs:88:9:88:37 | call to method AppendFormat | this | +| FormatInvalid.cs:89:25:89:27 | "}" | FormatInvalid.cs:89:25:89:27 | "}" | FormatInvalid.cs:89:25:89:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:40 | call to method AppendFormat | this | FormatInvalid.cs:89:9:89:40 | call to method AppendFormat | this | +| FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:33 | call to method WriteLine | this | FormatInvalid.cs:91:9:91:33 | call to method WriteLine | this | +| FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:34 | call to method WriteLine | this | FormatInvalid.cs:92:9:92:34 | call to method WriteLine | this | +| FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:36 | call to method WriteLine | this | FormatInvalid.cs:93:9:93:36 | call to method WriteLine | this | +| FormatInvalid.cs:94:27:94:29 | "}" | FormatInvalid.cs:94:27:94:29 | "}" | FormatInvalid.cs:94:27:94:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:94:9:94:39 | call to method WriteLine | this | FormatInvalid.cs:94:9:94:39 | call to method WriteLine | this | +| FormatInvalid.cs:95:27:95:29 | "}" | FormatInvalid.cs:95:27:95:29 | "}" | FormatInvalid.cs:95:27:95:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:42 | call to method WriteLine | this | FormatInvalid.cs:95:9:95:42 | call to method WriteLine | this | +| FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:28 | call to method WriteLine | this | FormatInvalid.cs:97:9:97:28 | call to method WriteLine | this | +| FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:29 | call to method WriteLine | this | FormatInvalid.cs:98:9:98:29 | call to method WriteLine | this | +| FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:31 | call to method WriteLine | this | FormatInvalid.cs:99:9:99:31 | call to method WriteLine | this | +| FormatInvalid.cs:100:22:100:24 | "}" | FormatInvalid.cs:100:22:100:24 | "}" | FormatInvalid.cs:100:22:100:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:100:9:100:34 | call to method WriteLine | this | FormatInvalid.cs:100:9:100:34 | call to method WriteLine | this | +| FormatInvalid.cs:101:22:101:24 | "}" | FormatInvalid.cs:101:22:101:24 | "}" | FormatInvalid.cs:101:22:101:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:37 | call to method WriteLine | this | FormatInvalid.cs:101:9:101:37 | call to method WriteLine | this | +| FormatInvalid.cs:103:44:103:46 | "}" | FormatInvalid.cs:103:44:103:46 | "}" | FormatInvalid.cs:103:44:103:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:51 | call to method WriteLine | this | FormatInvalid.cs:103:9:103:51 | call to method WriteLine | this | +| FormatInvalid.cs:104:45:104:47 | "}" | FormatInvalid.cs:104:45:104:47 | "}" | FormatInvalid.cs:104:45:104:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:51 | call to method TraceError | this | FormatInvalid.cs:104:9:104:51 | call to method TraceError | this | +| FormatInvalid.cs:105:51:105:53 | "}" | FormatInvalid.cs:105:51:105:53 | "}" | FormatInvalid.cs:105:51:105:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:57 | call to method TraceInformation | this | FormatInvalid.cs:105:9:105:57 | call to method TraceInformation | this | +| FormatInvalid.cs:106:47:106:49 | "}" | FormatInvalid.cs:106:47:106:49 | "}" | FormatInvalid.cs:106:47:106:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:106:9:106:53 | call to method TraceWarning | this | FormatInvalid.cs:106:9:106:53 | call to method TraceWarning | this | +| FormatInvalid.cs:107:29:107:31 | "}" | FormatInvalid.cs:107:29:107:31 | "}" | FormatInvalid.cs:107:29:107:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:35 | call to method TraceInformation | this | FormatInvalid.cs:107:9:107:35 | call to method TraceInformation | this | +| FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:29 | call to method Write | this | FormatInvalid.cs:109:9:109:29 | call to method Write | this | +| FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:32 | call to method Write | this | FormatInvalid.cs:110:9:110:32 | call to method Write | this | +| FormatInvalid.cs:111:23:111:25 | "}" | FormatInvalid.cs:111:23:111:25 | "}" | FormatInvalid.cs:111:23:111:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:111:9:111:35 | call to method Write | this | FormatInvalid.cs:111:9:111:35 | call to method Write | this | +| FormatInvalid.cs:112:23:112:25 | "}" | FormatInvalid.cs:112:23:112:25 | "}" | FormatInvalid.cs:112:23:112:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:112:9:112:38 | call to method Write | this | FormatInvalid.cs:112:9:112:38 | call to method Write | this | +| FormatInvalid.cs:117:56:117:58 | "}" | FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:63 | call to method Assert | this | FormatInvalid.cs:117:9:117:63 | call to method Assert | this | +| FormatInvalid.cs:118:18:118:20 | "}" | FormatInvalid.cs:118:18:118:20 | "}" | FormatInvalid.cs:118:18:118:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:118:9:118:24 | call to method Write | this | FormatInvalid.cs:118:9:118:24 | call to method Write | this | +| FormatInvalid.cs:119:40:119:42 | "}" | FormatInvalid.cs:119:40:119:42 | "}" | FormatInvalid.cs:119:40:119:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:119:9:119:47 | call to method Print | this | FormatInvalid.cs:119:9:119:47 | call to method Print | this | +| FormatInvalid.cs:124:9:124:32 | call to method WriteLine | FormatInvalid.cs:124:27:124:31 | "{0}" | FormatInvalid.cs:124:27:124:31 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:124:27:124:31 | "{0}" | this | FormatInvalid.cs:124:27:124:31 | "{0}" | this | +| FormatInvalid.cs:125:9:125:28 | call to method Write | FormatInvalid.cs:125:23:125:27 | "{0}" | FormatInvalid.cs:125:23:125:27 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:125:23:125:27 | "{0}" | this | FormatInvalid.cs:125:23:125:27 | "{0}" | this | +| FormatInvalid.cs:126:9:126:27 | call to method WriteLine | FormatInvalid.cs:126:22:126:26 | "{0}" | FormatInvalid.cs:126:22:126:26 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:126:22:126:26 | "{0}" | this | FormatInvalid.cs:126:22:126:26 | "{0}" | this | +| FormatInvalid.cs:127:9:127:23 | call to method Write | FormatInvalid.cs:127:18:127:22 | "{0}" | FormatInvalid.cs:127:18:127:22 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:127:18:127:22 | "{0}" | this | FormatInvalid.cs:127:18:127:22 | "{0}" | this | +| FormatInvalid.cs:128:9:128:45 | call to method Print | FormatInvalid.cs:128:40:128:44 | "{0}" | FormatInvalid.cs:128:40:128:44 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:128:40:128:44 | "{0}" | this | FormatInvalid.cs:128:40:128:44 | "{0}" | this | +| FormatInvalid.cs:131:9:131:50 | call to method TraceError | FormatInvalid.cs:131:45:131:49 | "{0}" | FormatInvalid.cs:131:45:131:49 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:131:45:131:49 | "{0}" | this | FormatInvalid.cs:131:45:131:49 | "{0}" | this | +| FormatInvalid.cs:132:9:132:56 | call to method TraceInformation | FormatInvalid.cs:132:51:132:55 | "{0}" | FormatInvalid.cs:132:51:132:55 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:132:51:132:55 | "{0}" | this | FormatInvalid.cs:132:51:132:55 | "{0}" | this | +| FormatInvalid.cs:133:9:133:52 | call to method TraceWarning | FormatInvalid.cs:133:47:133:51 | "{0}" | FormatInvalid.cs:133:47:133:51 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:133:47:133:51 | "{0}" | this | FormatInvalid.cs:133:47:133:51 | "{0}" | this | +| FormatInvalid.cs:134:9:134:34 | call to method TraceInformation | FormatInvalid.cs:134:29:134:33 | "{0}" | FormatInvalid.cs:134:29:134:33 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:134:29:134:33 | "{0}" | this | FormatInvalid.cs:134:29:134:33 | "{0}" | this | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | | FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | | FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | format string | FormatMissingArgument.cs:11:30:11:30 | (...) ... | this supplied value | @@ -91,39 +100,50 @@ nodes | FormatInvalid.cs:58:23:58:33 | "{0}{{{{}}" | semmle.label | "{0}{{{{}}" | | FormatInvalid.cs:75:23:75:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:76:23:76:25 | "}" | semmle.label | "}" | -| FormatInvalid.cs:77:27:77:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:78:23:78:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:77:23:77:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:78:27:78:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:79:23:79:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:80:23:80:25 | "}" | semmle.label | "}" | -| FormatInvalid.cs:82:25:82:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:81:23:81:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:83:25:83:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:84:29:84:31 | "}" | semmle.label | "}" | +| FormatInvalid.cs:84:25:84:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:85:25:85:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:86:25:86:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:86:29:86:31 | "}" | semmle.label | "}" | | FormatInvalid.cs:87:25:87:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:89:27:89:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:90:27:90:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:88:25:88:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:89:25:89:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:91:27:91:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:92:27:92:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:93:27:93:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:95:22:95:24 | "}" | semmle.label | "}" | -| FormatInvalid.cs:96:22:96:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:94:27:94:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:95:27:95:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:97:22:97:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:98:22:98:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:99:22:99:24 | "}" | semmle.label | "}" | -| FormatInvalid.cs:101:44:101:46 | "}" | semmle.label | "}" | -| FormatInvalid.cs:102:45:102:47 | "}" | semmle.label | "}" | -| FormatInvalid.cs:103:51:103:53 | "}" | semmle.label | "}" | -| FormatInvalid.cs:104:47:104:49 | "}" | semmle.label | "}" | -| FormatInvalid.cs:105:29:105:31 | "}" | semmle.label | "}" | -| FormatInvalid.cs:107:23:107:25 | "}" | semmle.label | "}" | -| FormatInvalid.cs:108:23:108:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:100:22:100:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:101:22:101:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:103:44:103:46 | "}" | semmle.label | "}" | +| FormatInvalid.cs:104:45:104:47 | "}" | semmle.label | "}" | +| FormatInvalid.cs:105:51:105:53 | "}" | semmle.label | "}" | +| FormatInvalid.cs:106:47:106:49 | "}" | semmle.label | "}" | +| FormatInvalid.cs:107:29:107:31 | "}" | semmle.label | "}" | | FormatInvalid.cs:109:23:109:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:110:23:110:25 | "}" | semmle.label | "}" | -| FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | -| FormatInvalid.cs:116:18:116:20 | "}" | semmle.label | "}" | -| FormatInvalid.cs:117:40:117:42 | "}" | semmle.label | "}" | -| FormatInvalid.cs:119:27:119:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:111:23:111:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:112:23:112:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | +| FormatInvalid.cs:118:18:118:20 | "}" | semmle.label | "}" | +| FormatInvalid.cs:119:40:119:42 | "}" | semmle.label | "}" | +| FormatInvalid.cs:121:27:121:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:124:27:124:31 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:125:23:125:27 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:126:22:126:26 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:127:18:127:22 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:128:40:128:44 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:131:45:131:49 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:132:51:132:55 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:133:47:133:51 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:134:29:134:33 | "{0}" | semmle.label | "{0}" | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | semmle.label | "class {0} { }" | | FormatInvalidGood.cs:7:30:7:46 | "class {0} {{ }}" | semmle.label | "class {0} {{ }}" | | FormatMissingArgument.cs:8:23:8:27 | "{0}" | semmle.label | "{0}" | @@ -154,3 +174,33 @@ nodes | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | subpaths +testFailures +| FormatInvalid.cs:75:29:75:38 | // ... | Missing result: Alert | +| FormatInvalid.cs:83:31:83:40 | // ... | Missing result: Alert | +| FormatInvalid.cs:124:9:124:32 | FormatInvalid.cs:124:27:124:31 | Unexpected result: Alert | +| FormatInvalid.cs:124:27:124:31 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:124:27:124:31 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:125:9:125:28 | FormatInvalid.cs:125:23:125:27 | Unexpected result: Alert | +| FormatInvalid.cs:125:23:125:27 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:125:23:125:27 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:126:9:126:27 | FormatInvalid.cs:126:22:126:26 | Unexpected result: Alert | +| FormatInvalid.cs:126:22:126:26 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:126:22:126:26 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:127:9:127:23 | FormatInvalid.cs:127:18:127:22 | Unexpected result: Alert | +| FormatInvalid.cs:127:18:127:22 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:127:18:127:22 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:128:9:128:45 | FormatInvalid.cs:128:40:128:44 | Unexpected result: Alert | +| FormatInvalid.cs:128:40:128:44 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:128:40:128:44 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:131:9:131:50 | FormatInvalid.cs:131:45:131:49 | Unexpected result: Alert | +| FormatInvalid.cs:131:45:131:49 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:131:45:131:49 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:132:9:132:56 | FormatInvalid.cs:132:51:132:55 | Unexpected result: Alert | +| FormatInvalid.cs:132:51:132:55 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:132:51:132:55 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:133:9:133:52 | FormatInvalid.cs:133:47:133:51 | Unexpected result: Alert | +| FormatInvalid.cs:133:47:133:51 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:133:47:133:51 | "{0}" | Unexpected result: Sink | +| FormatInvalid.cs:134:9:134:34 | FormatInvalid.cs:134:29:134:33 | Unexpected result: Alert | +| FormatInvalid.cs:134:29:134:33 | "{0}" | Unexpected result: Alert | +| FormatInvalid.cs:134:29:134:33 | "{0}" | Unexpected result: Sink | From 3f6fd7ee3170226aaf86ec2c89e703f1866c63a5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 4 Apr 2025 15:53:38 +0200 Subject: [PATCH 05/21] C#: Remove false positive example. --- .../API Abuse/FormatInvalid/FormatInvalid.expected | 14 ++++++-------- .../FormatInvalid/FormatMissingArgument.cs | 3 --- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index 4a7730a26e8f..57523031ece4 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -57,9 +57,8 @@ | FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | | FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:34:14:34 | (...) ... | this supplied value | | FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:37:14:37 | (...) ... | this supplied value | -| FormatMissingArgument.cs:25:9:25:32 | call to method WriteLine | FormatMissingArgument.cs:25:27:25:31 | "{0}" | FormatMissingArgument.cs:25:27:25:31 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | -| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | -| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | format string | FormatMissingArgument.cs:31:31:31:31 | (...) ... | this supplied value | +| FormatMissingArgument.cs:28:9:28:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | +| FormatMissingArgument.cs:28:9:28:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | format string | FormatMissingArgument.cs:28:31:28:31 | (...) ... | this supplied value | | FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | The $@ ignores $@. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | format string | FormatMissingArgumentBad.cs:8:44:8:48 | access to parameter first | this supplied value | @@ -77,8 +76,8 @@ | FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value | | FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value | edges -| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:24:28:29 | format : String | provenance | | -| FormatMissingArgument.cs:28:24:28:29 | format : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | provenance | | +| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:25:24:25:29 | format : String | provenance | | +| FormatMissingArgument.cs:25:24:25:29 | format : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | provenance | | nodes | FormatInvalid.cs:9:23:9:27 | "{0}" | semmle.label | "{0}" | | FormatInvalid.cs:12:23:12:29 | "{0,1}" | semmle.label | "{0,1}" | @@ -152,9 +151,8 @@ nodes | FormatMissingArgument.cs:17:23:17:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | | FormatMissingArgument.cs:20:23:20:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | semmle.label | "{1}" : String | -| FormatMissingArgument.cs:25:27:25:31 | "{0}" | semmle.label | "{0}" | -| FormatMissingArgument.cs:28:24:28:29 | format : String | semmle.label | format : String | -| FormatMissingArgument.cs:31:23:31:28 | access to parameter format | semmle.label | access to parameter format | +| FormatMissingArgument.cs:25:24:25:29 | format : String | semmle.label | format : String | +| FormatMissingArgument.cs:28:23:28:28 | access to parameter format | semmle.label | access to parameter format | | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" | | FormatMissingArgumentGood.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs index fa046a6fc7c6..fabe7b239e4a 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs @@ -20,9 +20,6 @@ void TestFormatMissingArgument() String.Format("{0} {1} {2} {3}", 0, 1, 2, 3); helper("{1}"); // $ Source - - // BAD: Missing {0} - Console.WriteLine("{0}"); // $ Alert Sink } void helper(string format) From 7095cca91d015450afc96678443349c9dadea10f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 4 Apr 2025 15:55:49 +0200 Subject: [PATCH 06/21] C#: Remove some false positives and add more true positives for cs/invalid-string-format. --- csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll | 2 ++ csharp/ql/src/API Abuse/FormatInvalid.ql | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index 4fd273014eb8..db1d4e42d74a 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -41,6 +41,7 @@ private class StringAndStringBuilderFormatMethods extends FormatMethod { private class SystemConsoleAndSystemIoTextWriterFormatMethods extends FormatMethod { SystemConsoleAndSystemIoTextWriterFormatMethods() { this.getParameter(0).getType() instanceof StringType and + this.getNumberOfParameters() > 1 and exists(Class declType | declType = this.getDeclaringType() | this.hasName(["Write", "WriteLine"]) and ( @@ -67,6 +68,7 @@ private class SystemDiagnosticsDebugAssert extends FormatMethod { private class SystemDiagnosticsFormatMethods extends FormatMethod { SystemDiagnosticsFormatMethods() { this.getParameter(0).getType() instanceof StringType and + this.getNumberOfParameters() > 1 and exists(Class declType | declType = this.getDeclaringType() and declType.getNamespace().getFullName() = "System.Diagnostics" diff --git a/csharp/ql/src/API Abuse/FormatInvalid.ql b/csharp/ql/src/API Abuse/FormatInvalid.ql index 235daa1ecc25..17923d5bc355 100644 --- a/csharp/ql/src/API Abuse/FormatInvalid.ql +++ b/csharp/ql/src/API Abuse/FormatInvalid.ql @@ -29,7 +29,6 @@ private predicate invalidFormatString( source.getNode().asExpr() = src and sink.getNode().asExpr() = call.getFormatExpr() and FormatInvalid::flowPath(source, sink) and - call.hasInsertions() and msg = "Invalid format string used in $@ formatting call." and callString = "this" } From c0253342d4a38ff2c1841b32d5a0a028fc5ef52f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 4 Apr 2025 15:57:00 +0200 Subject: [PATCH 07/21] C#: Update test expected output. --- .../FormatInvalid/FormatInvalid.expected | 51 +------------------ 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index 57523031ece4..798102dc350d 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -7,12 +7,14 @@ | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this | FormatInvalid.cs:42:9:42:35 | call to method Format | this | | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this | FormatInvalid.cs:45:9:45:36 | call to method Format | this | | FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:32 | call to method Format | this | FormatInvalid.cs:51:9:51:32 | call to method Format | this | +| FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:26 | call to method Format | this | FormatInvalid.cs:75:9:75:26 | call to method Format | this | | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:29 | call to method Format | this | FormatInvalid.cs:76:9:76:29 | call to method Format | this | | FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:30 | call to method Format | this | FormatInvalid.cs:77:9:77:30 | call to method Format | this | | FormatInvalid.cs:78:27:78:29 | "}" | FormatInvalid.cs:78:27:78:29 | "}" | FormatInvalid.cs:78:27:78:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:34 | call to method Format | this | FormatInvalid.cs:78:9:78:34 | call to method Format | this | | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:32 | call to method Format | this | FormatInvalid.cs:79:9:79:32 | call to method Format | this | | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:35 | call to method Format | this | FormatInvalid.cs:80:9:80:35 | call to method Format | this | | FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:81:9:81:38 | call to method Format | this | FormatInvalid.cs:81:9:81:38 | call to method Format | this | +| FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:28 | call to method AppendFormat | this | FormatInvalid.cs:83:9:83:28 | call to method AppendFormat | this | | FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:31 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:31 | call to method AppendFormat | this | | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:32 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:32 | call to method AppendFormat | this | | FormatInvalid.cs:86:29:86:31 | "}" | FormatInvalid.cs:86:29:86:31 | "}" | FormatInvalid.cs:86:29:86:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:36 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:36 | call to method AppendFormat | this | @@ -41,15 +43,6 @@ | FormatInvalid.cs:117:56:117:58 | "}" | FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:63 | call to method Assert | this | FormatInvalid.cs:117:9:117:63 | call to method Assert | this | | FormatInvalid.cs:118:18:118:20 | "}" | FormatInvalid.cs:118:18:118:20 | "}" | FormatInvalid.cs:118:18:118:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:118:9:118:24 | call to method Write | this | FormatInvalid.cs:118:9:118:24 | call to method Write | this | | FormatInvalid.cs:119:40:119:42 | "}" | FormatInvalid.cs:119:40:119:42 | "}" | FormatInvalid.cs:119:40:119:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:119:9:119:47 | call to method Print | this | FormatInvalid.cs:119:9:119:47 | call to method Print | this | -| FormatInvalid.cs:124:9:124:32 | call to method WriteLine | FormatInvalid.cs:124:27:124:31 | "{0}" | FormatInvalid.cs:124:27:124:31 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:124:27:124:31 | "{0}" | this | FormatInvalid.cs:124:27:124:31 | "{0}" | this | -| FormatInvalid.cs:125:9:125:28 | call to method Write | FormatInvalid.cs:125:23:125:27 | "{0}" | FormatInvalid.cs:125:23:125:27 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:125:23:125:27 | "{0}" | this | FormatInvalid.cs:125:23:125:27 | "{0}" | this | -| FormatInvalid.cs:126:9:126:27 | call to method WriteLine | FormatInvalid.cs:126:22:126:26 | "{0}" | FormatInvalid.cs:126:22:126:26 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:126:22:126:26 | "{0}" | this | FormatInvalid.cs:126:22:126:26 | "{0}" | this | -| FormatInvalid.cs:127:9:127:23 | call to method Write | FormatInvalid.cs:127:18:127:22 | "{0}" | FormatInvalid.cs:127:18:127:22 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:127:18:127:22 | "{0}" | this | FormatInvalid.cs:127:18:127:22 | "{0}" | this | -| FormatInvalid.cs:128:9:128:45 | call to method Print | FormatInvalid.cs:128:40:128:44 | "{0}" | FormatInvalid.cs:128:40:128:44 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:128:40:128:44 | "{0}" | this | FormatInvalid.cs:128:40:128:44 | "{0}" | this | -| FormatInvalid.cs:131:9:131:50 | call to method TraceError | FormatInvalid.cs:131:45:131:49 | "{0}" | FormatInvalid.cs:131:45:131:49 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:131:45:131:49 | "{0}" | this | FormatInvalid.cs:131:45:131:49 | "{0}" | this | -| FormatInvalid.cs:132:9:132:56 | call to method TraceInformation | FormatInvalid.cs:132:51:132:55 | "{0}" | FormatInvalid.cs:132:51:132:55 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:132:51:132:55 | "{0}" | this | FormatInvalid.cs:132:51:132:55 | "{0}" | this | -| FormatInvalid.cs:133:9:133:52 | call to method TraceWarning | FormatInvalid.cs:133:47:133:51 | "{0}" | FormatInvalid.cs:133:47:133:51 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:133:47:133:51 | "{0}" | this | FormatInvalid.cs:133:47:133:51 | "{0}" | this | -| FormatInvalid.cs:134:9:134:34 | call to method TraceInformation | FormatInvalid.cs:134:29:134:33 | "{0}" | FormatInvalid.cs:134:29:134:33 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatInvalid.cs:134:29:134:33 | "{0}" | this | FormatInvalid.cs:134:29:134:33 | "{0}" | this | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | | FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | | FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | format string | FormatMissingArgument.cs:11:30:11:30 | (...) ... | this supplied value | @@ -133,16 +126,6 @@ nodes | FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | | FormatInvalid.cs:118:18:118:20 | "}" | semmle.label | "}" | | FormatInvalid.cs:119:40:119:42 | "}" | semmle.label | "}" | -| FormatInvalid.cs:121:27:121:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:124:27:124:31 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:125:23:125:27 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:126:22:126:26 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:127:18:127:22 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:128:40:128:44 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:131:45:131:49 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:132:51:132:55 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:133:47:133:51 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:134:29:134:33 | "{0}" | semmle.label | "{0}" | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | semmle.label | "class {0} { }" | | FormatInvalidGood.cs:7:30:7:46 | "class {0} {{ }}" | semmle.label | "class {0} {{ }}" | | FormatMissingArgument.cs:8:23:8:27 | "{0}" | semmle.label | "{0}" | @@ -172,33 +155,3 @@ nodes | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | subpaths -testFailures -| FormatInvalid.cs:75:29:75:38 | // ... | Missing result: Alert | -| FormatInvalid.cs:83:31:83:40 | // ... | Missing result: Alert | -| FormatInvalid.cs:124:9:124:32 | FormatInvalid.cs:124:27:124:31 | Unexpected result: Alert | -| FormatInvalid.cs:124:27:124:31 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:124:27:124:31 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:125:9:125:28 | FormatInvalid.cs:125:23:125:27 | Unexpected result: Alert | -| FormatInvalid.cs:125:23:125:27 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:125:23:125:27 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:126:9:126:27 | FormatInvalid.cs:126:22:126:26 | Unexpected result: Alert | -| FormatInvalid.cs:126:22:126:26 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:126:22:126:26 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:127:9:127:23 | FormatInvalid.cs:127:18:127:22 | Unexpected result: Alert | -| FormatInvalid.cs:127:18:127:22 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:127:18:127:22 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:128:9:128:45 | FormatInvalid.cs:128:40:128:44 | Unexpected result: Alert | -| FormatInvalid.cs:128:40:128:44 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:128:40:128:44 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:131:9:131:50 | FormatInvalid.cs:131:45:131:49 | Unexpected result: Alert | -| FormatInvalid.cs:131:45:131:49 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:131:45:131:49 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:132:9:132:56 | FormatInvalid.cs:132:51:132:55 | Unexpected result: Alert | -| FormatInvalid.cs:132:51:132:55 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:132:51:132:55 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:133:9:133:52 | FormatInvalid.cs:133:47:133:51 | Unexpected result: Alert | -| FormatInvalid.cs:133:47:133:51 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:133:47:133:51 | "{0}" | Unexpected result: Sink | -| FormatInvalid.cs:134:9:134:34 | FormatInvalid.cs:134:29:134:33 | Unexpected result: Alert | -| FormatInvalid.cs:134:29:134:33 | "{0}" | Unexpected result: Alert | -| FormatInvalid.cs:134:29:134:33 | "{0}" | Unexpected result: Sink | From 523fff39dc8d3cabc9820c50436b10b40d04ff81 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 9 Apr 2025 14:41:21 +0200 Subject: [PATCH 08/21] C#: Add more invalid-string-formatting testcases. --- .../API Abuse/FormatInvalid/FormatInvalid.cs | 23 ++ .../FormatInvalid/FormatInvalid.expected | 281 ++++++++++-------- .../FormatInvalid/FormatMissingArgument.cs | 55 ++++ .../FormatInvalid/FormatUnusedArgument.cs | 42 +++ 4 files changed, 283 insertions(+), 118 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs index 4072dfbd6881..2690ec50890a 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Text; class FormatInvalid @@ -134,5 +135,27 @@ void FormatMethodTests() ts.TraceInformation("{0}"); // GOOD } + void CompositeFormatMethods() + { + var format = CompositeFormat.Parse("}"); // $ Alert + + // GOOD: Format is invalid and this flagged during parsing. + String.Format(null, format, ""); + String.Format(null, format, "", ""); + String.Format(null, format, "", "", ""); + + sb.AppendFormat(null, format, ""); + sb.AppendFormat(null, format, ""); + sb.AppendFormat(null, format, "", ""); + sb.AppendFormat(null, format, "", "", ""); + + + var span = new Span(); + span.TryWrite(null, format, out _); + span.TryWrite(null, format, out _, new object()); + span.TryWrite(null, format, out _, new object(), new object()); + span.TryWrite(null, format, out _, "", "", ""); + } + System.IO.StringWriter sw; } diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index 798102dc350d..3d23145b406e 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -1,157 +1,202 @@ #select -| FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:27:9:27:32 | call to method Format | this | FormatInvalid.cs:27:9:27:32 | call to method Format | this | -| FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:30:9:30:35 | call to method Format | this | FormatInvalid.cs:30:9:30:35 | call to method Format | this | -| FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:33:9:33:34 | call to method Format | this | FormatInvalid.cs:33:9:33:34 | call to method Format | this | -| FormatInvalid.cs:36:9:36:30 | call to method Format | FormatInvalid.cs:36:23:36:26 | "%d" | FormatInvalid.cs:36:23:36:26 | "%d" | The $@ ignores $@. | FormatInvalid.cs:36:23:36:26 | "%d" | format string | FormatInvalid.cs:36:29:36:29 | (...) ... | this supplied value | -| FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:39:9:39:40 | call to method Format | this | FormatInvalid.cs:39:9:39:40 | call to method Format | this | -| FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this | FormatInvalid.cs:42:9:42:35 | call to method Format | this | -| FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this | FormatInvalid.cs:45:9:45:36 | call to method Format | this | -| FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | FormatInvalid.cs:51:23:51:28 | "}{0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:32 | call to method Format | this | FormatInvalid.cs:51:9:51:32 | call to method Format | this | -| FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:26 | call to method Format | this | FormatInvalid.cs:75:9:75:26 | call to method Format | this | -| FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:29 | call to method Format | this | FormatInvalid.cs:76:9:76:29 | call to method Format | this | -| FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:30 | call to method Format | this | FormatInvalid.cs:77:9:77:30 | call to method Format | this | -| FormatInvalid.cs:78:27:78:29 | "}" | FormatInvalid.cs:78:27:78:29 | "}" | FormatInvalid.cs:78:27:78:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:34 | call to method Format | this | FormatInvalid.cs:78:9:78:34 | call to method Format | this | -| FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:32 | call to method Format | this | FormatInvalid.cs:79:9:79:32 | call to method Format | this | -| FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:35 | call to method Format | this | FormatInvalid.cs:80:9:80:35 | call to method Format | this | -| FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:81:9:81:38 | call to method Format | this | FormatInvalid.cs:81:9:81:38 | call to method Format | this | -| FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:28 | call to method AppendFormat | this | FormatInvalid.cs:83:9:83:28 | call to method AppendFormat | this | -| FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:31 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:31 | call to method AppendFormat | this | -| FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:32 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:32 | call to method AppendFormat | this | -| FormatInvalid.cs:86:29:86:31 | "}" | FormatInvalid.cs:86:29:86:31 | "}" | FormatInvalid.cs:86:29:86:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:36 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:36 | call to method AppendFormat | this | -| FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:34 | call to method AppendFormat | this | FormatInvalid.cs:87:9:87:34 | call to method AppendFormat | this | -| FormatInvalid.cs:88:25:88:27 | "}" | FormatInvalid.cs:88:25:88:27 | "}" | FormatInvalid.cs:88:25:88:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:88:9:88:37 | call to method AppendFormat | this | FormatInvalid.cs:88:9:88:37 | call to method AppendFormat | this | -| FormatInvalid.cs:89:25:89:27 | "}" | FormatInvalid.cs:89:25:89:27 | "}" | FormatInvalid.cs:89:25:89:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:40 | call to method AppendFormat | this | FormatInvalid.cs:89:9:89:40 | call to method AppendFormat | this | -| FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:33 | call to method WriteLine | this | FormatInvalid.cs:91:9:91:33 | call to method WriteLine | this | -| FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:34 | call to method WriteLine | this | FormatInvalid.cs:92:9:92:34 | call to method WriteLine | this | -| FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:36 | call to method WriteLine | this | FormatInvalid.cs:93:9:93:36 | call to method WriteLine | this | -| FormatInvalid.cs:94:27:94:29 | "}" | FormatInvalid.cs:94:27:94:29 | "}" | FormatInvalid.cs:94:27:94:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:94:9:94:39 | call to method WriteLine | this | FormatInvalid.cs:94:9:94:39 | call to method WriteLine | this | -| FormatInvalid.cs:95:27:95:29 | "}" | FormatInvalid.cs:95:27:95:29 | "}" | FormatInvalid.cs:95:27:95:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:42 | call to method WriteLine | this | FormatInvalid.cs:95:9:95:42 | call to method WriteLine | this | -| FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:28 | call to method WriteLine | this | FormatInvalid.cs:97:9:97:28 | call to method WriteLine | this | -| FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:29 | call to method WriteLine | this | FormatInvalid.cs:98:9:98:29 | call to method WriteLine | this | -| FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:31 | call to method WriteLine | this | FormatInvalid.cs:99:9:99:31 | call to method WriteLine | this | -| FormatInvalid.cs:100:22:100:24 | "}" | FormatInvalid.cs:100:22:100:24 | "}" | FormatInvalid.cs:100:22:100:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:100:9:100:34 | call to method WriteLine | this | FormatInvalid.cs:100:9:100:34 | call to method WriteLine | this | -| FormatInvalid.cs:101:22:101:24 | "}" | FormatInvalid.cs:101:22:101:24 | "}" | FormatInvalid.cs:101:22:101:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:37 | call to method WriteLine | this | FormatInvalid.cs:101:9:101:37 | call to method WriteLine | this | -| FormatInvalid.cs:103:44:103:46 | "}" | FormatInvalid.cs:103:44:103:46 | "}" | FormatInvalid.cs:103:44:103:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:51 | call to method WriteLine | this | FormatInvalid.cs:103:9:103:51 | call to method WriteLine | this | -| FormatInvalid.cs:104:45:104:47 | "}" | FormatInvalid.cs:104:45:104:47 | "}" | FormatInvalid.cs:104:45:104:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:51 | call to method TraceError | this | FormatInvalid.cs:104:9:104:51 | call to method TraceError | this | -| FormatInvalid.cs:105:51:105:53 | "}" | FormatInvalid.cs:105:51:105:53 | "}" | FormatInvalid.cs:105:51:105:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:57 | call to method TraceInformation | this | FormatInvalid.cs:105:9:105:57 | call to method TraceInformation | this | -| FormatInvalid.cs:106:47:106:49 | "}" | FormatInvalid.cs:106:47:106:49 | "}" | FormatInvalid.cs:106:47:106:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:106:9:106:53 | call to method TraceWarning | this | FormatInvalid.cs:106:9:106:53 | call to method TraceWarning | this | -| FormatInvalid.cs:107:29:107:31 | "}" | FormatInvalid.cs:107:29:107:31 | "}" | FormatInvalid.cs:107:29:107:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:35 | call to method TraceInformation | this | FormatInvalid.cs:107:9:107:35 | call to method TraceInformation | this | -| FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:29 | call to method Write | this | FormatInvalid.cs:109:9:109:29 | call to method Write | this | -| FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:32 | call to method Write | this | FormatInvalid.cs:110:9:110:32 | call to method Write | this | -| FormatInvalid.cs:111:23:111:25 | "}" | FormatInvalid.cs:111:23:111:25 | "}" | FormatInvalid.cs:111:23:111:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:111:9:111:35 | call to method Write | this | FormatInvalid.cs:111:9:111:35 | call to method Write | this | -| FormatInvalid.cs:112:23:112:25 | "}" | FormatInvalid.cs:112:23:112:25 | "}" | FormatInvalid.cs:112:23:112:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:112:9:112:38 | call to method Write | this | FormatInvalid.cs:112:9:112:38 | call to method Write | this | -| FormatInvalid.cs:117:56:117:58 | "}" | FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:63 | call to method Assert | this | FormatInvalid.cs:117:9:117:63 | call to method Assert | this | -| FormatInvalid.cs:118:18:118:20 | "}" | FormatInvalid.cs:118:18:118:20 | "}" | FormatInvalid.cs:118:18:118:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:118:9:118:24 | call to method Write | this | FormatInvalid.cs:118:9:118:24 | call to method Write | this | -| FormatInvalid.cs:119:40:119:42 | "}" | FormatInvalid.cs:119:40:119:42 | "}" | FormatInvalid.cs:119:40:119:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:119:9:119:47 | call to method Print | this | FormatInvalid.cs:119:9:119:47 | call to method Print | this | +| FormatInvalid.cs:28:23:28:28 | "{ 0}" | FormatInvalid.cs:28:23:28:28 | "{ 0}" | FormatInvalid.cs:28:23:28:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:28:9:28:32 | call to method Format | this | FormatInvalid.cs:28:9:28:32 | call to method Format | this | +| FormatInvalid.cs:31:23:31:31 | "{0,--1}" | FormatInvalid.cs:31:23:31:31 | "{0,--1}" | FormatInvalid.cs:31:23:31:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:31:9:31:35 | call to method Format | this | FormatInvalid.cs:31:9:31:35 | call to method Format | this | +| FormatInvalid.cs:34:23:34:30 | "{0:{}}" | FormatInvalid.cs:34:23:34:30 | "{0:{}}" | FormatInvalid.cs:34:23:34:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:34:9:34:34 | call to method Format | this | FormatInvalid.cs:34:9:34:34 | call to method Format | this | +| FormatInvalid.cs:37:9:37:30 | call to method Format | FormatInvalid.cs:37:23:37:26 | "%d" | FormatInvalid.cs:37:23:37:26 | "%d" | The $@ ignores $@. | FormatInvalid.cs:37:23:37:26 | "%d" | format string | FormatInvalid.cs:37:29:37:29 | (...) ... | this supplied value | +| FormatInvalid.cs:40:23:40:33 | "{{0}-{1}}" | FormatInvalid.cs:40:23:40:33 | "{{0}-{1}}" | FormatInvalid.cs:40:23:40:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:40:9:40:40 | call to method Format | this | FormatInvalid.cs:40:9:40:40 | call to method Format | this | +| FormatInvalid.cs:43:23:43:28 | "{0}}" | FormatInvalid.cs:43:23:43:28 | "{0}}" | FormatInvalid.cs:43:23:43:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:43:9:43:35 | call to method Format | this | FormatInvalid.cs:43:9:43:35 | call to method Format | this | +| FormatInvalid.cs:46:23:46:32 | "{foo{0}}" | FormatInvalid.cs:46:23:46:32 | "{foo{0}}" | FormatInvalid.cs:46:23:46:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:46:9:46:36 | call to method Format | this | FormatInvalid.cs:46:9:46:36 | call to method Format | this | +| FormatInvalid.cs:52:23:52:28 | "}{0}" | FormatInvalid.cs:52:23:52:28 | "}{0}" | FormatInvalid.cs:52:23:52:28 | "}{0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:52:9:52:32 | call to method Format | this | FormatInvalid.cs:52:9:52:32 | call to method Format | this | +| FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:26 | call to method Format | this | FormatInvalid.cs:76:9:76:26 | call to method Format | this | +| FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | FormatInvalid.cs:77:23:77:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:29 | call to method Format | this | FormatInvalid.cs:77:9:77:29 | call to method Format | this | +| FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:30 | call to method Format | this | FormatInvalid.cs:78:9:78:30 | call to method Format | this | +| FormatInvalid.cs:79:27:79:29 | "}" | FormatInvalid.cs:79:27:79:29 | "}" | FormatInvalid.cs:79:27:79:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:34 | call to method Format | this | FormatInvalid.cs:79:9:79:34 | call to method Format | this | +| FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:32 | call to method Format | this | FormatInvalid.cs:80:9:80:32 | call to method Format | this | +| FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | FormatInvalid.cs:81:23:81:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:81:9:81:35 | call to method Format | this | FormatInvalid.cs:81:9:81:35 | call to method Format | this | +| FormatInvalid.cs:82:23:82:25 | "}" | FormatInvalid.cs:82:23:82:25 | "}" | FormatInvalid.cs:82:23:82:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:38 | call to method Format | this | FormatInvalid.cs:82:9:82:38 | call to method Format | this | +| FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | FormatInvalid.cs:84:25:84:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:28 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:28 | call to method AppendFormat | this | +| FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:31 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:31 | call to method AppendFormat | this | +| FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:32 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:32 | call to method AppendFormat | this | +| FormatInvalid.cs:87:29:87:31 | "}" | FormatInvalid.cs:87:29:87:31 | "}" | FormatInvalid.cs:87:29:87:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:36 | call to method AppendFormat | this | FormatInvalid.cs:87:9:87:36 | call to method AppendFormat | this | +| FormatInvalid.cs:88:25:88:27 | "}" | FormatInvalid.cs:88:25:88:27 | "}" | FormatInvalid.cs:88:25:88:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:88:9:88:34 | call to method AppendFormat | this | FormatInvalid.cs:88:9:88:34 | call to method AppendFormat | this | +| FormatInvalid.cs:89:25:89:27 | "}" | FormatInvalid.cs:89:25:89:27 | "}" | FormatInvalid.cs:89:25:89:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:37 | call to method AppendFormat | this | FormatInvalid.cs:89:9:89:37 | call to method AppendFormat | this | +| FormatInvalid.cs:90:25:90:27 | "}" | FormatInvalid.cs:90:25:90:27 | "}" | FormatInvalid.cs:90:25:90:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:40 | call to method AppendFormat | this | FormatInvalid.cs:90:9:90:40 | call to method AppendFormat | this | +| FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:33 | call to method WriteLine | this | FormatInvalid.cs:92:9:92:33 | call to method WriteLine | this | +| FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:34 | call to method WriteLine | this | FormatInvalid.cs:93:9:93:34 | call to method WriteLine | this | +| FormatInvalid.cs:94:27:94:29 | "}" | FormatInvalid.cs:94:27:94:29 | "}" | FormatInvalid.cs:94:27:94:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:94:9:94:36 | call to method WriteLine | this | FormatInvalid.cs:94:9:94:36 | call to method WriteLine | this | +| FormatInvalid.cs:95:27:95:29 | "}" | FormatInvalid.cs:95:27:95:29 | "}" | FormatInvalid.cs:95:27:95:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:39 | call to method WriteLine | this | FormatInvalid.cs:95:9:95:39 | call to method WriteLine | this | +| FormatInvalid.cs:96:27:96:29 | "}" | FormatInvalid.cs:96:27:96:29 | "}" | FormatInvalid.cs:96:27:96:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:42 | call to method WriteLine | this | FormatInvalid.cs:96:9:96:42 | call to method WriteLine | this | +| FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:28 | call to method WriteLine | this | FormatInvalid.cs:98:9:98:28 | call to method WriteLine | this | +| FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:29 | call to method WriteLine | this | FormatInvalid.cs:99:9:99:29 | call to method WriteLine | this | +| FormatInvalid.cs:100:22:100:24 | "}" | FormatInvalid.cs:100:22:100:24 | "}" | FormatInvalid.cs:100:22:100:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:100:9:100:31 | call to method WriteLine | this | FormatInvalid.cs:100:9:100:31 | call to method WriteLine | this | +| FormatInvalid.cs:101:22:101:24 | "}" | FormatInvalid.cs:101:22:101:24 | "}" | FormatInvalid.cs:101:22:101:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:34 | call to method WriteLine | this | FormatInvalid.cs:101:9:101:34 | call to method WriteLine | this | +| FormatInvalid.cs:102:22:102:24 | "}" | FormatInvalid.cs:102:22:102:24 | "}" | FormatInvalid.cs:102:22:102:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:37 | call to method WriteLine | this | FormatInvalid.cs:102:9:102:37 | call to method WriteLine | this | +| FormatInvalid.cs:104:44:104:46 | "}" | FormatInvalid.cs:104:44:104:46 | "}" | FormatInvalid.cs:104:44:104:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:51 | call to method WriteLine | this | FormatInvalid.cs:104:9:104:51 | call to method WriteLine | this | +| FormatInvalid.cs:105:45:105:47 | "}" | FormatInvalid.cs:105:45:105:47 | "}" | FormatInvalid.cs:105:45:105:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:51 | call to method TraceError | this | FormatInvalid.cs:105:9:105:51 | call to method TraceError | this | +| FormatInvalid.cs:106:51:106:53 | "}" | FormatInvalid.cs:106:51:106:53 | "}" | FormatInvalid.cs:106:51:106:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:106:9:106:57 | call to method TraceInformation | this | FormatInvalid.cs:106:9:106:57 | call to method TraceInformation | this | +| FormatInvalid.cs:107:47:107:49 | "}" | FormatInvalid.cs:107:47:107:49 | "}" | FormatInvalid.cs:107:47:107:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:53 | call to method TraceWarning | this | FormatInvalid.cs:107:9:107:53 | call to method TraceWarning | this | +| FormatInvalid.cs:108:29:108:31 | "}" | FormatInvalid.cs:108:29:108:31 | "}" | FormatInvalid.cs:108:29:108:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:35 | call to method TraceInformation | this | FormatInvalid.cs:108:9:108:35 | call to method TraceInformation | this | +| FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:29 | call to method Write | this | FormatInvalid.cs:110:9:110:29 | call to method Write | this | +| FormatInvalid.cs:111:23:111:25 | "}" | FormatInvalid.cs:111:23:111:25 | "}" | FormatInvalid.cs:111:23:111:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:111:9:111:32 | call to method Write | this | FormatInvalid.cs:111:9:111:32 | call to method Write | this | +| FormatInvalid.cs:112:23:112:25 | "}" | FormatInvalid.cs:112:23:112:25 | "}" | FormatInvalid.cs:112:23:112:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:112:9:112:35 | call to method Write | this | FormatInvalid.cs:112:9:112:35 | call to method Write | this | +| FormatInvalid.cs:113:23:113:25 | "}" | FormatInvalid.cs:113:23:113:25 | "}" | FormatInvalid.cs:113:23:113:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:113:9:113:38 | call to method Write | this | FormatInvalid.cs:113:9:113:38 | call to method Write | this | +| FormatInvalid.cs:118:56:118:58 | "}" | FormatInvalid.cs:118:56:118:58 | [assertion success] "}" | FormatInvalid.cs:118:56:118:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:118:9:118:63 | call to method Assert | this | FormatInvalid.cs:118:9:118:63 | call to method Assert | this | +| FormatInvalid.cs:119:18:119:20 | "}" | FormatInvalid.cs:119:18:119:20 | "}" | FormatInvalid.cs:119:18:119:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:119:9:119:24 | call to method Write | this | FormatInvalid.cs:119:9:119:24 | call to method Write | this | +| FormatInvalid.cs:120:40:120:42 | "}" | FormatInvalid.cs:120:40:120:42 | "}" | FormatInvalid.cs:120:40:120:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:120:9:120:47 | call to method Print | this | FormatInvalid.cs:120:9:120:47 | call to method Print | this | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | -| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | -| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | format string | FormatMissingArgument.cs:11:30:11:30 | (...) ... | this supplied value | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:34:14:34 | (...) ... | this supplied value | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:37:14:37 | (...) ... | this supplied value | -| FormatMissingArgument.cs:28:9:28:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | -| FormatMissingArgument.cs:28:9:28:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | format string | FormatMissingArgument.cs:28:31:28:31 | (...) ... | this supplied value | +| FormatMissingArgument.cs:12:9:12:31 | call to method Format | FormatMissingArgument.cs:12:23:12:27 | "{1}" | FormatMissingArgument.cs:12:23:12:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:12:23:12:27 | "{1}" | this | FormatMissingArgument.cs:12:23:12:27 | "{1}" | this | +| FormatMissingArgument.cs:12:9:12:31 | call to method Format | FormatMissingArgument.cs:12:23:12:27 | "{1}" | FormatMissingArgument.cs:12:23:12:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:12:23:12:27 | "{1}" | format string | FormatMissingArgument.cs:12:30:12:30 | (...) ... | this supplied value | +| FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | +| FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | +| FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | format string | FormatMissingArgument.cs:15:34:15:34 | (...) ... | this supplied value | +| FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | format string | FormatMissingArgument.cs:15:37:15:37 | (...) ... | this supplied value | +| FormatMissingArgument.cs:29:9:29:32 | call to method Format | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:23:16:23:20 | "{1}" | this | FormatMissingArgument.cs:23:16:23:20 | "{1}" | this | +| FormatMissingArgument.cs:29:9:29:32 | call to method Format | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:23:16:23:20 | "{1}" | format string | FormatMissingArgument.cs:29:31:29:31 | (...) ... | this supplied value | | FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | The $@ ignores $@. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | format string | FormatMissingArgumentBad.cs:8:44:8:48 | access to parameter first | this supplied value | -| FormatUnusedArgument.cs:11:9:11:29 | call to method Format | FormatUnusedArgument.cs:11:23:11:25 | "X" | FormatUnusedArgument.cs:11:23:11:25 | "X" | The $@ ignores $@. | FormatUnusedArgument.cs:11:23:11:25 | "X" | format string | FormatUnusedArgument.cs:11:28:11:28 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:14:9:14:34 | call to method Format | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | The $@ ignores $@. | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | format string | FormatUnusedArgument.cs:14:33:14:33 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:17:9:17:38 | call to method Format | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | The $@ ignores $@. | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:17:37:17:37 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:20:9:20:38 | call to method Format | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | The $@ ignores $@. | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:20:34:20:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:34:23:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:37:23:37 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:40:23:40 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:26:9:26:35 | call to method Format | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:26:34:26:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:38:9:38:33 | call to method Format | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | format string | FormatUnusedArgument.cs:38:32:38:32 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:12:9:12:29 | call to method Format | FormatUnusedArgument.cs:12:23:12:25 | "X" | FormatUnusedArgument.cs:12:23:12:25 | "X" | The $@ ignores $@. | FormatUnusedArgument.cs:12:23:12:25 | "X" | format string | FormatUnusedArgument.cs:12:28:12:28 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:15:9:15:34 | call to method Format | FormatUnusedArgument.cs:15:23:15:27 | "{0}" | FormatUnusedArgument.cs:15:23:15:27 | "{0}" | The $@ ignores $@. | FormatUnusedArgument.cs:15:23:15:27 | "{0}" | format string | FormatUnusedArgument.cs:15:33:15:33 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:18:9:18:38 | call to method Format | FormatUnusedArgument.cs:18:23:18:31 | "{0} {0}" | FormatUnusedArgument.cs:18:23:18:31 | "{0} {0}" | The $@ ignores $@. | FormatUnusedArgument.cs:18:23:18:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:18:37:18:37 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:21:9:21:38 | call to method Format | FormatUnusedArgument.cs:21:23:21:31 | "{1} {1}" | FormatUnusedArgument.cs:21:23:21:31 | "{1} {1}" | The $@ ignores $@. | FormatUnusedArgument.cs:21:23:21:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:21:34:21:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:24:9:24:41 | call to method Format | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | format string | FormatUnusedArgument.cs:24:34:24:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:24:9:24:41 | call to method Format | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | format string | FormatUnusedArgument.cs:24:37:24:37 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:24:9:24:41 | call to method Format | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | format string | FormatUnusedArgument.cs:24:40:24:40 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:27:9:27:35 | call to method Format | FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:27:34:27:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:39:9:39:33 | call to method Format | FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | format string | FormatUnusedArgument.cs:39:32:39:32 | (...) ... | this supplied value | | FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value | | FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value | | FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value | | FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value | edges -| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:25:24:25:29 | format : String | provenance | | -| FormatMissingArgument.cs:25:24:25:29 | format : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | provenance | | +| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:26:24:26:29 | format : String | provenance | | +| FormatMissingArgument.cs:26:24:26:29 | format : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | provenance | | nodes -| FormatInvalid.cs:9:23:9:27 | "{0}" | semmle.label | "{0}" | -| FormatInvalid.cs:12:23:12:29 | "{0,1}" | semmle.label | "{0,1}" | -| FormatInvalid.cs:15:23:15:31 | "{0, 1}" | semmle.label | "{0, 1}" | -| FormatInvalid.cs:18:23:18:30 | "{0,-1}" | semmle.label | "{0,-1}" | -| FormatInvalid.cs:21:23:21:33 | "{0:0.000}" | semmle.label | "{0:0.000}" | -| FormatInvalid.cs:24:23:24:39 | "{0, -10 :0.000}" | semmle.label | "{0, -10 :0.000}" | -| FormatInvalid.cs:27:23:27:28 | "{ 0}" | semmle.label | "{ 0}" | -| FormatInvalid.cs:30:23:30:31 | "{0,--1}" | semmle.label | "{0,--1}" | -| FormatInvalid.cs:33:23:33:30 | "{0:{}}" | semmle.label | "{0:{}}" | -| FormatInvalid.cs:36:23:36:26 | "%d" | semmle.label | "%d" | -| FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | semmle.label | "{{0}-{1}}" | -| FormatInvalid.cs:42:23:42:28 | "{0}}" | semmle.label | "{0}}" | -| FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | semmle.label | "{foo{0}}" | -| FormatInvalid.cs:48:23:48:34 | "{{sdc}}{0}" | semmle.label | "{{sdc}}{0}" | -| FormatInvalid.cs:51:23:51:28 | "}{0}" | semmle.label | "}{0}" | -| FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | semmle.label | "new {0} ({1} => {{" | -| FormatInvalid.cs:57:23:57:29 | "{0}{{" | semmle.label | "{0}{{" | -| FormatInvalid.cs:58:23:58:33 | "{0}{{{{}}" | semmle.label | "{0}{{{{}}" | -| FormatInvalid.cs:75:23:75:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:10:23:10:27 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:13:23:13:29 | "{0,1}" | semmle.label | "{0,1}" | +| FormatInvalid.cs:16:23:16:31 | "{0, 1}" | semmle.label | "{0, 1}" | +| FormatInvalid.cs:19:23:19:30 | "{0,-1}" | semmle.label | "{0,-1}" | +| FormatInvalid.cs:22:23:22:33 | "{0:0.000}" | semmle.label | "{0:0.000}" | +| FormatInvalid.cs:25:23:25:39 | "{0, -10 :0.000}" | semmle.label | "{0, -10 :0.000}" | +| FormatInvalid.cs:28:23:28:28 | "{ 0}" | semmle.label | "{ 0}" | +| FormatInvalid.cs:31:23:31:31 | "{0,--1}" | semmle.label | "{0,--1}" | +| FormatInvalid.cs:34:23:34:30 | "{0:{}}" | semmle.label | "{0:{}}" | +| FormatInvalid.cs:37:23:37:26 | "%d" | semmle.label | "%d" | +| FormatInvalid.cs:40:23:40:33 | "{{0}-{1}}" | semmle.label | "{{0}-{1}}" | +| FormatInvalid.cs:43:23:43:28 | "{0}}" | semmle.label | "{0}}" | +| FormatInvalid.cs:46:23:46:32 | "{foo{0}}" | semmle.label | "{foo{0}}" | +| FormatInvalid.cs:49:23:49:34 | "{{sdc}}{0}" | semmle.label | "{{sdc}}{0}" | +| FormatInvalid.cs:52:23:52:28 | "}{0}" | semmle.label | "}{0}" | +| FormatInvalid.cs:55:23:55:42 | "new {0} ({1} => {{" | semmle.label | "new {0} ({1} => {{" | +| FormatInvalid.cs:58:23:58:29 | "{0}{{" | semmle.label | "{0}{{" | +| FormatInvalid.cs:59:23:59:33 | "{0}{{{{}}" | semmle.label | "{0}{{{{}}" | | FormatInvalid.cs:76:23:76:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:77:23:77:25 | "}" | semmle.label | "}" | -| FormatInvalid.cs:78:27:78:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:79:23:79:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:78:23:78:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:79:27:79:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:80:23:80:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:81:23:81:25 | "}" | semmle.label | "}" | -| FormatInvalid.cs:83:25:83:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:82:23:82:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:84:25:84:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:85:25:85:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:86:29:86:31 | "}" | semmle.label | "}" | -| FormatInvalid.cs:87:25:87:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:86:25:86:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:87:29:87:31 | "}" | semmle.label | "}" | | FormatInvalid.cs:88:25:88:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:89:25:89:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:91:27:91:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:90:25:90:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:92:27:92:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:93:27:93:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:94:27:94:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:95:27:95:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:97:22:97:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:96:27:96:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:98:22:98:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:99:22:99:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:100:22:100:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:101:22:101:24 | "}" | semmle.label | "}" | -| FormatInvalid.cs:103:44:103:46 | "}" | semmle.label | "}" | -| FormatInvalid.cs:104:45:104:47 | "}" | semmle.label | "}" | -| FormatInvalid.cs:105:51:105:53 | "}" | semmle.label | "}" | -| FormatInvalid.cs:106:47:106:49 | "}" | semmle.label | "}" | -| FormatInvalid.cs:107:29:107:31 | "}" | semmle.label | "}" | -| FormatInvalid.cs:109:23:109:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:102:22:102:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:104:44:104:46 | "}" | semmle.label | "}" | +| FormatInvalid.cs:105:45:105:47 | "}" | semmle.label | "}" | +| FormatInvalid.cs:106:51:106:53 | "}" | semmle.label | "}" | +| FormatInvalid.cs:107:47:107:49 | "}" | semmle.label | "}" | +| FormatInvalid.cs:108:29:108:31 | "}" | semmle.label | "}" | | FormatInvalid.cs:110:23:110:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:111:23:111:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:112:23:112:25 | "}" | semmle.label | "}" | -| FormatInvalid.cs:117:56:117:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | -| FormatInvalid.cs:118:18:118:20 | "}" | semmle.label | "}" | -| FormatInvalid.cs:119:40:119:42 | "}" | semmle.label | "}" | +| FormatInvalid.cs:113:23:113:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:118:56:118:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | +| FormatInvalid.cs:119:18:119:20 | "}" | semmle.label | "}" | +| FormatInvalid.cs:120:40:120:42 | "}" | semmle.label | "}" | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | semmle.label | "class {0} { }" | | FormatInvalidGood.cs:7:30:7:46 | "class {0} {{ }}" | semmle.label | "class {0} {{ }}" | -| FormatMissingArgument.cs:8:23:8:27 | "{0}" | semmle.label | "{0}" | -| FormatMissingArgument.cs:11:23:11:27 | "{1}" | semmle.label | "{1}" | -| FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | semmle.label | "{2} {3}" | -| FormatMissingArgument.cs:17:23:17:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | -| FormatMissingArgument.cs:20:23:20:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | -| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | semmle.label | "{1}" : String | -| FormatMissingArgument.cs:25:24:25:29 | format : String | semmle.label | format : String | -| FormatMissingArgument.cs:28:23:28:28 | access to parameter format | semmle.label | access to parameter format | +| FormatMissingArgument.cs:9:23:9:27 | "{0}" | semmle.label | "{0}" | +| FormatMissingArgument.cs:12:23:12:27 | "{1}" | semmle.label | "{1}" | +| FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | semmle.label | "{2} {3}" | +| FormatMissingArgument.cs:18:23:18:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatMissingArgument.cs:21:23:21:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:26:24:26:29 | format : String | semmle.label | format : String | +| FormatMissingArgument.cs:29:23:29:28 | access to parameter format | semmle.label | access to parameter format | | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" | | FormatMissingArgumentGood.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | -| FormatUnusedArgument.cs:8:23:8:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | -| FormatUnusedArgument.cs:11:23:11:25 | "X" | semmle.label | "X" | -| FormatUnusedArgument.cs:14:23:14:27 | "{0}" | semmle.label | "{0}" | -| FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | semmle.label | "{0} {0}" | -| FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | semmle.label | "{1} {1}" | -| FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | semmle.label | "abcdefg" | -| FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | -| FormatUnusedArgument.cs:29:23:29:33 | "{{{0:D}}}" | semmle.label | "{{{0:D}}}" | -| FormatUnusedArgument.cs:32:23:32:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | -| FormatUnusedArgument.cs:35:23:35:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | -| FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | semmle.label | "{{0}}" | -| FormatUnusedArgument.cs:42:23:42:24 | "" | semmle.label | "" | +| FormatUnusedArgument.cs:9:23:9:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatUnusedArgument.cs:12:23:12:25 | "X" | semmle.label | "X" | +| FormatUnusedArgument.cs:15:23:15:27 | "{0}" | semmle.label | "{0}" | +| FormatUnusedArgument.cs:18:23:18:31 | "{0} {0}" | semmle.label | "{0} {0}" | +| FormatUnusedArgument.cs:21:23:21:31 | "{1} {1}" | semmle.label | "{1} {1}" | +| FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | semmle.label | "abcdefg" | +| FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | +| FormatUnusedArgument.cs:30:23:30:33 | "{{{0:D}}}" | semmle.label | "{{{0:D}}}" | +| FormatUnusedArgument.cs:33:23:33:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatUnusedArgument.cs:36:23:36:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | semmle.label | "{{0}}" | +| FormatUnusedArgument.cs:43:23:43:24 | "" | semmle.label | "" | | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | semmle.label | "Error processing file: {0}" | | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | subpaths +testFailures +| FormatInvalid.cs:140:50:140:59 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:35:53:35:63 | // ... | Missing result: Source | +| FormatMissingArgument.cs:37:57:37:67 | // ... | Missing result: Source | +| FormatMissingArgument.cs:43:51:43:65 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:43:51:43:65 | // ... | Missing result: Sink | +| FormatMissingArgument.cs:49:64:49:78 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:49:64:49:78 | // ... | Missing result: Sink | +| FormatMissingArgument.cs:57:45:57:59 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:57:45:57:59 | // ... | Missing result: Sink | +| FormatMissingArgument.cs:58:53:58:67 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:58:53:58:67 | // ... | Missing result: Sink | +| FormatMissingArgument.cs:64:66:64:80 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:64:66:64:80 | // ... | Missing result: Sink | +| FormatMissingArgument.cs:74:50:74:64 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:74:50:74:64 | // ... | Missing result: Sink | +| FormatMissingArgument.cs:75:58:75:72 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:75:58:75:72 | // ... | Missing result: Sink | +| FormatMissingArgument.cs:81:71:81:85 | // ... | Missing result: Alert | +| FormatMissingArgument.cs:81:71:81:85 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:48:50:48:60 | // ... | Missing result: Source | +| FormatUnusedArgument.cs:49:57:49:67 | // ... | Missing result: Source | +| FormatUnusedArgument.cs:50:57:50:67 | // ... | Missing result: Source | +| FormatUnusedArgument.cs:53:50:53:64 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:53:50:53:64 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:56:64:56:78 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:56:64:56:78 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:59:64:59:78 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:59:64:59:78 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:62:44:62:58 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:62:44:62:58 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:63:52:63:66 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:63:52:63:66 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:66:66:66:80 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:66:66:66:80 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:69:66:69:80 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:69:66:69:80 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:74:49:74:63 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:74:49:74:63 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:75:57:75:71 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:75:57:75:71 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:78:71:78:85 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:78:71:78:85 | // ... | Missing result: Sink | +| FormatUnusedArgument.cs:81:71:81:85 | // ... | Missing result: Alert | +| FormatUnusedArgument.cs:81:71:81:85 | // ... | Missing result: Sink | diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs index fabe7b239e4a..d059e7a5400c 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs @@ -1,4 +1,5 @@ using System; +using System.Text; class Class1 { @@ -28,5 +29,59 @@ void helper(string format) String.Format(format, 0); // $ Alert Sink } + void TestCompositeFormatMissingArgument() + { + var format0 = CompositeFormat.Parse("{0}"); + var format1 = CompositeFormat.Parse("{1}"); // $ Source + var format01 = CompositeFormat.Parse("{0}{1}"); + var format23 = CompositeFormat.Parse("{2}{3}"); // $ Source + + // GOOD: All args supplied + String.Format(null, format0, ""); + + // BAD: Missing {1} + String.Format(null, format1, ""); // $ Alert Sink + + // GOOD: All args supplied + String.Format(null, format01, "", ""); + + // BAD: Missing {2} and {3} + String.Format(null, format23, "", ""); // $ Alert Sink + + + // GOOD: All arguments supplied + sb.AppendFormat(null, format0, ""); + sb.AppendFormat(null, format0, ""); + + // BAD: Missing {1} + sb.AppendFormat(null, format1, ""); // $ Alert Sink + sb.AppendFormat(null, format1, ""); // $ Alert Sink + + // GOOD: All args supplied + sb.AppendFormat(null, format01, "", ""); + + // BAD: Missing {2} and {3} + sb.AppendFormat(null, format23, "", ""); // $ Alert Sink + + + var span = new Span(); + + // GOOD: All args supplied + span.TryWrite(null, format0, out _, ""); + span.TryWrite(null, format0, out _, ""); + + // BAD: Missing {1} + span.TryWrite(null, format1, out _, ""); // $ Alert Sink + span.TryWrite(null, format1, out _, ""); // $ Alert Sink + + // GOOD: All args supplied + span.TryWrite(null, format01, out _, "", ""); + + // BAD: Missing {2} and {3} + span.TryWrite(null, format23, out _, "", ""); // $ Alert Sink + } + object[] args; + + StringBuilder sb; } diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs index 61f691840870..77ef70338dbc 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs @@ -1,4 +1,5 @@ using System; +using System.Text; class C { @@ -42,5 +43,46 @@ void FormatTests() String.Format("", 1); } + void CompositeFormatTests() + { + var format = CompositeFormat.Parse("X"); // $ Source + var format00 = CompositeFormat.Parse("{0}{0}"); // $ Source + var format11 = CompositeFormat.Parse("{1}{1}"); // $ Source + + // BAD: Unused arg {0} + String.Format(null, format, ""); // $ Alert Sink + + // BAD: Unused arg {1} + String.Format(null, format00, "", ""); // $ Alert Sink + + // BAD: Unused arg {0} + String.Format(null, format11, "", ""); // $ Alert Sink + + // BAD: Unused arg {0} + sb.AppendFormat(null, format, ""); // $ Alert Sink + sb.AppendFormat(null, format, ""); // $ Alert Sink + + // BAD: Unused arg {1} + sb.AppendFormat(null, format00, "", ""); // $ Alert Sink + + // BAD: Unused arg {0} + sb.AppendFormat(null, format11, "", ""); // $ Alert Sink + + var span = new Span(); + + // BAD: Unused arg {0} + span.TryWrite(null, format, out _, ""); // $ Alert Sink + span.TryWrite(null, format, out _, ""); // $ Alert Sink + + // BAD: Unused arg {1} + span.TryWrite(null, format00, out _, "", ""); // $ Alert Sink + + // BAD: Unused arg {0} + span.TryWrite(null, format11, out _, "", ""); // $ Alert Sink + + } + object[] ps; + + StringBuilder sb; } From c48175421c7d0b474aa7a6903d1fcfbd27a5d45c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 8 Apr 2025 16:46:14 +0200 Subject: [PATCH 09/21] C#: Improve format logic to take CompositeFormat and generics into account. --- .../semmle/code/csharp/frameworks/Format.qll | 29 ++++++++- .../semmle/code/csharp/frameworks/System.qll | 14 +++- .../code/csharp/frameworks/system/Text.qll | 15 ++++- csharp/ql/src/API Abuse/FormatInvalid.ql | 64 +++++++++++++++---- 4 files changed, 106 insertions(+), 16 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index db1d4e42d74a..7bccf3e0e6bd 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -14,13 +14,26 @@ abstract class FormatMethod extends Method { * `string.Format(IFormatProvider, String, Object)` is `1`. */ abstract int getFormatArgument(); + + /** + * Gets the argument number of the first supplied insert. + */ + int getFirstArgument() { result = this.getFormatArgument() + 1 } +} + +/** A class of types used for formatting. */ +private class FormatType extends Type { + FormatType() { + this instanceof StringType or + this instanceof SystemTextCompositeFormatClass + } } private class StringAndStringBuilderFormatMethods extends FormatMethod { StringAndStringBuilderFormatMethods() { ( this.getParameter(0).getType() instanceof SystemIFormatProviderInterface and - this.getParameter(1).getType() instanceof StringType + this.getParameter(1).getType() instanceof FormatType or this.getParameter(0).getType() instanceof StringType ) and @@ -38,6 +51,18 @@ private class StringAndStringBuilderFormatMethods extends FormatMethod { } } +private class SystemMemoryExtensionsFormatMethods extends FormatMethod { + SystemMemoryExtensionsFormatMethods() { + this = any(SystemMemoryExtensionsClass c).getTryWriteMethod() and + this.getParameter(1).getType() instanceof SystemIFormatProviderInterface and + this.getParameter(2).getType() instanceof SystemTextCompositeFormatClass + } + + override int getFormatArgument() { result = 2 } + + override int getFirstArgument() { result = this.getFormatArgument() + 2 } +} + private class SystemConsoleAndSystemIoTextWriterFormatMethods extends FormatMethod { SystemConsoleAndSystemIoTextWriterFormatMethods() { this.getParameter(0).getType() instanceof StringType and @@ -220,7 +245,7 @@ class FormatCall extends MethodCall { int getFormatArgument() { result = this.getTarget().(FormatMethod).getFormatArgument() } /** Gets the argument number of the first supplied insert. */ - int getFirstArgument() { result = this.getFormatArgument() + 1 } + int getFirstArgument() { result = this.getTarget().(FormatMethod).getFirstArgument() } /** Holds if this call has one or more insertions. */ predicate hasInsertions() { exists(this.getArgument(this.getFirstArgument())) } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll index 678563589e8a..2681b9437b69 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll @@ -365,7 +365,7 @@ class SystemStringClass extends StringType { /** Gets a `Format(...)` method. */ Method getFormatMethod() { result.getDeclaringType() = this and - result.hasName("Format") and + result.getName().regexpMatch("Format(<.*>)?") and result.getNumberOfParameters() in [2 .. 5] and result.getReturnType() instanceof StringType } @@ -751,6 +751,18 @@ class SystemNotImplementedExceptionClass extends SystemClass { SystemNotImplementedExceptionClass() { this.hasName("NotImplementedException") } } +/** The `System.MemoryExtensions` class. */ +class SystemMemoryExtensionsClass extends SystemClass { + SystemMemoryExtensionsClass() { this.hasName("MemoryExtensions") } + + /** Gets a `TryWrite` method. */ + Method getTryWriteMethod() { + result.getDeclaringType() = this and + result.getName().regexpMatch("TryWrite(<.*>)?") and + result.getParameter(0).getType().getUnboundDeclaration() instanceof SystemSpanStruct + } +} + /** The `System.DateTime` struct. */ class SystemDateTimeStruct extends SystemStruct { SystemDateTimeStruct() { this.hasName("DateTime") } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll index fb4c37489af6..c5d44c7c9add 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Text.qll @@ -22,7 +22,12 @@ class SystemTextStringBuilderClass extends SystemTextClass { SystemTextStringBuilderClass() { this.hasName("StringBuilder") } /** Gets the `AppendFormat` method. */ - Method getAppendFormatMethod() { result = this.getAMethod("AppendFormat") } + Method getAppendFormatMethod() { + exists(string name | + name.regexpMatch("AppendFormat(<.*>)?") and + result = this.getAMethod(name) + ) + } } /** The `System.Text.Encoding` class. */ @@ -38,3 +43,11 @@ class SystemTextEncodingClass extends SystemTextClass { /** Gets the `GetChars` method. */ Method getGetCharsMethod() { result = this.getAMethod("GetChars") } } + +/** The `System.Text.CompositeFormat` class */ +class SystemTextCompositeFormatClass extends SystemTextClass { + SystemTextCompositeFormatClass() { this.hasName("CompositeFormat") } + + /** Gets the `Parse` method. */ + Method getParseMethod() { result = this.getAMethod("Parse") } +} diff --git a/csharp/ql/src/API Abuse/FormatInvalid.ql b/csharp/ql/src/API Abuse/FormatInvalid.ql index 17923d5bc355..a2b8ef5e2220 100644 --- a/csharp/ql/src/API Abuse/FormatInvalid.ql +++ b/csharp/ql/src/API Abuse/FormatInvalid.ql @@ -11,20 +11,59 @@ */ import csharp +import semmle.code.csharp.frameworks.system.Text import semmle.code.csharp.frameworks.Format -import FormatInvalid::PathGraph +import FormatFlow::PathGraph + +abstract class FormatStringParseCall extends MethodCall { + abstract Expr getFormatExpr(); +} + +class OrdinaryFormatCall extends FormatStringParseCall instanceof FormatCall { + override Expr getFormatExpr() { result = FormatCall.super.getFormatExpr() } +} + +class ParseFormatStringCall extends FormatStringParseCall { + ParseFormatStringCall() { + this.getTarget() = any(SystemTextCompositeFormatClass x).getParseMethod() + } + + override Expr getFormatExpr() { result = this.getArgument(0) } +} module FormatInvalidConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLiteral } - predicate isSink(DataFlow::Node n) { exists(FormatCall c | n.asExpr() = c.getFormatExpr()) } + predicate isSink(DataFlow::Node n) { + exists(FormatStringParseCall c | n.asExpr() = c.getFormatExpr()) + } } module FormatInvalid = DataFlow::Global; +module FormatLiteralConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLiteral } + + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + // Add flow via `System.Text.CompositeFormat.Parse`. + exists(ParseFormatStringCall call | + pred.asExpr() = call.getFormatExpr() and + succ.asExpr() = call + ) + } + + predicate isSink(DataFlow::Node n) { exists(FormatCall c | n.asExpr() = c.getFormatExpr()) } +} + +module FormatLiteral = DataFlow::Global; + +module FormatFlow = + DataFlow::MergePathGraph; + private predicate invalidFormatString( InvalidFormatString src, FormatInvalid::PathNode source, FormatInvalid::PathNode sink, string msg, - FormatCall call, string callString + FormatStringParseCall call, string callString ) { source.getNode().asExpr() = src and sink.getNode().asExpr() = call.getFormatExpr() and @@ -34,13 +73,13 @@ private predicate invalidFormatString( } private predicate unusedArgument( - FormatCall call, FormatInvalid::PathNode source, FormatInvalid::PathNode sink, string msg, + FormatCall call, FormatLiteral::PathNode source, FormatLiteral::PathNode sink, string msg, ValidFormatString src, string srcString, Expr unusedExpr, string unusedString ) { exists(int unused | source.getNode().asExpr() = src and sink.getNode().asExpr() = call.getFormatExpr() and - FormatInvalid::flowPath(source, sink) and + FormatLiteral::flowPath(source, sink) and unused = call.getASuppliedArgument() and not unused = src.getAnInsert() and not src.getValue() = "" and @@ -52,13 +91,13 @@ private predicate unusedArgument( } private predicate missingArgument( - FormatCall call, FormatInvalid::PathNode source, FormatInvalid::PathNode sink, string msg, + FormatCall call, FormatLiteral::PathNode source, FormatLiteral::PathNode sink, string msg, ValidFormatString src, string srcString ) { exists(int used, int supplied | source.getNode().asExpr() = src and sink.getNode().asExpr() = call.getFormatExpr() and - FormatInvalid::flowPath(source, sink) and + FormatLiteral::flowPath(source, sink) and used = src.getAnInsert() and supplied = call.getSuppliedArguments() and used >= supplied and @@ -68,16 +107,17 @@ private predicate missingArgument( } from - Element alert, FormatInvalid::PathNode source, FormatInvalid::PathNode sink, string msg, - Element extra1, string extra1String, Element extra2, string extra2String + Element alert, FormatFlow::PathNode source, FormatFlow::PathNode sink, string msg, Element extra1, + string extra1String, Element extra2, string extra2String where - invalidFormatString(alert, source, sink, msg, extra1, extra1String) and + invalidFormatString(alert, source.asPathNode1(), sink.asPathNode1(), msg, extra1, extra1String) and extra2 = extra1 and extra2String = extra1String or - unusedArgument(alert, source, sink, msg, extra1, extra1String, extra2, extra2String) + unusedArgument(alert, source.asPathNode2(), sink.asPathNode2(), msg, extra1, extra1String, extra2, + extra2String) or - missingArgument(alert, source, sink, msg, extra1, extra1String) and + missingArgument(alert, source.asPathNode2(), sink.asPathNode2(), msg, extra1, extra1String) and extra2 = extra1 and extra2String = extra1String select alert, source, sink, msg, extra1, extra1String, extra2, extra2String From a018ab182bd526ba7499bf85e8679a21d99285ed Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 9 Apr 2025 14:42:44 +0200 Subject: [PATCH 10/21] C#: Update test expected output. --- .../FormatInvalid/FormatInvalid.expected | 287 +++++++++++++++--- 1 file changed, 242 insertions(+), 45 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index 3d23145b406e..ddbdd5c4fb5a 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -43,6 +43,7 @@ | FormatInvalid.cs:118:56:118:58 | "}" | FormatInvalid.cs:118:56:118:58 | [assertion success] "}" | FormatInvalid.cs:118:56:118:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:118:9:118:63 | call to method Assert | this | FormatInvalid.cs:118:9:118:63 | call to method Assert | this | | FormatInvalid.cs:119:18:119:20 | "}" | FormatInvalid.cs:119:18:119:20 | "}" | FormatInvalid.cs:119:18:119:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:119:9:119:24 | call to method Write | this | FormatInvalid.cs:119:9:119:24 | call to method Write | this | | FormatInvalid.cs:120:40:120:42 | "}" | FormatInvalid.cs:120:40:120:42 | "}" | FormatInvalid.cs:120:40:120:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:120:9:120:47 | call to method Print | this | FormatInvalid.cs:120:9:120:47 | call to method Print | this | +| FormatInvalid.cs:140:44:140:46 | "}" | FormatInvalid.cs:140:44:140:46 | "}" | FormatInvalid.cs:140:44:140:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:140:22:140:47 | call to method Parse | this | FormatInvalid.cs:140:22:140:47 | call to method Parse | this | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | | FormatMissingArgument.cs:12:9:12:31 | call to method Format | FormatMissingArgument.cs:12:23:12:27 | "{1}" | FormatMissingArgument.cs:12:23:12:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:12:23:12:27 | "{1}" | this | FormatMissingArgument.cs:12:23:12:27 | "{1}" | this | | FormatMissingArgument.cs:12:9:12:31 | call to method Format | FormatMissingArgument.cs:12:23:12:27 | "{1}" | FormatMissingArgument.cs:12:23:12:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:12:23:12:27 | "{1}" | format string | FormatMissingArgument.cs:12:30:12:30 | (...) ... | this supplied value | @@ -52,6 +53,28 @@ | FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | format string | FormatMissingArgument.cs:15:37:15:37 | (...) ... | this supplied value | | FormatMissingArgument.cs:29:9:29:32 | call to method Format | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:23:16:23:20 | "{1}" | this | FormatMissingArgument.cs:23:16:23:20 | "{1}" | this | | FormatMissingArgument.cs:29:9:29:32 | call to method Format | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:23:16:23:20 | "{1}" | format string | FormatMissingArgument.cs:29:31:29:31 | (...) ... | this supplied value | +| FormatMissingArgument.cs:43:9:43:48 | call to method Format | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | +| FormatMissingArgument.cs:43:9:43:48 | call to method Format | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:43:46:43:47 | "" | this supplied value | +| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:49:55:49:56 | "" | this supplied value | +| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:49:59:49:60 | "" | this supplied value | +| FormatMissingArgument.cs:57:9:57:42 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | +| FormatMissingArgument.cs:57:9:57:42 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:57:40:57:41 | "" | this supplied value | +| FormatMissingArgument.cs:58:9:58:50 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | +| FormatMissingArgument.cs:58:9:58:50 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:58:48:58:49 | "" | this supplied value | +| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:64:57:64:58 | "" | this supplied value | +| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:64:61:64:62 | "" | this supplied value | +| FormatMissingArgument.cs:74:9:74:47 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | +| FormatMissingArgument.cs:74:9:74:47 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:74:45:74:46 | "" | this supplied value | +| FormatMissingArgument.cs:75:9:75:55 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | +| FormatMissingArgument.cs:75:9:75:55 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:75:53:75:54 | "" | this supplied value | +| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:81:62:81:63 | "" | this supplied value | +| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:81:66:81:67 | "" | this supplied value | | FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | The $@ ignores $@. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | format string | FormatMissingArgumentBad.cs:8:44:8:48 | access to parameter first | this supplied value | @@ -64,139 +87,313 @@ | FormatUnusedArgument.cs:24:9:24:41 | call to method Format | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | format string | FormatUnusedArgument.cs:24:40:24:40 | (...) ... | this supplied value | | FormatUnusedArgument.cs:27:9:27:35 | call to method Format | FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:27:34:27:34 | (...) ... | this supplied value | | FormatUnusedArgument.cs:39:9:39:33 | call to method Format | FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | format string | FormatUnusedArgument.cs:39:32:39:32 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:53:9:53:47 | call to method Format | FormatUnusedArgument.cs:48:44:48:46 | "X" : String | FormatUnusedArgument.cs:53:37:53:42 | access to local variable format | The $@ ignores $@. | FormatUnusedArgument.cs:48:44:48:46 | "X" | format string | FormatUnusedArgument.cs:53:45:53:46 | "" | this supplied value | +| FormatUnusedArgument.cs:56:9:56:61 | call to method Format | FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" : String | FormatUnusedArgument.cs:56:45:56:52 | access to local variable format00 | The $@ ignores $@. | FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" | format string | FormatUnusedArgument.cs:56:59:56:60 | "" | this supplied value | +| FormatUnusedArgument.cs:59:9:59:61 | call to method Format | FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" : String | FormatUnusedArgument.cs:59:45:59:52 | access to local variable format11 | The $@ ignores $@. | FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" | format string | FormatUnusedArgument.cs:59:55:59:56 | "" | this supplied value | +| FormatUnusedArgument.cs:62:9:62:41 | call to method AppendFormat | FormatUnusedArgument.cs:48:44:48:46 | "X" : String | FormatUnusedArgument.cs:62:31:62:36 | access to local variable format | The $@ ignores $@. | FormatUnusedArgument.cs:48:44:48:46 | "X" | format string | FormatUnusedArgument.cs:62:39:62:40 | "" | this supplied value | +| FormatUnusedArgument.cs:63:9:63:49 | call to method AppendFormat | FormatUnusedArgument.cs:48:44:48:46 | "X" : String | FormatUnusedArgument.cs:63:39:63:44 | access to local variable format | The $@ ignores $@. | FormatUnusedArgument.cs:48:44:48:46 | "X" | format string | FormatUnusedArgument.cs:63:47:63:48 | "" | this supplied value | +| FormatUnusedArgument.cs:66:9:66:63 | call to method AppendFormat | FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" : String | FormatUnusedArgument.cs:66:47:66:54 | access to local variable format00 | The $@ ignores $@. | FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" | format string | FormatUnusedArgument.cs:66:61:66:62 | "" | this supplied value | +| FormatUnusedArgument.cs:69:9:69:63 | call to method AppendFormat | FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" : String | FormatUnusedArgument.cs:69:47:69:54 | access to local variable format11 | The $@ ignores $@. | FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" | format string | FormatUnusedArgument.cs:69:57:69:58 | "" | this supplied value | +| FormatUnusedArgument.cs:74:9:74:46 | call to method TryWrite | FormatUnusedArgument.cs:48:44:48:46 | "X" : String | FormatUnusedArgument.cs:74:29:74:34 | access to local variable format | The $@ ignores $@. | FormatUnusedArgument.cs:48:44:48:46 | "X" | format string | FormatUnusedArgument.cs:74:44:74:45 | "" | this supplied value | +| FormatUnusedArgument.cs:75:9:75:54 | call to method TryWrite | FormatUnusedArgument.cs:48:44:48:46 | "X" : String | FormatUnusedArgument.cs:75:37:75:42 | access to local variable format | The $@ ignores $@. | FormatUnusedArgument.cs:48:44:48:46 | "X" | format string | FormatUnusedArgument.cs:75:52:75:53 | "" | this supplied value | +| FormatUnusedArgument.cs:78:9:78:68 | call to method TryWrite | FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" : String | FormatUnusedArgument.cs:78:45:78:52 | access to local variable format00 | The $@ ignores $@. | FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" | format string | FormatUnusedArgument.cs:78:66:78:67 | "" | this supplied value | +| FormatUnusedArgument.cs:81:9:81:68 | call to method TryWrite | FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" : String | FormatUnusedArgument.cs:81:45:81:52 | access to local variable format11 | The $@ ignores $@. | FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" | format string | FormatUnusedArgument.cs:81:62:81:63 | "" | this supplied value | | FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value | | FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value | | FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value | | FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value | edges +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:143:37:143:42 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:144:45:144:50 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:145:53:145:58 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:147:31:147:36 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:148:39:148:44 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:149:47:149:52 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:150:55:150:60 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:154:29:154:34 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:155:37:155:42 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:156:45:156:50 | access to local variable format | provenance | | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:157:53:157:58 | access to local variable format | provenance | | +| FormatInvalid.cs:140:22:140:47 | call to method Parse : CompositeFormat | FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | provenance | | +| FormatInvalid.cs:140:44:140:46 | "}" : String | FormatInvalid.cs:140:22:140:47 | call to method Parse : CompositeFormat | provenance | Config | | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:26:24:26:29 | format : String | provenance | | +| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:26:24:26:29 | format : String | provenance | | +| FormatMissingArgument.cs:26:24:26:29 | format : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | provenance | | | FormatMissingArgument.cs:26:24:26:29 | format : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | provenance | | +| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:40:37:40:43 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:53:31:53:37 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:54:39:54:45 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:70:29:70:35 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:71:37:71:43 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:34:23:34:50 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:34:45:34:49 | "{0}" : String | FormatMissingArgument.cs:34:23:34:50 | call to method Parse : CompositeFormat | provenance | Config | +| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:35:23:35:50 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:35:23:35:50 | call to method Parse : CompositeFormat | provenance | Config | +| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:46:45:46:52 | access to local variable format01 | provenance | | +| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:61:47:61:54 | access to local variable format01 | provenance | | +| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:78:45:78:52 | access to local variable format01 | provenance | | +| FormatMissingArgument.cs:36:24:36:54 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:36:46:36:53 | "{0}{1}" : String | FormatMissingArgument.cs:36:24:36:54 | call to method Parse : CompositeFormat | provenance | Config | +| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | provenance | | +| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | provenance | | +| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | provenance | | +| FormatMissingArgument.cs:37:24:37:54 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:37:24:37:54 | call to method Parse : CompositeFormat | provenance | Config | +| FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:53:37:53:42 | access to local variable format | provenance | | +| FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:62:31:62:36 | access to local variable format | provenance | | +| FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:63:39:63:44 | access to local variable format | provenance | | +| FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:74:29:74:34 | access to local variable format | provenance | | +| FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:75:37:75:42 | access to local variable format | provenance | | +| FormatUnusedArgument.cs:48:22:48:47 | call to method Parse : CompositeFormat | FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | provenance | | +| FormatUnusedArgument.cs:48:44:48:46 | "X" : String | FormatUnusedArgument.cs:48:22:48:47 | call to method Parse : CompositeFormat | provenance | Config | +| FormatUnusedArgument.cs:49:13:49:20 | access to local variable format00 : CompositeFormat | FormatUnusedArgument.cs:56:45:56:52 | access to local variable format00 | provenance | | +| FormatUnusedArgument.cs:49:13:49:20 | access to local variable format00 : CompositeFormat | FormatUnusedArgument.cs:66:47:66:54 | access to local variable format00 | provenance | | +| FormatUnusedArgument.cs:49:13:49:20 | access to local variable format00 : CompositeFormat | FormatUnusedArgument.cs:78:45:78:52 | access to local variable format00 | provenance | | +| FormatUnusedArgument.cs:49:24:49:54 | call to method Parse : CompositeFormat | FormatUnusedArgument.cs:49:13:49:20 | access to local variable format00 : CompositeFormat | provenance | | +| FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" : String | FormatUnusedArgument.cs:49:24:49:54 | call to method Parse : CompositeFormat | provenance | Config | +| FormatUnusedArgument.cs:50:13:50:20 | access to local variable format11 : CompositeFormat | FormatUnusedArgument.cs:59:45:59:52 | access to local variable format11 | provenance | | +| FormatUnusedArgument.cs:50:13:50:20 | access to local variable format11 : CompositeFormat | FormatUnusedArgument.cs:69:47:69:54 | access to local variable format11 | provenance | | +| FormatUnusedArgument.cs:50:13:50:20 | access to local variable format11 : CompositeFormat | FormatUnusedArgument.cs:81:45:81:52 | access to local variable format11 | provenance | | +| FormatUnusedArgument.cs:50:24:50:54 | call to method Parse : CompositeFormat | FormatUnusedArgument.cs:50:13:50:20 | access to local variable format11 : CompositeFormat | provenance | | +| FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" : String | FormatUnusedArgument.cs:50:24:50:54 | call to method Parse : CompositeFormat | provenance | Config | nodes | FormatInvalid.cs:10:23:10:27 | "{0}" | semmle.label | "{0}" | +| FormatInvalid.cs:10:23:10:27 | "{0}" | semmle.label | "{0}" | | FormatInvalid.cs:13:23:13:29 | "{0,1}" | semmle.label | "{0,1}" | +| FormatInvalid.cs:13:23:13:29 | "{0,1}" | semmle.label | "{0,1}" | +| FormatInvalid.cs:16:23:16:31 | "{0, 1}" | semmle.label | "{0, 1}" | | FormatInvalid.cs:16:23:16:31 | "{0, 1}" | semmle.label | "{0, 1}" | | FormatInvalid.cs:19:23:19:30 | "{0,-1}" | semmle.label | "{0,-1}" | +| FormatInvalid.cs:19:23:19:30 | "{0,-1}" | semmle.label | "{0,-1}" | | FormatInvalid.cs:22:23:22:33 | "{0:0.000}" | semmle.label | "{0:0.000}" | +| FormatInvalid.cs:22:23:22:33 | "{0:0.000}" | semmle.label | "{0:0.000}" | +| FormatInvalid.cs:25:23:25:39 | "{0, -10 :0.000}" | semmle.label | "{0, -10 :0.000}" | | FormatInvalid.cs:25:23:25:39 | "{0, -10 :0.000}" | semmle.label | "{0, -10 :0.000}" | | FormatInvalid.cs:28:23:28:28 | "{ 0}" | semmle.label | "{ 0}" | +| FormatInvalid.cs:28:23:28:28 | "{ 0}" | semmle.label | "{ 0}" | | FormatInvalid.cs:31:23:31:31 | "{0,--1}" | semmle.label | "{0,--1}" | +| FormatInvalid.cs:31:23:31:31 | "{0,--1}" | semmle.label | "{0,--1}" | +| FormatInvalid.cs:34:23:34:30 | "{0:{}}" | semmle.label | "{0:{}}" | | FormatInvalid.cs:34:23:34:30 | "{0:{}}" | semmle.label | "{0:{}}" | | FormatInvalid.cs:37:23:37:26 | "%d" | semmle.label | "%d" | +| FormatInvalid.cs:37:23:37:26 | "%d" | semmle.label | "%d" | +| FormatInvalid.cs:40:23:40:33 | "{{0}-{1}}" | semmle.label | "{{0}-{1}}" | | FormatInvalid.cs:40:23:40:33 | "{{0}-{1}}" | semmle.label | "{{0}-{1}}" | | FormatInvalid.cs:43:23:43:28 | "{0}}" | semmle.label | "{0}}" | +| FormatInvalid.cs:43:23:43:28 | "{0}}" | semmle.label | "{0}}" | | FormatInvalid.cs:46:23:46:32 | "{foo{0}}" | semmle.label | "{foo{0}}" | +| FormatInvalid.cs:46:23:46:32 | "{foo{0}}" | semmle.label | "{foo{0}}" | +| FormatInvalid.cs:49:23:49:34 | "{{sdc}}{0}" | semmle.label | "{{sdc}}{0}" | | FormatInvalid.cs:49:23:49:34 | "{{sdc}}{0}" | semmle.label | "{{sdc}}{0}" | | FormatInvalid.cs:52:23:52:28 | "}{0}" | semmle.label | "}{0}" | +| FormatInvalid.cs:52:23:52:28 | "}{0}" | semmle.label | "}{0}" | +| FormatInvalid.cs:55:23:55:42 | "new {0} ({1} => {{" | semmle.label | "new {0} ({1} => {{" | | FormatInvalid.cs:55:23:55:42 | "new {0} ({1} => {{" | semmle.label | "new {0} ({1} => {{" | | FormatInvalid.cs:58:23:58:29 | "{0}{{" | semmle.label | "{0}{{" | +| FormatInvalid.cs:58:23:58:29 | "{0}{{" | semmle.label | "{0}{{" | | FormatInvalid.cs:59:23:59:33 | "{0}{{{{}}" | semmle.label | "{0}{{{{}}" | +| FormatInvalid.cs:59:23:59:33 | "{0}{{{{}}" | semmle.label | "{0}{{{{}}" | +| FormatInvalid.cs:76:23:76:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:76:23:76:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:77:23:77:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:77:23:77:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:78:23:78:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:78:23:78:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:79:27:79:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:79:27:79:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:80:23:80:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:80:23:80:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:81:23:81:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:81:23:81:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:82:23:82:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:82:23:82:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:84:25:84:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:84:25:84:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:85:25:85:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:85:25:85:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:86:25:86:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:86:25:86:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:87:29:87:31 | "}" | semmle.label | "}" | +| FormatInvalid.cs:87:29:87:31 | "}" | semmle.label | "}" | +| FormatInvalid.cs:88:25:88:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:88:25:88:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:89:25:89:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:89:25:89:27 | "}" | semmle.label | "}" | +| FormatInvalid.cs:90:25:90:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:90:25:90:27 | "}" | semmle.label | "}" | | FormatInvalid.cs:92:27:92:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:92:27:92:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:93:27:93:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:93:27:93:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:94:27:94:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:94:27:94:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:95:27:95:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:95:27:95:29 | "}" | semmle.label | "}" | +| FormatInvalid.cs:96:27:96:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:96:27:96:29 | "}" | semmle.label | "}" | | FormatInvalid.cs:98:22:98:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:98:22:98:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:99:22:99:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:99:22:99:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:100:22:100:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:100:22:100:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:101:22:101:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:101:22:101:24 | "}" | semmle.label | "}" | +| FormatInvalid.cs:102:22:102:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:102:22:102:24 | "}" | semmle.label | "}" | | FormatInvalid.cs:104:44:104:46 | "}" | semmle.label | "}" | +| FormatInvalid.cs:104:44:104:46 | "}" | semmle.label | "}" | | FormatInvalid.cs:105:45:105:47 | "}" | semmle.label | "}" | +| FormatInvalid.cs:105:45:105:47 | "}" | semmle.label | "}" | +| FormatInvalid.cs:106:51:106:53 | "}" | semmle.label | "}" | | FormatInvalid.cs:106:51:106:53 | "}" | semmle.label | "}" | | FormatInvalid.cs:107:47:107:49 | "}" | semmle.label | "}" | +| FormatInvalid.cs:107:47:107:49 | "}" | semmle.label | "}" | | FormatInvalid.cs:108:29:108:31 | "}" | semmle.label | "}" | +| FormatInvalid.cs:108:29:108:31 | "}" | semmle.label | "}" | +| FormatInvalid.cs:110:23:110:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:110:23:110:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:111:23:111:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:111:23:111:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:112:23:112:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:112:23:112:25 | "}" | semmle.label | "}" | +| FormatInvalid.cs:113:23:113:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:113:23:113:25 | "}" | semmle.label | "}" | | FormatInvalid.cs:118:56:118:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | +| FormatInvalid.cs:118:56:118:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | +| FormatInvalid.cs:119:18:119:20 | "}" | semmle.label | "}" | | FormatInvalid.cs:119:18:119:20 | "}" | semmle.label | "}" | | FormatInvalid.cs:120:40:120:42 | "}" | semmle.label | "}" | +| FormatInvalid.cs:120:40:120:42 | "}" | semmle.label | "}" | +| FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | semmle.label | access to local variable format : CompositeFormat | +| FormatInvalid.cs:140:22:140:47 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatInvalid.cs:140:44:140:46 | "}" | semmle.label | "}" | +| FormatInvalid.cs:140:44:140:46 | "}" : String | semmle.label | "}" : String | +| FormatInvalid.cs:143:37:143:42 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:144:45:144:50 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:145:53:145:58 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:147:31:147:36 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:148:39:148:44 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:149:47:149:52 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:150:55:150:60 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:154:29:154:34 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:155:37:155:42 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:156:45:156:50 | access to local variable format | semmle.label | access to local variable format | +| FormatInvalid.cs:157:53:157:58 | access to local variable format | semmle.label | access to local variable format | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | semmle.label | "class {0} { }" | +| FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | semmle.label | "class {0} { }" | +| FormatInvalidGood.cs:7:30:7:46 | "class {0} {{ }}" | semmle.label | "class {0} {{ }}" | | FormatInvalidGood.cs:7:30:7:46 | "class {0} {{ }}" | semmle.label | "class {0} {{ }}" | | FormatMissingArgument.cs:9:23:9:27 | "{0}" | semmle.label | "{0}" | +| FormatMissingArgument.cs:9:23:9:27 | "{0}" | semmle.label | "{0}" | +| FormatMissingArgument.cs:12:23:12:27 | "{1}" | semmle.label | "{1}" | | FormatMissingArgument.cs:12:23:12:27 | "{1}" | semmle.label | "{1}" | | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | semmle.label | "{2} {3}" | +| FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | semmle.label | "{2} {3}" | | FormatMissingArgument.cs:18:23:18:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatMissingArgument.cs:18:23:18:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatMissingArgument.cs:21:23:21:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | | FormatMissingArgument.cs:21:23:21:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:26:24:26:29 | format : String | semmle.label | format : String | | FormatMissingArgument.cs:26:24:26:29 | format : String | semmle.label | format : String | | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | semmle.label | access to parameter format | +| FormatMissingArgument.cs:29:23:29:28 | access to parameter format | semmle.label | access to parameter format | +| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | semmle.label | access to local variable format0 : CompositeFormat | +| FormatMissingArgument.cs:34:23:34:50 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:34:45:34:49 | "{0}" | semmle.label | "{0}" | +| FormatMissingArgument.cs:34:45:34:49 | "{0}" : String | semmle.label | "{0}" : String | +| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | semmle.label | access to local variable format1 : CompositeFormat | +| FormatMissingArgument.cs:35:23:35:50 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:35:45:35:49 | "{1}" | semmle.label | "{1}" | +| FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | semmle.label | access to local variable format01 : CompositeFormat | +| FormatMissingArgument.cs:36:24:36:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:36:46:36:53 | "{0}{1}" | semmle.label | "{0}{1}" | +| FormatMissingArgument.cs:36:46:36:53 | "{0}{1}" : String | semmle.label | "{0}{1}" : String | +| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | semmle.label | access to local variable format23 : CompositeFormat | +| FormatMissingArgument.cs:37:24:37:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | semmle.label | "{2}{3}" | +| FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | semmle.label | "{2}{3}" : String | +| FormatMissingArgument.cs:40:37:40:43 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:46:45:46:52 | access to local variable format01 | semmle.label | access to local variable format01 | +| FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | semmle.label | access to local variable format23 | +| FormatMissingArgument.cs:53:31:53:37 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:54:39:54:45 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:61:47:61:54 | access to local variable format01 | semmle.label | access to local variable format01 | +| FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | semmle.label | access to local variable format23 | +| FormatMissingArgument.cs:70:29:70:35 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:71:37:71:43 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:78:45:78:52 | access to local variable format01 | semmle.label | access to local variable format01 | +| FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | semmle.label | access to local variable format23 | | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | +| FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | +| FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" | | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" | | FormatMissingArgumentGood.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | +| FormatMissingArgumentGood.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | | FormatUnusedArgument.cs:9:23:9:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatUnusedArgument.cs:9:23:9:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatUnusedArgument.cs:12:23:12:25 | "X" | semmle.label | "X" | | FormatUnusedArgument.cs:12:23:12:25 | "X" | semmle.label | "X" | | FormatUnusedArgument.cs:15:23:15:27 | "{0}" | semmle.label | "{0}" | +| FormatUnusedArgument.cs:15:23:15:27 | "{0}" | semmle.label | "{0}" | | FormatUnusedArgument.cs:18:23:18:31 | "{0} {0}" | semmle.label | "{0} {0}" | +| FormatUnusedArgument.cs:18:23:18:31 | "{0} {0}" | semmle.label | "{0} {0}" | +| FormatUnusedArgument.cs:21:23:21:31 | "{1} {1}" | semmle.label | "{1} {1}" | | FormatUnusedArgument.cs:21:23:21:31 | "{1} {1}" | semmle.label | "{1} {1}" | | FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | semmle.label | "abcdefg" | +| FormatUnusedArgument.cs:24:23:24:31 | "abcdefg" | semmle.label | "abcdefg" | +| FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | | FormatUnusedArgument.cs:27:23:27:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | | FormatUnusedArgument.cs:30:23:30:33 | "{{{0:D}}}" | semmle.label | "{{{0:D}}}" | +| FormatUnusedArgument.cs:30:23:30:33 | "{{{0:D}}}" | semmle.label | "{{{0:D}}}" | | FormatUnusedArgument.cs:33:23:33:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatUnusedArgument.cs:33:23:33:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatUnusedArgument.cs:36:23:36:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | | FormatUnusedArgument.cs:36:23:36:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | | FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | semmle.label | "{{0}}" | +| FormatUnusedArgument.cs:39:23:39:29 | "{{0}}" | semmle.label | "{{0}}" | +| FormatUnusedArgument.cs:43:23:43:24 | "" | semmle.label | "" | | FormatUnusedArgument.cs:43:23:43:24 | "" | semmle.label | "" | +| FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | semmle.label | access to local variable format : CompositeFormat | +| FormatUnusedArgument.cs:48:22:48:47 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatUnusedArgument.cs:48:44:48:46 | "X" | semmle.label | "X" | +| FormatUnusedArgument.cs:48:44:48:46 | "X" : String | semmle.label | "X" : String | +| FormatUnusedArgument.cs:49:13:49:20 | access to local variable format00 : CompositeFormat | semmle.label | access to local variable format00 : CompositeFormat | +| FormatUnusedArgument.cs:49:24:49:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" | semmle.label | "{0}{0}" | +| FormatUnusedArgument.cs:49:46:49:53 | "{0}{0}" : String | semmle.label | "{0}{0}" : String | +| FormatUnusedArgument.cs:50:13:50:20 | access to local variable format11 : CompositeFormat | semmle.label | access to local variable format11 : CompositeFormat | +| FormatUnusedArgument.cs:50:24:50:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" | semmle.label | "{1}{1}" | +| FormatUnusedArgument.cs:50:46:50:53 | "{1}{1}" : String | semmle.label | "{1}{1}" : String | +| FormatUnusedArgument.cs:53:37:53:42 | access to local variable format | semmle.label | access to local variable format | +| FormatUnusedArgument.cs:56:45:56:52 | access to local variable format00 | semmle.label | access to local variable format00 | +| FormatUnusedArgument.cs:59:45:59:52 | access to local variable format11 | semmle.label | access to local variable format11 | +| FormatUnusedArgument.cs:62:31:62:36 | access to local variable format | semmle.label | access to local variable format | +| FormatUnusedArgument.cs:63:39:63:44 | access to local variable format | semmle.label | access to local variable format | +| FormatUnusedArgument.cs:66:47:66:54 | access to local variable format00 | semmle.label | access to local variable format00 | +| FormatUnusedArgument.cs:69:47:69:54 | access to local variable format11 | semmle.label | access to local variable format11 | +| FormatUnusedArgument.cs:74:29:74:34 | access to local variable format | semmle.label | access to local variable format | +| FormatUnusedArgument.cs:75:37:75:42 | access to local variable format | semmle.label | access to local variable format | +| FormatUnusedArgument.cs:78:45:78:52 | access to local variable format00 | semmle.label | access to local variable format00 | +| FormatUnusedArgument.cs:81:45:81:52 | access to local variable format11 | semmle.label | access to local variable format11 | +| FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | semmle.label | "Error processing file: {0}" | | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | semmle.label | "Error processing file: {0}" | | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | +| FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | +| FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | subpaths -testFailures -| FormatInvalid.cs:140:50:140:59 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:35:53:35:63 | // ... | Missing result: Source | -| FormatMissingArgument.cs:37:57:37:67 | // ... | Missing result: Source | -| FormatMissingArgument.cs:43:51:43:65 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:43:51:43:65 | // ... | Missing result: Sink | -| FormatMissingArgument.cs:49:64:49:78 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:49:64:49:78 | // ... | Missing result: Sink | -| FormatMissingArgument.cs:57:45:57:59 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:57:45:57:59 | // ... | Missing result: Sink | -| FormatMissingArgument.cs:58:53:58:67 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:58:53:58:67 | // ... | Missing result: Sink | -| FormatMissingArgument.cs:64:66:64:80 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:64:66:64:80 | // ... | Missing result: Sink | -| FormatMissingArgument.cs:74:50:74:64 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:74:50:74:64 | // ... | Missing result: Sink | -| FormatMissingArgument.cs:75:58:75:72 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:75:58:75:72 | // ... | Missing result: Sink | -| FormatMissingArgument.cs:81:71:81:85 | // ... | Missing result: Alert | -| FormatMissingArgument.cs:81:71:81:85 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:48:50:48:60 | // ... | Missing result: Source | -| FormatUnusedArgument.cs:49:57:49:67 | // ... | Missing result: Source | -| FormatUnusedArgument.cs:50:57:50:67 | // ... | Missing result: Source | -| FormatUnusedArgument.cs:53:50:53:64 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:53:50:53:64 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:56:64:56:78 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:56:64:56:78 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:59:64:59:78 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:59:64:59:78 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:62:44:62:58 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:62:44:62:58 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:63:52:63:66 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:63:52:63:66 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:66:66:66:80 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:66:66:66:80 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:69:66:69:80 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:69:66:69:80 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:74:49:74:63 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:74:49:74:63 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:75:57:75:71 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:75:57:75:71 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:78:71:78:85 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:78:71:78:85 | // ... | Missing result: Sink | -| FormatUnusedArgument.cs:81:71:81:85 | // ... | Missing result: Alert | -| FormatUnusedArgument.cs:81:71:81:85 | // ... | Missing result: Sink | From 9f961ed9e4232dd55f87dab612bbba378e0024af Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 9 Apr 2025 16:16:35 +0200 Subject: [PATCH 11/21] C#: Add FP for string.Format using params collection. --- .../FormatInvalid/FormatInvalid.expected | 192 +++++++++--------- .../FormatInvalid/FormatMissingArgument.cs | 3 + 2 files changed, 103 insertions(+), 92 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index ddbdd5c4fb5a..566e47ac0e06 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -51,30 +51,32 @@ | FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | | FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | format string | FormatMissingArgument.cs:15:34:15:34 | (...) ... | this supplied value | | FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | format string | FormatMissingArgument.cs:15:37:15:37 | (...) ... | this supplied value | -| FormatMissingArgument.cs:29:9:29:32 | call to method Format | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:23:16:23:20 | "{1}" | this | FormatMissingArgument.cs:23:16:23:20 | "{1}" | this | -| FormatMissingArgument.cs:29:9:29:32 | call to method Format | FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:23:16:23:20 | "{1}" | format string | FormatMissingArgument.cs:29:31:29:31 | (...) ... | this supplied value | -| FormatMissingArgument.cs:43:9:43:48 | call to method Format | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | -| FormatMissingArgument.cs:43:9:43:48 | call to method Format | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:43:46:43:47 | "" | this supplied value | -| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | -| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | -| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:49:55:49:56 | "" | this supplied value | -| FormatMissingArgument.cs:49:9:49:61 | call to method Format | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:49:59:49:60 | "" | this supplied value | -| FormatMissingArgument.cs:57:9:57:42 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | -| FormatMissingArgument.cs:57:9:57:42 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:57:40:57:41 | "" | this supplied value | -| FormatMissingArgument.cs:58:9:58:50 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | -| FormatMissingArgument.cs:58:9:58:50 | call to method AppendFormat | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:58:48:58:49 | "" | this supplied value | -| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | -| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | -| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:64:57:64:58 | "" | this supplied value | -| FormatMissingArgument.cs:64:9:64:63 | call to method AppendFormat | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:64:61:64:62 | "" | this supplied value | -| FormatMissingArgument.cs:74:9:74:47 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | -| FormatMissingArgument.cs:74:9:74:47 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:74:45:74:46 | "" | this supplied value | -| FormatMissingArgument.cs:75:9:75:55 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | FormatMissingArgument.cs:35:45:35:49 | "{1}" | this | -| FormatMissingArgument.cs:75:9:75:55 | call to method TryWrite | FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:35:45:35:49 | "{1}" | format string | FormatMissingArgument.cs:75:53:75:54 | "" | this supplied value | -| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | -| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | this | -| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:81:62:81:63 | "" | this supplied value | -| FormatMissingArgument.cs:81:9:81:68 | call to method TryWrite | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | format string | FormatMissingArgument.cs:81:66:81:67 | "" | this supplied value | +| FormatMissingArgument.cs:21:9:21:47 | call to method Format | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | +| FormatMissingArgument.cs:21:9:21:47 | call to method Format | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | +| FormatMissingArgument.cs:32:9:32:32 | call to method Format | FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | FormatMissingArgument.cs:32:23:32:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:26:16:26:20 | "{1}" | this | FormatMissingArgument.cs:26:16:26:20 | "{1}" | this | +| FormatMissingArgument.cs:32:9:32:32 | call to method Format | FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | FormatMissingArgument.cs:32:23:32:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:26:16:26:20 | "{1}" | format string | FormatMissingArgument.cs:32:31:32:31 | (...) ... | this supplied value | +| FormatMissingArgument.cs:46:9:46:48 | call to method Format | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:46:37:46:43 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | +| FormatMissingArgument.cs:46:9:46:48 | call to method Format | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:46:37:46:43 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | format string | FormatMissingArgument.cs:46:46:46:47 | "" | this supplied value | +| FormatMissingArgument.cs:52:9:52:61 | call to method Format | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:52:45:52:52 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:52:9:52:61 | call to method Format | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:52:45:52:52 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:52:9:52:61 | call to method Format | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:52:45:52:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | format string | FormatMissingArgument.cs:52:55:52:56 | "" | this supplied value | +| FormatMissingArgument.cs:52:9:52:61 | call to method Format | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:52:45:52:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | format string | FormatMissingArgument.cs:52:59:52:60 | "" | this supplied value | +| FormatMissingArgument.cs:60:9:60:42 | call to method AppendFormat | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:60:31:60:37 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | +| FormatMissingArgument.cs:60:9:60:42 | call to method AppendFormat | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:60:31:60:37 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | format string | FormatMissingArgument.cs:60:40:60:41 | "" | this supplied value | +| FormatMissingArgument.cs:61:9:61:50 | call to method AppendFormat | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:61:39:61:45 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | +| FormatMissingArgument.cs:61:9:61:50 | call to method AppendFormat | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:61:39:61:45 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | format string | FormatMissingArgument.cs:61:48:61:49 | "" | this supplied value | +| FormatMissingArgument.cs:67:9:67:63 | call to method AppendFormat | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:67:47:67:54 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:67:9:67:63 | call to method AppendFormat | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:67:47:67:54 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:67:9:67:63 | call to method AppendFormat | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:67:47:67:54 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | format string | FormatMissingArgument.cs:67:57:67:58 | "" | this supplied value | +| FormatMissingArgument.cs:67:9:67:63 | call to method AppendFormat | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:67:47:67:54 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | format string | FormatMissingArgument.cs:67:61:67:62 | "" | this supplied value | +| FormatMissingArgument.cs:77:9:77:47 | call to method TryWrite | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:77:29:77:35 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | +| FormatMissingArgument.cs:77:9:77:47 | call to method TryWrite | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:77:29:77:35 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | format string | FormatMissingArgument.cs:77:45:77:46 | "" | this supplied value | +| FormatMissingArgument.cs:78:9:78:55 | call to method TryWrite | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:78:37:78:43 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | +| FormatMissingArgument.cs:78:9:78:55 | call to method TryWrite | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:78:37:78:43 | access to local variable format1 | The $@ ignores $@. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | format string | FormatMissingArgument.cs:78:53:78:54 | "" | this supplied value | +| FormatMissingArgument.cs:84:9:84:68 | call to method TryWrite | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:84:45:84:52 | access to local variable format23 | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:84:9:84:68 | call to method TryWrite | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:84:45:84:52 | access to local variable format23 | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | this | +| FormatMissingArgument.cs:84:9:84:68 | call to method TryWrite | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:84:45:84:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | format string | FormatMissingArgument.cs:84:62:84:63 | "" | this supplied value | +| FormatMissingArgument.cs:84:9:84:68 | call to method TryWrite | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:84:45:84:52 | access to local variable format23 | The $@ ignores $@. | FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | format string | FormatMissingArgument.cs:84:66:84:67 | "" | this supplied value | | FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | | FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | The $@ ignores $@. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | format string | FormatMissingArgumentBad.cs:8:44:8:48 | access to parameter first | this supplied value | @@ -116,34 +118,34 @@ edges | FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | FormatInvalid.cs:157:53:157:58 | access to local variable format | provenance | | | FormatInvalid.cs:140:22:140:47 | call to method Parse : CompositeFormat | FormatInvalid.cs:140:13:140:18 | access to local variable format : CompositeFormat | provenance | | | FormatInvalid.cs:140:44:140:46 | "}" : String | FormatInvalid.cs:140:22:140:47 | call to method Parse : CompositeFormat | provenance | Config | -| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:26:24:26:29 | format : String | provenance | | -| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | FormatMissingArgument.cs:26:24:26:29 | format : String | provenance | | -| FormatMissingArgument.cs:26:24:26:29 | format : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | provenance | | -| FormatMissingArgument.cs:26:24:26:29 | format : String | FormatMissingArgument.cs:29:23:29:28 | access to parameter format | provenance | | -| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:40:37:40:43 | access to local variable format0 | provenance | | -| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:53:31:53:37 | access to local variable format0 | provenance | | -| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:54:39:54:45 | access to local variable format0 | provenance | | -| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:70:29:70:35 | access to local variable format0 | provenance | | -| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:71:37:71:43 | access to local variable format0 | provenance | | -| FormatMissingArgument.cs:34:23:34:50 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | provenance | | -| FormatMissingArgument.cs:34:45:34:49 | "{0}" : String | FormatMissingArgument.cs:34:23:34:50 | call to method Parse : CompositeFormat | provenance | Config | -| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | provenance | | -| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | provenance | | -| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | provenance | | -| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | provenance | | -| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | provenance | | -| FormatMissingArgument.cs:35:23:35:50 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | provenance | | -| FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | FormatMissingArgument.cs:35:23:35:50 | call to method Parse : CompositeFormat | provenance | Config | -| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:46:45:46:52 | access to local variable format01 | provenance | | -| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:61:47:61:54 | access to local variable format01 | provenance | | -| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:78:45:78:52 | access to local variable format01 | provenance | | -| FormatMissingArgument.cs:36:24:36:54 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | provenance | | -| FormatMissingArgument.cs:36:46:36:53 | "{0}{1}" : String | FormatMissingArgument.cs:36:24:36:54 | call to method Parse : CompositeFormat | provenance | Config | -| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | provenance | | -| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | provenance | | -| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | provenance | | -| FormatMissingArgument.cs:37:24:37:54 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | provenance | | -| FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | FormatMissingArgument.cs:37:24:37:54 | call to method Parse : CompositeFormat | provenance | Config | +| FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | FormatMissingArgument.cs:29:24:29:29 | format : String | provenance | | +| FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | FormatMissingArgument.cs:29:24:29:29 | format : String | provenance | | +| FormatMissingArgument.cs:29:24:29:29 | format : String | FormatMissingArgument.cs:32:23:32:28 | access to parameter format | provenance | | +| FormatMissingArgument.cs:29:24:29:29 | format : String | FormatMissingArgument.cs:32:23:32:28 | access to parameter format | provenance | | +| FormatMissingArgument.cs:37:13:37:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:43:37:43:43 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:37:13:37:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:56:31:56:37 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:37:13:37:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:57:39:57:45 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:37:13:37:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:73:29:73:35 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:37:13:37:19 | access to local variable format0 : CompositeFormat | FormatMissingArgument.cs:74:37:74:43 | access to local variable format0 | provenance | | +| FormatMissingArgument.cs:37:23:37:50 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:37:13:37:19 | access to local variable format0 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:37:45:37:49 | "{0}" : String | FormatMissingArgument.cs:37:23:37:50 | call to method Parse : CompositeFormat | provenance | Config | +| FormatMissingArgument.cs:38:13:38:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:46:37:46:43 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:38:13:38:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:60:31:60:37 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:38:13:38:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:61:39:61:45 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:38:13:38:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:77:29:77:35 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:38:13:38:19 | access to local variable format1 : CompositeFormat | FormatMissingArgument.cs:78:37:78:43 | access to local variable format1 | provenance | | +| FormatMissingArgument.cs:38:23:38:50 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:38:13:38:19 | access to local variable format1 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:38:23:38:50 | call to method Parse : CompositeFormat | provenance | Config | +| FormatMissingArgument.cs:39:13:39:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:49:45:49:52 | access to local variable format01 | provenance | | +| FormatMissingArgument.cs:39:13:39:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:64:47:64:54 | access to local variable format01 | provenance | | +| FormatMissingArgument.cs:39:13:39:20 | access to local variable format01 : CompositeFormat | FormatMissingArgument.cs:81:45:81:52 | access to local variable format01 | provenance | | +| FormatMissingArgument.cs:39:24:39:54 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:39:13:39:20 | access to local variable format01 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:39:46:39:53 | "{0}{1}" : String | FormatMissingArgument.cs:39:24:39:54 | call to method Parse : CompositeFormat | provenance | Config | +| FormatMissingArgument.cs:40:13:40:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:52:45:52:52 | access to local variable format23 | provenance | | +| FormatMissingArgument.cs:40:13:40:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:67:47:67:54 | access to local variable format23 | provenance | | +| FormatMissingArgument.cs:40:13:40:20 | access to local variable format23 : CompositeFormat | FormatMissingArgument.cs:84:45:84:52 | access to local variable format23 | provenance | | +| FormatMissingArgument.cs:40:24:40:54 | call to method Parse : CompositeFormat | FormatMissingArgument.cs:40:13:40:20 | access to local variable format23 : CompositeFormat | provenance | | +| FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | FormatMissingArgument.cs:40:24:40:54 | call to method Parse : CompositeFormat | provenance | Config | | FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:53:37:53:42 | access to local variable format | provenance | | | FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:62:31:62:36 | access to local variable format | provenance | | | FormatUnusedArgument.cs:48:13:48:18 | access to local variable format : CompositeFormat | FormatUnusedArgument.cs:63:39:63:44 | access to local variable format | provenance | | @@ -297,46 +299,48 @@ nodes | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | semmle.label | "{2} {3}" | | FormatMissingArgument.cs:18:23:18:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | | FormatMissingArgument.cs:18:23:18:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | -| FormatMissingArgument.cs:21:23:21:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | -| FormatMissingArgument.cs:21:23:21:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | -| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | semmle.label | "{1}" : String | -| FormatMissingArgument.cs:23:16:23:20 | "{1}" : String | semmle.label | "{1}" : String | -| FormatMissingArgument.cs:26:24:26:29 | format : String | semmle.label | format : String | -| FormatMissingArgument.cs:26:24:26:29 | format : String | semmle.label | format : String | -| FormatMissingArgument.cs:29:23:29:28 | access to parameter format | semmle.label | access to parameter format | -| FormatMissingArgument.cs:29:23:29:28 | access to parameter format | semmle.label | access to parameter format | -| FormatMissingArgument.cs:34:13:34:19 | access to local variable format0 : CompositeFormat | semmle.label | access to local variable format0 : CompositeFormat | -| FormatMissingArgument.cs:34:23:34:50 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | -| FormatMissingArgument.cs:34:45:34:49 | "{0}" | semmle.label | "{0}" | -| FormatMissingArgument.cs:34:45:34:49 | "{0}" : String | semmle.label | "{0}" : String | -| FormatMissingArgument.cs:35:13:35:19 | access to local variable format1 : CompositeFormat | semmle.label | access to local variable format1 : CompositeFormat | -| FormatMissingArgument.cs:35:23:35:50 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | -| FormatMissingArgument.cs:35:45:35:49 | "{1}" | semmle.label | "{1}" | -| FormatMissingArgument.cs:35:45:35:49 | "{1}" : String | semmle.label | "{1}" : String | -| FormatMissingArgument.cs:36:13:36:20 | access to local variable format01 : CompositeFormat | semmle.label | access to local variable format01 : CompositeFormat | -| FormatMissingArgument.cs:36:24:36:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | -| FormatMissingArgument.cs:36:46:36:53 | "{0}{1}" | semmle.label | "{0}{1}" | -| FormatMissingArgument.cs:36:46:36:53 | "{0}{1}" : String | semmle.label | "{0}{1}" : String | -| FormatMissingArgument.cs:37:13:37:20 | access to local variable format23 : CompositeFormat | semmle.label | access to local variable format23 : CompositeFormat | -| FormatMissingArgument.cs:37:24:37:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | -| FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" | semmle.label | "{2}{3}" | -| FormatMissingArgument.cs:37:46:37:53 | "{2}{3}" : String | semmle.label | "{2}{3}" : String | -| FormatMissingArgument.cs:40:37:40:43 | access to local variable format0 | semmle.label | access to local variable format0 | -| FormatMissingArgument.cs:43:37:43:43 | access to local variable format1 | semmle.label | access to local variable format1 | -| FormatMissingArgument.cs:46:45:46:52 | access to local variable format01 | semmle.label | access to local variable format01 | -| FormatMissingArgument.cs:49:45:49:52 | access to local variable format23 | semmle.label | access to local variable format23 | -| FormatMissingArgument.cs:53:31:53:37 | access to local variable format0 | semmle.label | access to local variable format0 | -| FormatMissingArgument.cs:54:39:54:45 | access to local variable format0 | semmle.label | access to local variable format0 | -| FormatMissingArgument.cs:57:31:57:37 | access to local variable format1 | semmle.label | access to local variable format1 | -| FormatMissingArgument.cs:58:39:58:45 | access to local variable format1 | semmle.label | access to local variable format1 | -| FormatMissingArgument.cs:61:47:61:54 | access to local variable format01 | semmle.label | access to local variable format01 | -| FormatMissingArgument.cs:64:47:64:54 | access to local variable format23 | semmle.label | access to local variable format23 | -| FormatMissingArgument.cs:70:29:70:35 | access to local variable format0 | semmle.label | access to local variable format0 | -| FormatMissingArgument.cs:71:37:71:43 | access to local variable format0 | semmle.label | access to local variable format0 | -| FormatMissingArgument.cs:74:29:74:35 | access to local variable format1 | semmle.label | access to local variable format1 | -| FormatMissingArgument.cs:75:37:75:43 | access to local variable format1 | semmle.label | access to local variable format1 | -| FormatMissingArgument.cs:78:45:78:52 | access to local variable format01 | semmle.label | access to local variable format01 | -| FormatMissingArgument.cs:81:45:81:52 | access to local variable format23 | semmle.label | access to local variable format23 | +| FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatMissingArgument.cs:24:23:24:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatMissingArgument.cs:24:23:24:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:29:24:29:29 | format : String | semmle.label | format : String | +| FormatMissingArgument.cs:29:24:29:29 | format : String | semmle.label | format : String | +| FormatMissingArgument.cs:32:23:32:28 | access to parameter format | semmle.label | access to parameter format | +| FormatMissingArgument.cs:32:23:32:28 | access to parameter format | semmle.label | access to parameter format | +| FormatMissingArgument.cs:37:13:37:19 | access to local variable format0 : CompositeFormat | semmle.label | access to local variable format0 : CompositeFormat | +| FormatMissingArgument.cs:37:23:37:50 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:37:45:37:49 | "{0}" | semmle.label | "{0}" | +| FormatMissingArgument.cs:37:45:37:49 | "{0}" : String | semmle.label | "{0}" : String | +| FormatMissingArgument.cs:38:13:38:19 | access to local variable format1 : CompositeFormat | semmle.label | access to local variable format1 : CompositeFormat | +| FormatMissingArgument.cs:38:23:38:50 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:38:45:38:49 | "{1}" | semmle.label | "{1}" | +| FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:39:13:39:20 | access to local variable format01 : CompositeFormat | semmle.label | access to local variable format01 : CompositeFormat | +| FormatMissingArgument.cs:39:24:39:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:39:46:39:53 | "{0}{1}" | semmle.label | "{0}{1}" | +| FormatMissingArgument.cs:39:46:39:53 | "{0}{1}" : String | semmle.label | "{0}{1}" : String | +| FormatMissingArgument.cs:40:13:40:20 | access to local variable format23 : CompositeFormat | semmle.label | access to local variable format23 : CompositeFormat | +| FormatMissingArgument.cs:40:24:40:54 | call to method Parse : CompositeFormat | semmle.label | call to method Parse : CompositeFormat | +| FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" | semmle.label | "{2}{3}" | +| FormatMissingArgument.cs:40:46:40:53 | "{2}{3}" : String | semmle.label | "{2}{3}" : String | +| FormatMissingArgument.cs:43:37:43:43 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:46:37:46:43 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:49:45:49:52 | access to local variable format01 | semmle.label | access to local variable format01 | +| FormatMissingArgument.cs:52:45:52:52 | access to local variable format23 | semmle.label | access to local variable format23 | +| FormatMissingArgument.cs:56:31:56:37 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:57:39:57:45 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:60:31:60:37 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:61:39:61:45 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:64:47:64:54 | access to local variable format01 | semmle.label | access to local variable format01 | +| FormatMissingArgument.cs:67:47:67:54 | access to local variable format23 | semmle.label | access to local variable format23 | +| FormatMissingArgument.cs:73:29:73:35 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:74:37:74:43 | access to local variable format0 | semmle.label | access to local variable format0 | +| FormatMissingArgument.cs:77:29:77:35 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:78:37:78:43 | access to local variable format1 | semmle.label | access to local variable format1 | +| FormatMissingArgument.cs:81:45:81:52 | access to local variable format01 | semmle.label | access to local variable format01 | +| FormatMissingArgument.cs:84:45:84:52 | access to local variable format23 | semmle.label | access to local variable format23 | | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" | @@ -397,3 +401,7 @@ nodes | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | subpaths +testFailures +| FormatMissingArgument.cs:21:9:21:47 | FormatMissingArgument.cs:21:23:21:35 | Unexpected result: Alert | +| FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Unexpected result: Alert | +| FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Unexpected result: Sink | diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs index d059e7a5400c..52aabd8cf2bd 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs @@ -17,6 +17,9 @@ void TestFormatMissingArgument() // GOOD: An array has been supplied. String.Format("{0} {1} {2}", args); + // GOOD: A collection has been supplied. + String.Format("{0} {1} {2}", [0, 1, 2]); + // GOOD: All arguments supplied to params String.Format("{0} {1} {2} {3}", 0, 1, 2, 3); From 2a21ab08a9d6e01d862f21a247c2563653084990 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 9 Apr 2025 16:18:04 +0200 Subject: [PATCH 12/21] C#: Generalize array logic to params collection like types. --- .../semmle/code/csharp/commons/Collections.qll | 3 ++- .../semmle/code/csharp/frameworks/Format.qll | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll b/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll index 7a881981c1c1..b33c0f73d60d 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll @@ -97,7 +97,8 @@ private class ParamsConstructedCollectionTypes extends ParamsCollectionTypeImpl unboundbase instanceof SystemCollectionsGenericIReadOnlyListTInterface or unboundbase instanceof SystemSpanStruct or unboundbase instanceof SystemReadOnlySpanStruct - ) + ) and + not this instanceof SystemStringClass } override Type getElementType() { result = base.getTypeArgument(0) } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index 7bccf3e0e6bd..eb9d52702631 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -250,19 +250,31 @@ class FormatCall extends MethodCall { /** Holds if this call has one or more insertions. */ predicate hasInsertions() { exists(this.getArgument(this.getFirstArgument())) } - /** Holds if the arguments are supplied in an array, not individually. */ - predicate hasArrayExpr() { + /** + * DEPRECATED: use `hasCollectionExpr` instead. + * + * Holds if the arguments are supplied in an array, not individually. + */ + deprecated predicate hasArrayExpr() { this.getNumberOfArguments() = this.getFirstArgument() + 1 and this.getArgument(this.getFirstArgument()).getType() instanceof ArrayType } + /** + * Holds if the arguments are supplied in a collection, not individually. + */ + predicate hasCollectionExpr() { + this.getNumberOfArguments() = this.getFirstArgument() + 1 and + this.getArgument(this.getFirstArgument()).getType() instanceof ParamsCollectionType + } + /** * Gets the number of supplied arguments (excluding the format string and format * provider). Does not return a value if the arguments are supplied in an array, * in which case we generally can't assess the size of the array. */ int getSuppliedArguments() { - not this.hasArrayExpr() and + not this.hasCollectionExpr() and result = this.getNumberOfArguments() - this.getFirstArgument() } From b17b56144f1a901ca4b8b9a8f1b68c5c60637455 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 9 Apr 2025 16:19:08 +0200 Subject: [PATCH 13/21] C#: Update test expected output. --- .../API Abuse/FormatInvalid/FormatInvalid.expected | 6 ------ 1 file changed, 6 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index 566e47ac0e06..a33793ae461a 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -51,8 +51,6 @@ | FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | this | | FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | format string | FormatMissingArgument.cs:15:34:15:34 | (...) ... | this supplied value | | FormatMissingArgument.cs:15:9:15:38 | call to method Format | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:15:23:15:31 | "{2} {3}" | format string | FormatMissingArgument.cs:15:37:15:37 | (...) ... | this supplied value | -| FormatMissingArgument.cs:21:9:21:47 | call to method Format | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | -| FormatMissingArgument.cs:21:9:21:47 | call to method Format | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | this | | FormatMissingArgument.cs:32:9:32:32 | call to method Format | FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | FormatMissingArgument.cs:32:23:32:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:26:16:26:20 | "{1}" | this | FormatMissingArgument.cs:26:16:26:20 | "{1}" | this | | FormatMissingArgument.cs:32:9:32:32 | call to method Format | FormatMissingArgument.cs:26:16:26:20 | "{1}" : String | FormatMissingArgument.cs:32:23:32:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:26:16:26:20 | "{1}" | format string | FormatMissingArgument.cs:32:31:32:31 | (...) ... | this supplied value | | FormatMissingArgument.cs:46:9:46:48 | call to method Format | FormatMissingArgument.cs:38:45:38:49 | "{1}" : String | FormatMissingArgument.cs:46:37:46:43 | access to local variable format1 | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | FormatMissingArgument.cs:38:45:38:49 | "{1}" | this | @@ -401,7 +399,3 @@ nodes | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | subpaths -testFailures -| FormatMissingArgument.cs:21:9:21:47 | FormatMissingArgument.cs:21:23:21:35 | Unexpected result: Alert | -| FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Unexpected result: Alert | -| FormatMissingArgument.cs:21:23:21:35 | "{0} {1} {2}" | Unexpected result: Sink | From c365ce08a957860e2974855218d45631996db169 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 9 Apr 2025 16:23:37 +0200 Subject: [PATCH 14/21] C#: Hide the abstract FormatMethod class. --- .../lib/semmle/code/csharp/frameworks/Format.qll | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index eb9d52702631..cf61a5d75aab 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -8,7 +8,7 @@ private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.Text /** A method that formats a string, for example `string.Format()`. */ -abstract class FormatMethod extends Method { +abstract private class FormatMethodImpl extends Method { /** * Gets the argument containing the format string. For example, the argument of * `string.Format(IFormatProvider, String, Object)` is `1`. @@ -21,6 +21,8 @@ abstract class FormatMethod extends Method { int getFirstArgument() { result = this.getFormatArgument() + 1 } } +final class FormatMethod = FormatMethodImpl; + /** A class of types used for formatting. */ private class FormatType extends Type { FormatType() { @@ -29,7 +31,7 @@ private class FormatType extends Type { } } -private class StringAndStringBuilderFormatMethods extends FormatMethod { +private class StringAndStringBuilderFormatMethods extends FormatMethodImpl { StringAndStringBuilderFormatMethods() { ( this.getParameter(0).getType() instanceof SystemIFormatProviderInterface and @@ -51,7 +53,7 @@ private class StringAndStringBuilderFormatMethods extends FormatMethod { } } -private class SystemMemoryExtensionsFormatMethods extends FormatMethod { +private class SystemMemoryExtensionsFormatMethods extends FormatMethodImpl { SystemMemoryExtensionsFormatMethods() { this = any(SystemMemoryExtensionsClass c).getTryWriteMethod() and this.getParameter(1).getType() instanceof SystemIFormatProviderInterface and @@ -63,7 +65,7 @@ private class SystemMemoryExtensionsFormatMethods extends FormatMethod { override int getFirstArgument() { result = this.getFormatArgument() + 2 } } -private class SystemConsoleAndSystemIoTextWriterFormatMethods extends FormatMethod { +private class SystemConsoleAndSystemIoTextWriterFormatMethods extends FormatMethodImpl { SystemConsoleAndSystemIoTextWriterFormatMethods() { this.getParameter(0).getType() instanceof StringType and this.getNumberOfParameters() > 1 and @@ -80,7 +82,7 @@ private class SystemConsoleAndSystemIoTextWriterFormatMethods extends FormatMeth override int getFormatArgument() { result = 0 } } -private class SystemDiagnosticsDebugAssert extends FormatMethod { +private class SystemDiagnosticsDebugAssert extends FormatMethodImpl { SystemDiagnosticsDebugAssert() { this.hasName("Assert") and this.getDeclaringType().hasFullyQualifiedName("System.Diagnostics", "Debug") and @@ -90,7 +92,7 @@ private class SystemDiagnosticsDebugAssert extends FormatMethod { override int getFormatArgument() { result = 2 } } -private class SystemDiagnosticsFormatMethods extends FormatMethod { +private class SystemDiagnosticsFormatMethods extends FormatMethodImpl { SystemDiagnosticsFormatMethods() { this.getParameter(0).getType() instanceof StringType and this.getNumberOfParameters() > 1 and From ac43abc1aa66256417ca38175769091a1acdd787 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 9 Apr 2025 16:55:46 +0200 Subject: [PATCH 15/21] C#: Update string format item parameter expected test case. --- .../frameworks/format/StringFormatItemParameter.expected | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected b/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected index 692ec0529bb0..dc3017a5f6f2 100644 --- a/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected +++ b/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected @@ -17,6 +17,12 @@ | Debug | Assert(bool, string, string, params Object[]) | args | | Debug | Print(string, params Object[]) | args | | Debug | WriteLine(string, params Object[]) | args | +| MemoryExtensions | TryWrite(Span, IFormatProvider, CompositeFormat, out int, params Object[]) | args | +| MemoryExtensions | TryWrite(Span, IFormatProvider, CompositeFormat, out int, params Object[]) | charsWritten | +| MemoryExtensions | TryWrite(Span, IFormatProvider, CompositeFormat, out int, params ReadOnlySpan) | args | +| MemoryExtensions | TryWrite(Span, IFormatProvider, CompositeFormat, out int, params ReadOnlySpan) | charsWritten | +| StringBuilder | AppendFormat(IFormatProvider, CompositeFormat, params Object[]) | args | +| StringBuilder | AppendFormat(IFormatProvider, CompositeFormat, params ReadOnlySpan) | args | | StringBuilder | AppendFormat(IFormatProvider, string, object) | arg0 | | StringBuilder | AppendFormat(IFormatProvider, string, object, object) | arg0 | | StringBuilder | AppendFormat(IFormatProvider, string, object, object) | arg1 | @@ -51,6 +57,8 @@ | TextWriter | WriteLine(string, object, object, object) | arg2 | | TextWriter | WriteLine(string, params Object[]) | arg | | TextWriter | WriteLine(string, params ReadOnlySpan) | arg | +| string | Format(IFormatProvider, CompositeFormat, params Object[]) | args | +| string | Format(IFormatProvider, CompositeFormat, params ReadOnlySpan) | args | | string | Format(IFormatProvider, string, object) | arg0 | | string | Format(IFormatProvider, string, object, object) | arg0 | | string | Format(IFormatProvider, string, object, object) | arg1 | From 5c6b1dd85b996f3b2848b57e0612534b53070600 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 10 Apr 2025 08:47:41 +0200 Subject: [PATCH 16/21] C#: Add change note. --- .../ql/src/change-notes/2025-04-10-invalid-string-format.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/src/change-notes/2025-04-10-invalid-string-format.md diff --git a/csharp/ql/src/change-notes/2025-04-10-invalid-string-format.md b/csharp/ql/src/change-notes/2025-04-10-invalid-string-format.md new file mode 100644 index 000000000000..1d1d424d985f --- /dev/null +++ b/csharp/ql/src/change-notes/2025-04-10-invalid-string-format.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The precision of the query `cs/invalid-string-formatting` has been improved. More methods and more overloads of existing format like methods are taken into account by the query. From cfbf94fde0c4e063a08de53d5895a9d9a7bb3632 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 10 Apr 2025 14:13:45 +0200 Subject: [PATCH 17/21] C#: Convert cs/uncontrolled-format-string tests to use test inline expectations. --- .../CWE-134/ConsoleUncontrolledFormatString.cs | 4 ++-- .../Security Features/CWE-134/UncontrolledFormatString.cs | 8 ++++---- .../CWE-134/UncontrolledFormatString.qlref | 4 +++- .../CWE-134/UncontrolledFormatStringBad.cs | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/ConsoleUncontrolledFormatString.cs b/csharp/ql/test/query-tests/Security Features/CWE-134/ConsoleUncontrolledFormatString.cs index c9d4440cf787..c7d8c38a71b4 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/ConsoleUncontrolledFormatString.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/ConsoleUncontrolledFormatString.cs @@ -5,9 +5,9 @@ public class Program { public static void Main() { - var format = Console.ReadLine(); + var format = Console.ReadLine(); // $ Source // BAD: Uncontrolled format string. - var x = string.Format(format, 1, 2); + var x = string.Format(format, 1, 2); // $ Alert } } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs index 37da55bec766..531d4ade8846 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs @@ -6,13 +6,13 @@ public class TaintedPathHandler : IHttpHandler { public void ProcessRequest(HttpContext ctx) { - String path = ctx.Request.QueryString["page"]; + String path = ctx.Request.QueryString["page"]; // $ Source // BAD: Uncontrolled format string. - String.Format(path, "Do not do this"); + String.Format(path, "Do not do this"); // $ Alert // BAD: Using an IFormatProvider. - String.Format((IFormatProvider)null, path, "Do not do this"); + String.Format((IFormatProvider)null, path, "Do not do this"); // $ Alert // GOOD: Not the format string. String.Format("Do not do this", path); @@ -29,6 +29,6 @@ public void ProcessRequest(HttpContext ctx) void OnButtonClicked() { // BAD: Uncontrolled format string. - String.Format(box1.Text, "Do not do this"); + String.Format(box1.Text, "Do not do this"); // $ Alert } } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.qlref b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.qlref index 88de17860f9c..10aa9e825cdd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.qlref +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.qlref @@ -1,2 +1,4 @@ query: Security Features/CWE-134/UncontrolledFormatString.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatStringBad.cs b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatStringBad.cs index dc0c689eefa5..aeb252b18a71 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatStringBad.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatStringBad.cs @@ -6,9 +6,9 @@ public class HttpHandler : IHttpHandler public void ProcessRequest(HttpContext ctx) { - string format = ctx.Request.QueryString["nameformat"]; + string format = ctx.Request.QueryString["nameformat"]; // $ Source // BAD: Uncontrolled format string. - FormattedName = string.Format(format, Surname, Forenames); + FormattedName = string.Format(format, Surname, Forenames); // $ Alert } } From 95f947faea1c26a2741fe8c93949bec1bbf97992 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 10 Apr 2025 14:18:14 +0200 Subject: [PATCH 18/21] C#: Add a testcase for CompositeFormat.Parse for cs/uncontrolled-format-string. --- .../CWE-134/UncontrolledFormatString.cs | 4 +++ .../CWE-134/UncontrolledFormatString.expected | 30 ++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs index 531d4ade8846..814167b15d91 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using System.IO; using System.Web; @@ -22,6 +23,9 @@ public void ProcessRequest(HttpContext ctx) // GOOD: Not a formatting call Console.WriteLine(path); + + // BAD: Uncontrolled format string. + CompositeFormat.Parse(path); // $ Alert } System.Windows.Forms.TextBox box1; diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected index 6c70f8450b2e..63c093f5c340 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected @@ -1,17 +1,17 @@ #select | ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format | ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine : String | ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format | This format string depends on $@. | ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine | thisread from stdin | -| UncontrolledFormatString.cs:12:23:12:26 | access to local variable path | UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:12:23:12:26 | access to local variable path | This format string depends on $@. | UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString | thisASP.NET query string | -| UncontrolledFormatString.cs:15:46:15:49 | access to local variable path | UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:15:46:15:49 | access to local variable path | This format string depends on $@. | UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString | thisASP.NET query string | -| UncontrolledFormatString.cs:32:23:32:31 | access to property Text | UncontrolledFormatString.cs:32:23:32:31 | access to property Text | UncontrolledFormatString.cs:32:23:32:31 | access to property Text | This format string depends on $@. | UncontrolledFormatString.cs:32:23:32:31 | access to property Text | thisTextBox text | +| UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | This format string depends on $@. | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString | thisASP.NET query string | +| UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | This format string depends on $@. | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString | thisASP.NET query string | +| UncontrolledFormatString.cs:36:23:36:31 | access to property Text | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | This format string depends on $@. | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | thisTextBox text | | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | This format string depends on $@. | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | thisASP.NET query string | edges | ConsoleUncontrolledFormatString.cs:8:13:8:18 | access to local variable format : String | ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format | provenance | | | ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine : String | ConsoleUncontrolledFormatString.cs:8:13:8:18 | access to local variable format : String | provenance | Src:MaD:1 | -| UncontrolledFormatString.cs:9:16:9:19 | access to local variable path : String | UncontrolledFormatString.cs:12:23:12:26 | access to local variable path | provenance | | -| UncontrolledFormatString.cs:9:16:9:19 | access to local variable path : String | UncontrolledFormatString.cs:15:46:15:49 | access to local variable path | provenance | | -| UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:9:16:9:19 | access to local variable path : String | provenance | | -| UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:9:23:9:53 | access to indexer : String | provenance | MaD:2 | -| UncontrolledFormatString.cs:9:23:9:53 | access to indexer : String | UncontrolledFormatString.cs:9:16:9:19 | access to local variable path : String | provenance | | +| UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | provenance | | +| UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | provenance | | +| UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | provenance | | +| UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:10:23:10:53 | access to indexer : String | provenance | MaD:2 | +| UncontrolledFormatString.cs:10:23:10:53 | access to indexer : String | UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | provenance | | | UncontrolledFormatStringBad.cs:9:16:9:21 | access to local variable format : String | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | provenance | | | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | UncontrolledFormatStringBad.cs:9:16:9:21 | access to local variable format : String | provenance | | | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | UncontrolledFormatStringBad.cs:9:25:9:61 | access to indexer : String | provenance | MaD:2 | @@ -23,14 +23,16 @@ nodes | ConsoleUncontrolledFormatString.cs:8:13:8:18 | access to local variable format : String | semmle.label | access to local variable format : String | | ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine : String | semmle.label | call to method ReadLine : String | | ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format | semmle.label | access to local variable format | -| UncontrolledFormatString.cs:9:16:9:19 | access to local variable path : String | semmle.label | access to local variable path : String | -| UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | -| UncontrolledFormatString.cs:9:23:9:53 | access to indexer : String | semmle.label | access to indexer : String | -| UncontrolledFormatString.cs:12:23:12:26 | access to local variable path | semmle.label | access to local variable path | -| UncontrolledFormatString.cs:15:46:15:49 | access to local variable path | semmle.label | access to local variable path | -| UncontrolledFormatString.cs:32:23:32:31 | access to property Text | semmle.label | access to property Text | +| UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | semmle.label | access to local variable path : String | +| UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | +| UncontrolledFormatString.cs:10:23:10:53 | access to indexer : String | semmle.label | access to indexer : String | +| UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | semmle.label | access to local variable path | +| UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | semmle.label | access to local variable path | +| UncontrolledFormatString.cs:36:23:36:31 | access to property Text | semmle.label | access to property Text | | UncontrolledFormatStringBad.cs:9:16:9:21 | access to local variable format : String | semmle.label | access to local variable format : String | | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | | UncontrolledFormatStringBad.cs:9:25:9:61 | access to indexer : String | semmle.label | access to indexer : String | | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | semmle.label | access to local variable format | subpaths +testFailures +| UncontrolledFormatString.cs:28:38:28:47 | // ... | Missing result: Alert | From 7594e64468de3724d399b38c22ab3897aa85e099 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 10 Apr 2025 14:19:19 +0200 Subject: [PATCH 19/21] C#: Include CompositeFormat.Parse as Format like method. --- .../semmle/code/csharp/frameworks/Format.qll | 28 +++++++++++++++++++ csharp/ql/src/API Abuse/FormatInvalid.ql | 16 ----------- .../CWE-134/UncontrolledFormatString.ql | 2 +- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index cf61a5d75aab..f2fd292693d8 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -289,3 +289,31 @@ class FormatCall extends MethodCall { result = this.getArgument(this.getFirstArgument() + index) } } + +/** + * A method call to a method that parses a format string, for example a call + * to `string.Format()`. + */ +abstract private class FormatStringParseCallImpl extends MethodCall { + /** + * Gets the expression used as the format string. + */ + abstract Expr getFormatExpr(); +} + +final class FormatStringParseCall = FormatStringParseCallImpl; + +private class OrdinaryFormatCall extends FormatStringParseCallImpl instanceof FormatCall { + override Expr getFormatExpr() { result = FormatCall.super.getFormatExpr() } +} + +/** + * A method call to `System.Text.CompositeFormat.Parse`. + */ +class ParseFormatStringCall extends FormatStringParseCallImpl { + ParseFormatStringCall() { + this.getTarget() = any(SystemTextCompositeFormatClass x).getParseMethod() + } + + override Expr getFormatExpr() { result = this.getArgument(0) } +} diff --git a/csharp/ql/src/API Abuse/FormatInvalid.ql b/csharp/ql/src/API Abuse/FormatInvalid.ql index a2b8ef5e2220..575613902921 100644 --- a/csharp/ql/src/API Abuse/FormatInvalid.ql +++ b/csharp/ql/src/API Abuse/FormatInvalid.ql @@ -15,22 +15,6 @@ import semmle.code.csharp.frameworks.system.Text import semmle.code.csharp.frameworks.Format import FormatFlow::PathGraph -abstract class FormatStringParseCall extends MethodCall { - abstract Expr getFormatExpr(); -} - -class OrdinaryFormatCall extends FormatStringParseCall instanceof FormatCall { - override Expr getFormatExpr() { result = FormatCall.super.getFormatExpr() } -} - -class ParseFormatStringCall extends FormatStringParseCall { - ParseFormatStringCall() { - this.getTarget() = any(SystemTextCompositeFormatClass x).getParseMethod() - } - - override Expr getFormatExpr() { result = this.getArgument(0) } -} - module FormatInvalidConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLiteral } diff --git a/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql b/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql index a027170dc372..b99839226c59 100644 --- a/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql +++ b/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql @@ -20,7 +20,7 @@ module FormatStringConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(FormatCall call | call.hasInsertions()).getFormatExpr() + sink.asExpr() = any(FormatStringParseCall call).getFormatExpr() } } From 85aa0abcefd0bbca6a6e2ae7c8573d2f8265243b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 10 Apr 2025 14:20:24 +0200 Subject: [PATCH 20/21] C#: Update test expected output. --- .../CWE-134/UncontrolledFormatString.expected | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected index 63c093f5c340..fa6aa70abf7c 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected @@ -2,6 +2,7 @@ | ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format | ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine : String | ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format | This format string depends on $@. | ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine | thisread from stdin | | UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | This format string depends on $@. | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString | thisASP.NET query string | | UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | This format string depends on $@. | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString | thisASP.NET query string | +| UncontrolledFormatString.cs:28:31:28:34 | access to local variable path | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:28:31:28:34 | access to local variable path | This format string depends on $@. | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString | thisASP.NET query string | | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | This format string depends on $@. | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | thisTextBox text | | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | This format string depends on $@. | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | thisASP.NET query string | edges @@ -9,6 +10,7 @@ edges | ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine : String | ConsoleUncontrolledFormatString.cs:8:13:8:18 | access to local variable format : String | provenance | Src:MaD:1 | | UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | provenance | | | UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | provenance | | +| UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | UncontrolledFormatString.cs:28:31:28:34 | access to local variable path | provenance | | | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | provenance | | | UncontrolledFormatString.cs:10:23:10:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:10:23:10:53 | access to indexer : String | provenance | MaD:2 | | UncontrolledFormatString.cs:10:23:10:53 | access to indexer : String | UncontrolledFormatString.cs:10:16:10:19 | access to local variable path : String | provenance | | @@ -28,11 +30,10 @@ nodes | UncontrolledFormatString.cs:10:23:10:53 | access to indexer : String | semmle.label | access to indexer : String | | UncontrolledFormatString.cs:13:23:13:26 | access to local variable path | semmle.label | access to local variable path | | UncontrolledFormatString.cs:16:46:16:49 | access to local variable path | semmle.label | access to local variable path | +| UncontrolledFormatString.cs:28:31:28:34 | access to local variable path | semmle.label | access to local variable path | | UncontrolledFormatString.cs:36:23:36:31 | access to property Text | semmle.label | access to property Text | | UncontrolledFormatStringBad.cs:9:16:9:21 | access to local variable format : String | semmle.label | access to local variable format : String | | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | | UncontrolledFormatStringBad.cs:9:25:9:61 | access to indexer : String | semmle.label | access to indexer : String | | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | semmle.label | access to local variable format | subpaths -testFailures -| UncontrolledFormatString.cs:28:38:28:47 | // ... | Missing result: Alert | From 2118c8e7feb667c6d339fa64fceb3ed1a6162e76 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 10 Apr 2025 14:25:56 +0200 Subject: [PATCH 21/21] C#: Add change note. --- .../src/change-notes/2025-04-10-uncontrolled-format-string.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/src/change-notes/2025-04-10-uncontrolled-format-string.md diff --git a/csharp/ql/src/change-notes/2025-04-10-uncontrolled-format-string.md b/csharp/ql/src/change-notes/2025-04-10-uncontrolled-format-string.md new file mode 100644 index 000000000000..184f84b51761 --- /dev/null +++ b/csharp/ql/src/change-notes/2025-04-10-uncontrolled-format-string.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The precision of the query `cs/uncontrolled-format-string` has been improved. Calls to `System.Text.CompositeFormat.Parse` are now considered a format like method call.