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 f54476b9e4fc..f2fd292693d8 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -8,67 +8,120 @@ 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 private class FormatMethodImpl extends Method { + /** + * Gets the argument containing the format string. For example, the argument of + * `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 } +} + +final class FormatMethod = FormatMethodImpl; + +/** A class of types used for formatting. */ +private class FormatType extends Type { + FormatType() { + this instanceof StringType or + this instanceof SystemTextCompositeFormatClass + } +} + +private class StringAndStringBuilderFormatMethods extends FormatMethodImpl { + StringAndStringBuilderFormatMethods() { + ( this.getParameter(0).getType() instanceof SystemIFormatProviderInterface and - this.getParameter(1).getType() instanceof StringType and + this.getParameter(1).getType() instanceof FormatType + 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 SystemMemoryExtensionsFormatMethods extends FormatMethodImpl { + 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 FormatMethodImpl { + SystemConsoleAndSystemIoTextWriterFormatMethods() { + this.getParameter(0).getType() instanceof StringType and + this.getNumberOfParameters() > 1 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 FormatMethodImpl { + SystemDiagnosticsDebugAssert() { + this.hasName("Assert") and + this.getDeclaringType().hasFullyQualifiedName("System.Diagnostics", "Debug") and + this.getNumberOfParameters() = 4 + } + + override int getFormatArgument() { result = 2 } +} + +private class SystemDiagnosticsFormatMethods extends FormatMethodImpl { + SystemDiagnosticsFormatMethods() { + this.getParameter(0).getType() instanceof StringType and + this.getNumberOfParameters() > 1 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 - ) - or - declType.hasFullyQualifiedName("System.Diagnostics", "Trace") and - ( - this.hasName("TraceError") or - this.hasName("TraceInformation") or - this.hasName("TraceWarning") - ) + this.hasName("TraceError") or - this.hasName("TraceInformation") and - declType.hasFullyQualifiedName("System.Diagnostics", "TraceSource") + this.hasName("TraceInformation") 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] @@ -194,24 +247,36 @@ 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())) } - /** 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() } @@ -224,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/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 235daa1ecc25..575613902921 100644 --- a/csharp/ql/src/API Abuse/FormatInvalid.ql +++ b/csharp/ql/src/API Abuse/FormatInvalid.ql @@ -11,37 +11,59 @@ */ import csharp +import semmle.code.csharp.frameworks.system.Text import semmle.code.csharp.frameworks.Format -import FormatInvalid::PathGraph +import FormatFlow::PathGraph 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 FormatInvalid::flowPath(source, sink) and - call.hasInsertions() and msg = "Invalid format string used in $@ formatting call." and callString = "this" } 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 @@ -53,13 +75,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 @@ -69,16 +91,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 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() } } 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. 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. 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 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 | 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..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 @@ -24,38 +25,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,51 +73,88 @@ 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("}"); // $ Alert + 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("}"); // $ 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 + + // 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 + } + + 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 a1c5e9254370..a33793ae461a 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -1,160 +1,401 @@ +#select +| 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 | +| 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 | +| 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: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 | +| 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 | +| 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 -| 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 | | +| 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: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 | | +| 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: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:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | -| FormatInvalid.cs:51:23:51:25 | "}" | semmle.label | "}" | -| 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:75:23:75:25 | "}" | semmle.label | "}" | +| 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:77:27:77:29 | "}" | 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:23:79: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:82:25:82:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:83:25:83:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:84:29:84:31 | "}" | 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:25:87:27 | "}" | semmle.label | "}" | -| FormatInvalid.cs:89:27:89:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:90:27:90:29 | "}" | semmle.label | "}" | -| FormatInvalid.cs:91:27:91:29 | "}" | 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:95:22:95:24 | "}" | semmle.label | "}" | -| FormatInvalid.cs:96:22:96:24 | "}" | semmle.label | "}" | -| FormatInvalid.cs:97:22:97:24 | "}" | 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: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:109:23:109:25 | "}" | 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: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: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} {{ }}" | -| 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: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 | +| 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: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}" | | 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 | "" | +| 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 -#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..52aabd8cf2bd 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 { @@ -8,28 +9,82 @@ 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); + // 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); - helper("{1}"); - - // BAD: Missing {0} - Console.WriteLine("{0}"); + helper("{1}"); // $ Source } void helper(string format) { // BAD: Missing {1} - String.Format(format, 0); + 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/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..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 { @@ -8,22 +9,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,12 +36,53 @@ 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(). 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; } 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 } } 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..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; @@ -6,13 +7,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); @@ -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; @@ -29,6 +33,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.expected b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected index 6c70f8450b2e..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 @@ -1,17 +1,19 @@ #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: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 | 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: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 | | | 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,12 +25,13 @@ 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: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 | 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 } }