diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index cab164846e2..bf867ee1a83 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -731,11 +731,9 @@ module LocalFlow { or node2 = node1.(LocalFunctionCreationNode).getAnAccess(true) or - node1 = - unique(FlowSummaryNode n1 | - FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(), - node2.(FlowSummaryNode).getSummaryNode(), true, _) - ) + FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1 + .(FlowSummaryNode) + .getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode()) } } diff --git a/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql b/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql index e64d714f8bb..f1487d7a2ce 100644 --- a/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql +++ b/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.ql @@ -52,6 +52,7 @@ class ICryptoTransform extends ValueOrRefType { } from UnsafeField field +where field.fromSource() select field, "Static field '" + field.getName() + "' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way." diff --git a/csharp/ql/src/Telemetry/DatabaseQuality.qll b/csharp/ql/src/Telemetry/DatabaseQuality.qll index 1ca553ffd31..eba5ebb5211 100644 --- a/csharp/ql/src/Telemetry/DatabaseQuality.qll +++ b/csharp/ql/src/Telemetry/DatabaseQuality.qll @@ -68,15 +68,25 @@ module CallTargetStats implements StatsSig { ) } - private predicate isInitializedWithCollectionInitializer(PropertyCall c) { + private predicate isInitializedWithObjectOrCollectionInitializer(PropertyCall c) { exists(Property p, AssignExpr assign | p = c.getProperty() and assign = c.getParent() and assign.getLValue() = c and - assign.getRValue() instanceof CollectionInitializer + assign.getRValue() instanceof ObjectOrCollectionInitializer ) } + private predicate isEventFieldAccess(EventCall c) { + exists(Event e | c.getEvent() = e | + forall(Accessor a | e.getAnAccessor() = a | a.isCompilerGenerated()) + ) + } + + private predicate isTypeParameterInstantiation(ObjectCreation e) { + e.getType() instanceof TypeParameter + } + additional predicate isNotOkCall(Call c) { not exists(c.getTarget()) and not c instanceof DelegateCall and @@ -84,8 +94,10 @@ module CallTargetStats implements StatsSig { not isNoSetterPropertyCallInConstructor(c) and not isNoSetterPropertyInitialization(c) and not isAnonymousObjectMemberDeclaration(c) and - not isInitializedWithCollectionInitializer(c) and - not c.getParent+() instanceof NameOfExpr + not isInitializedWithObjectOrCollectionInitializer(c) and + not c.getParent+() instanceof NameOfExpr and + not isEventFieldAccess(c) and + not isTypeParameterInstantiation(c) } int getNumberOfNotOk() { result = count(Call c | isNotOkCall(c)) } diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected index e69de29bb2d..205022b7180 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected @@ -0,0 +1,4 @@ +| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer | +| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer | +| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer | +| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null | diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected index 28f090d3d3d..84b6994e033 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected @@ -4,4 +4,12 @@ | Quality.cs:15:24:15:34 | access to property MyProperty3 | Call without target $@. | Quality.cs:15:24:15:34 | access to property MyProperty3 | access to property MyProperty3 | | Quality.cs:15:24:15:46 | access to property MyProperty2 | Call without target $@. | Quality.cs:15:24:15:46 | access to property MyProperty2 | access to property MyProperty2 | | Quality.cs:19:13:19:23 | access to property MyProperty4 | Call without target $@. | Quality.cs:19:13:19:23 | access to property MyProperty4 | access to property MyProperty4 | -| Quality.cs:24:16:24:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:24:16:24:26 | access to property MyProperty2 | access to property MyProperty2 | +| Quality.cs:20:13:20:23 | access to property MyProperty6 | Call without target $@. | Quality.cs:20:13:20:23 | access to property MyProperty6 | access to property MyProperty6 | +| Quality.cs:23:9:23:14 | access to event Event1 | Call without target $@. | Quality.cs:23:9:23:14 | access to event Event1 | access to event Event1 | +| Quality.cs:23:9:23:30 | delegate call | Call without target $@. | Quality.cs:23:9:23:30 | delegate call | delegate call | +| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer | +| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer | +| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer | +| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null | +| Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 | +| Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T | diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs index 18d0ec678b6..c3ec759d687 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs @@ -16,8 +16,22 @@ public class Test new Test() { - MyProperty4 = { 1, 2, 3 } + MyProperty4 = { 1, 2, 3 }, + MyProperty6 = { [1] = "" } }; + + Event1.Invoke(this, 5); + + var str = "abcd"; + var sub = str[..3]; // TODO: this is not an indexer call, but rather a `str.Substring(0, 3)` call. + + Span sp = null; + var slice = sp[..3]; // TODO: this is not an indexer call, but rather a `sp.Slice(0, 3)` call. + + Span guidBytes = stackalloc byte[16]; + guidBytes[08] = 1; // TODO: this indexer call has no target, because the target is a `ref` returning getter. + + new MyList([new(), new Test()]); // TODO: the `new()` call has no target, which is unexpected, as we know at compile time, that this is a `new Test()` call. } public int MyProperty1 { get; } @@ -25,4 +39,20 @@ public class Test public Test MyProperty3 { get; set; } public List MyProperty4 { get; } static int MyProperty5 { get; } + public Dictionary MyProperty6 { get; } + + public event EventHandler Event1; + + class Gen where T : new() + { + public static T Factory() + { + return new T(); + } + } + + class MyList + { + public MyList(IEnumerable init) { } + } } diff --git a/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md b/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md new file mode 100644 index 00000000000..8b1ee9b60b2 --- /dev/null +++ b/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index 1b09ea466cc..1f1234aa1de 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -496,14 +496,15 @@ class StructType extends @structtype, CompositeType { Field getFieldOfEmbedded(Field embeddedParent, string name, int depth, boolean isEmbedded) { // embeddedParent is a field of 'this' at depth 'depth - 1' this.hasFieldCand(_, embeddedParent, depth - 1, true) and - // embeddedParent's type has the result field - exists(StructType embeddedType, Type fieldType | - fieldType = embeddedParent.getType().getUnderlyingType() and - pragma[only_bind_into](embeddedType) = - [fieldType, fieldType.(PointerType).getBaseType().getUnderlyingType()] - | - result = embeddedType.getOwnField(name, isEmbedded) - ) + // embeddedParent's type has the result field. Note that it is invalid Go + // to have an embedded field with a named type whose underlying type is a + // pointer, so we don't have to have + // `lookThroughPointerType(embeddedParent.getType().getUnderlyingType())`. + result = + lookThroughPointerType(embeddedParent.getType()) + .getUnderlyingType() + .(StructType) + .getOwnField(name, isEmbedded) } /** @@ -523,8 +524,12 @@ class StructType extends @structtype, CompositeType { private predicate hasFieldCand(string name, Field f, int depth, boolean isEmbedded) { f = this.getOwnField(name, isEmbedded) and depth = 0 or - not this.hasOwnField(_, name, _, _) and - f = this.getFieldOfEmbedded(_, name, depth, isEmbedded) + f = this.getFieldOfEmbedded(_, name, depth, isEmbedded) and + // If this is a cyclic field and this is not the first time we see this embedded field + // then don't include it as a field candidate to avoid non-termination. + not exists(Type t | lookThroughPointerType(t) = lookThroughPointerType(f.getType()) | + this.hasOwnField(_, name, t, _) + ) } private predicate hasMethodCand(string name, Method m, int depth) { @@ -541,15 +546,7 @@ class StructType extends @structtype, CompositeType { predicate hasField(string name, Type tp) { exists(int mindepth | mindepth = min(int depth | this.hasFieldCand(name, _, depth, _)) and - tp = unique(Field f | f = this.getFieldCand(name, mindepth, _)).getType() - ) - } - - private Field getFieldCand(string name, int depth, boolean isEmbedded) { - result = this.getOwnField(name, isEmbedded) and depth = 0 - or - exists(Type embedded | this.hasEmbeddedField(embedded, depth - 1) | - result = embedded.getUnderlyingType().(StructType).getOwnField(name, isEmbedded) + tp = unique(Field f | this.hasFieldCand(name, f, mindepth, _)).getType() ) } @@ -564,9 +561,9 @@ class StructType extends @structtype, CompositeType { * The depth of a field `f` declared in this type is zero. */ Field getFieldAtDepth(string name, int depth) { - depth = min(int depthCand | exists(this.getFieldCand(name, depthCand, _))) and - result = this.getFieldCand(name, depth, _) and - strictcount(this.getFieldCand(name, depth, _)) = 1 + depth = min(int depthCand | this.hasFieldCand(name, _, depthCand, _)) and + this.hasFieldCand(name, result, depth, _) and + strictcount(Field f | this.hasFieldCand(name, f, depth, _)) = 1 } Method getMethodAtDepth(string name, int depth) { diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected b/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected index 485a42b185e..8a527e3d4f7 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_getPackage.expected @@ -13,8 +13,8 @@ | depth.go:19:2:19:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | embedded.go:4:2:4:2 | A | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | embedded.go:8:3:8:5 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | -| embedded.go:13:2:13:4 | Qux | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | -| embedded.go:14:2:14:4 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | +| embedded.go:12:2:12:4 | Qux | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | +| embedded.go:13:2:13:4 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:4:2:4:11 | valueField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:5:2:5:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:6:2:6:11 | arrayField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | @@ -26,6 +26,7 @@ | generic.go:21:2:21:9 | mapField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:25:2:25:12 | structField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | generic.go:29:2:29:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | +| main.go:18:7:18:15 | NameClash | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | pkg1/embedding.go:19:23:19:26 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/embedding.go:22:27:22:30 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/embedding.go:25:24:25:31 | embedder | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | @@ -36,20 +37,22 @@ | pkg1/promotedStructs.go:14:2:14:7 | PField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/promotedStructs.go:22:22:22:22 | S | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg1/promotedStructs.go:25:22:25:22 | P | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:4:2:4:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:5:2:5:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:6:2:6:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:10:2:10:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:11:2:11:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:15:3:15:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:16:3:16:5 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:20:3:20:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:21:2:21:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:25:2:25:4 | val | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:26:2:26:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | -| pkg1/tst.go:30:2:30:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:6:2:6:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:7:2:7:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:8:2:8:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:12:2:12:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:13:2:13:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:17:3:17:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:18:3:18:5 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:22:3:22:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:23:2:23:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:27:2:27:4 | val | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:28:2:28:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:32:2:32:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | +| pkg1/tst.go:62:7:62:15 | NameClash | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | | pkg2/tst.go:4:2:4:2 | g | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | | pkg2/tst.go:8:2:8:2 | g | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | +| pkg2/tst.go:17:2:17:8 | NCField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | | struct_tags.go:4:2:4:7 | field1 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | struct_tags.go:5:2:5:7 | field2 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | | struct_tags.go:9:2:9:7 | field1 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected index c8575332f6f..e7ffe6bc1ba 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName2.expected @@ -18,10 +18,11 @@ | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.c | f | | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.d | f | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Baz | A | +| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | A | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | A | | embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | Baz | -| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Qux | -| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Baz | +| embedded.go:12:2:12:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Qux | +| embedded.go:13:2:13:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Baz | | generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | valueField | | generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | pointerField | | generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | arrayField | @@ -33,6 +34,7 @@ | generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2 | mapField | | generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2b | structField | | generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct2 | pointerField | +| main.go:18:7:18:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NameClash | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | base | @@ -49,27 +51,31 @@ | pkg1/promotedStructs.go:14:2:14:7 | PField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | PField | | pkg1/promotedStructs.go:22:22:22:22 | S | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | S | | pkg1/promotedStructs.go:25:22:25:22 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | P | -| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | f | -| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Foo | -| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Bar | -| pkg1/tst.go:10:2:10:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Foo | -| pkg1/tst.go:11:2:11:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Bar | -| pkg1/tst.go:15:3:15:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Foo | -| pkg1/tst.go:16:3:16:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Bar | -| pkg1/tst.go:20:3:20:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Foo | -| pkg1/tst.go:21:2:21:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Bar | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | val | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | flag | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | flag | +| pkg1/tst.go:6:2:6:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | f | +| pkg1/tst.go:7:2:7:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Foo | +| pkg1/tst.go:8:2:8:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Bar | +| pkg1/tst.go:12:2:12:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Foo | +| pkg1/tst.go:13:2:13:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Bar | +| pkg1/tst.go:17:3:17:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Foo | +| pkg1/tst.go:18:3:18:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Bar | +| pkg1/tst.go:22:3:22:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Foo | +| pkg1/tst.go:23:2:23:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Bar | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | val | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | flag | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | flag | +| pkg1/tst.go:62:7:62:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NameClash | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | g | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NCField | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NCField | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | NCField | | struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | field1 | | struct_tags.go:5:2:5:7 | field2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | field2 | | struct_tags.go:9:2:9:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S2 | field1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected index 56176082d9a..03b93b37c74 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Field_hasQualifiedName3.expected @@ -18,10 +18,11 @@ | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | c | f | | depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | d | f | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Baz | A | +| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | A | | embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Qux | A | | embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Qux | Baz | -| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Qux | -| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Baz | +| embedded.go:12:2:12:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Qux | +| embedded.go:13:2:13:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Baz | | generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | valueField | | generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | pointerField | | generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | arrayField | @@ -33,6 +34,7 @@ | generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2 | mapField | | generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2b | structField | | generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | CircularGenericStruct2 | pointerField | +| main.go:18:7:18:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NameClash | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | base | | pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | base | @@ -49,27 +51,31 @@ | pkg1/promotedStructs.go:14:2:14:7 | PField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | PField | | pkg1/promotedStructs.go:22:22:22:22 | S | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedS | S | | pkg1/promotedStructs.go:25:22:25:22 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | P | -| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | f | -| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Foo | -| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Bar | -| pkg1/tst.go:10:2:10:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Foo | -| pkg1/tst.go:11:2:11:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Bar | -| pkg1/tst.go:15:3:15:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Foo | -| pkg1/tst.go:16:3:16:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Bar | -| pkg1/tst.go:20:3:20:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Foo | -| pkg1/tst.go:21:2:21:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Bar | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | val | -| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | val | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | flag | -| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Bar | flag | -| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | flag | +| pkg1/tst.go:6:2:6:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | f | +| pkg1/tst.go:7:2:7:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Foo | +| pkg1/tst.go:8:2:8:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Bar | +| pkg1/tst.go:12:2:12:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Foo | +| pkg1/tst.go:13:2:13:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Bar | +| pkg1/tst.go:17:3:17:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Foo | +| pkg1/tst.go:18:3:18:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Bar | +| pkg1/tst.go:22:3:22:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Foo | +| pkg1/tst.go:23:2:23:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Bar | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | val | +| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | val | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | flag | +| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Bar | flag | +| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | flag | +| pkg1/tst.go:62:7:62:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NameClash | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | G | g | | pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | G | g | | pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NCField | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NCField | +| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | NameClash | NCField | | struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S1 | field1 | | struct_tags.go:5:2:5:7 | field2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S1 | field2 | | struct_tags.go:9:2:9:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S2 | field1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected index 48de9172b36..8ec8033d086 100644 --- a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected +++ b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected @@ -1,2 +1,2 @@ -failures testFailures +failures diff --git a/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected b/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected index 9d576b0f4f6..351b29c6222 100644 --- a/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected +++ b/go/ql/test/library-tests/semmle/go/Types/MethodCount.expected @@ -1,4 +1,6 @@ +| * EmbedsNameClash | 1 | | * Foo | 1 | +| * NameClash | 1 | | * P | 1 | | * S | 1 | | * SEmbedP | 1 | @@ -19,10 +21,12 @@ | AExtended | 2 | | B | 2 | | C | 2 | +| EmbedsNameClash | 1 | | Foo | 1 | | GenericInterface | 1 | | MixedExportedAndNot | 2 | | MyInterface | 17 | +| NameClash | 1 | | S | 1 | | SEmbedS | 1 | | T | 1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected b/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected index 326debd2f80..d143fb3121e 100644 --- a/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected +++ b/go/ql/test/library-tests/semmle/go/Types/MethodTypes.expected @@ -30,6 +30,7 @@ | interface.go:95:6:95:8 | i18 | StringA | func() string | | interface.go:101:6:101:8 | i19 | StringB | func() string | | interface.go:105:6:105:8 | i20 | StringB | func() string | +| main.go:17:6:17:20 | EmbedsNameClash | NCMethod | func() | | pkg1/embedding.go:19:6:19:13 | embedder | f | func() int | | pkg1/embedding.go:22:6:22:16 | ptrembedder | f | func() int | | pkg1/embedding.go:22:6:22:16 | ptrembedder | g | func() int | @@ -51,8 +52,9 @@ | pkg1/interfaces.go:35:6:35:24 | MixedExportedAndNot | Exported | func() | | pkg1/interfaces.go:35:6:35:24 | MixedExportedAndNot | notExported | func() | | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | SMethod | func() interface { } | -| pkg1/tst.go:3:6:3:6 | T | half | func() Foo | -| pkg1/tst.go:14:6:14:7 | T3 | half | func() Foo | -| pkg1/tst.go:19:6:19:7 | T4 | half | func() Foo | +| pkg1/tst.go:5:6:5:6 | T | half | func() Foo | +| pkg1/tst.go:16:6:16:7 | T3 | half | func() Foo | +| pkg1/tst.go:21:6:21:7 | T4 | half | func() Foo | +| pkg1/tst.go:61:6:61:14 | NameClash | NCMethod | func() | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | Exported | func() | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | notExported | func() | diff --git a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected index 1f893728e30..3929e1d98d5 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName2.expected @@ -59,9 +59,12 @@ | pkg1/promotedStructs.go:8:12:8:18 | SMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | SMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.P | PMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | PMethod | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | half | | pkg2/tst.go:12:2:12:9 | Exported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | Exported | | pkg2/tst.go:13:2:13:12 | notExported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | notExported | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | NCMethod | diff --git a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected index 59a298e4b5f..9699ba3f382 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Method_hasQualifiedName3.expected @@ -59,9 +59,12 @@ | pkg1/promotedStructs.go:8:12:8:18 | SMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedS | SMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | P | PMethod | | pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | PMethod | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half | -| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half | +| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half | | pkg2/tst.go:12:2:12:9 | Exported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | MixedExportedAndNot | Exported | | pkg2/tst.go:13:2:13:12 | notExported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | MixedExportedAndNot | notExported | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NCMethod | +| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | NameClash | NCMethod | diff --git a/go/ql/test/library-tests/semmle/go/Types/Methods.expected b/go/ql/test/library-tests/semmle/go/Types/Methods.expected index 2c17013c186..c75b336543a 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Methods.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Methods.expected @@ -1,11 +1,13 @@ -| * Foo | half | pkg1/tst.go:33:16:33:19 | half | +| * EmbedsNameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | +| * Foo | half | pkg1/tst.go:35:16:35:19 | half | +| * NameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | | * P | PMethod | pkg1/promotedStructs.go:17:13:17:19 | PMethod | | * S | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | | * SEmbedP | PMethod | pkg1/promotedStructs.go:17:13:17:19 | PMethod | | * SEmbedS | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | -| * T | half | pkg1/tst.go:33:16:33:19 | half | -| * T3 | half | pkg1/tst.go:33:16:33:19 | half | -| * T4 | half | pkg1/tst.go:33:16:33:19 | half | +| * T | half | pkg1/tst.go:35:16:35:19 | half | +| * T3 | half | pkg1/tst.go:35:16:35:19 | half | +| * T4 | half | pkg1/tst.go:35:16:35:19 | half | | * base | f | pkg1/embedding.go:10:13:10:13 | f | | * base | g | pkg1/embedding.go:14:14:14:14 | g | | * embedder | f | pkg1/embedding.go:10:13:10:13 | f | @@ -29,7 +31,8 @@ | B | n | pkg1/interfaces.go:9:2:9:2 | n | | C | n | pkg1/interfaces.go:13:2:13:2 | n | | C | o | pkg1/interfaces.go:14:2:14:2 | o | -| Foo | half | pkg1/tst.go:33:16:33:19 | half | +| EmbedsNameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | +| Foo | half | pkg1/tst.go:35:16:35:19 | half | | GenericInterface | GetT | generic.go:33:2:33:5 | GetT | | MixedExportedAndNot | Exported | pkg1/interfaces.go:36:2:36:9 | Exported | | MixedExportedAndNot | Exported | pkg2/tst.go:12:2:12:9 | Exported | @@ -52,11 +55,12 @@ | MyInterface | dummy18 | generic.go:62:2:62:8 | dummy18 | | MyInterface | dummy19 | generic.go:63:2:63:8 | dummy19 | | MyInterface | dummy20 | generic.go:64:2:64:8 | dummy20 | +| NameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod | | S | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | | SEmbedS | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod | -| T | half | pkg1/tst.go:33:16:33:19 | half | -| T3 | half | pkg1/tst.go:33:16:33:19 | half | -| T4 | half | pkg1/tst.go:33:16:33:19 | half | +| T | half | pkg1/tst.go:35:16:35:19 | half | +| T3 | half | pkg1/tst.go:35:16:35:19 | half | +| T4 | half | pkg1/tst.go:35:16:35:19 | half | | base | f | pkg1/embedding.go:10:13:10:13 | f | | embedder | f | pkg1/embedding.go:10:13:10:13 | f | | embedder2 | f | pkg1/embedding.go:10:13:10:13 | f | diff --git a/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected b/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected index 660209effbb..dd6e9021a4f 100644 --- a/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected +++ b/go/ql/test/library-tests/semmle/go/Types/QualifiedNames.expected @@ -9,7 +9,7 @@ | depth.go:18:6:18:6 | d | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.d | | embedded.go:3:6:3:8 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Baz | | embedded.go:7:6:7:8 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | -| embedded.go:12:6:12:14 | EmbedsBaz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | +| embedded.go:11:6:11:14 | EmbedsBaz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | | generic.go:3:6:3:19 | GenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | | generic.go:11:6:11:27 | CircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct1 | | generic.go:15:6:15:31 | UsesCircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.UsesCircularGenericStruct1 | @@ -77,6 +77,7 @@ | interface.go:136:6:136:21 | testComparable21 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable21 | | interface.go:137:6:137:21 | testComparable22 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable22 | | interface.go:138:6:138:21 | testComparable23 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable23 | +| main.go:17:6:17:20 | EmbedsNameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | | pkg1/embedding.go:8:6:8:9 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.base | | pkg1/embedding.go:19:6:19:13 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | | pkg1/embedding.go:22:6:22:16 | ptrembedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder | @@ -95,14 +96,16 @@ | pkg1/promotedStructs.go:13:6:13:6 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.P | | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | -| pkg1/tst.go:3:6:3:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | -| pkg1/tst.go:9:6:9:7 | T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | -| pkg1/tst.go:14:6:14:7 | T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | -| pkg1/tst.go:19:6:19:7 | T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | -| pkg1/tst.go:24:6:24:8 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | -| pkg1/tst.go:29:6:29:8 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | +| pkg1/tst.go:5:6:5:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | +| pkg1/tst.go:11:6:11:7 | T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | +| pkg1/tst.go:16:6:16:7 | T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | +| pkg1/tst.go:21:6:21:7 | T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | +| pkg1/tst.go:26:6:26:8 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | +| pkg1/tst.go:31:6:31:8 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | +| pkg1/tst.go:61:6:61:14 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | | pkg2/tst.go:3:6:3:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | | pkg2/tst.go:7:6:7:6 | G | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | +| pkg2/tst.go:16:6:16:14 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | | struct_tags.go:3:6:3:7 | S1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | | struct_tags.go:8:6:8:7 | S2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S2 | diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected index faedd5aa0de..5831152884b 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected @@ -4,18 +4,19 @@ | depth.go:22:1:25:1 | function declaration | 0 | | generic.go:70:1:72:1 | function declaration | 1 | | generic.go:74:1:80:1 | function declaration | 1 | -| main.go:5:1:5:30 | function declaration | 1 | -| main.go:7:1:9:1 | function declaration | 2 | -| main.go:11:1:11:14 | function declaration | 0 | +| main.go:9:1:9:30 | function declaration | 1 | +| main.go:11:1:13:1 | function declaration | 2 | +| main.go:15:1:15:14 | function declaration | 0 | | pkg1/embedding.go:10:1:12:1 | function declaration | 0 | | pkg1/embedding.go:14:1:16:1 | function declaration | 0 | | pkg1/embedding.go:30:1:32:1 | function declaration | 0 | | pkg1/embedding.go:40:1:61:1 | function declaration | 0 | | pkg1/promotedStructs.go:8:1:10:1 | function declaration | 0 | | pkg1/promotedStructs.go:17:1:19:1 | function declaration | 0 | -| pkg1/tst.go:33:1:35:1 | function declaration | 0 | -| pkg1/tst.go:37:1:37:26 | function declaration | 1 | -| pkg1/tst.go:39:1:57:1 | function declaration | 2 | +| pkg1/tst.go:35:1:37:1 | function declaration | 0 | +| pkg1/tst.go:39:1:39:26 | function declaration | 1 | +| pkg1/tst.go:41:1:59:1 | function declaration | 2 | +| pkg2/tst.go:20:1:20:32 | function declaration | 0 | | promoted.go:7:1:10:1 | function declaration | 1 | | promoted.go:12:1:15:1 | function declaration | 1 | | promoted.go:17:1:20:1 | function declaration | 1 | diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected index 513ad56bd3c..960a272f73c 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected @@ -4,18 +4,19 @@ | depth.go:22:1:25:1 | function declaration | 0 | | generic.go:70:1:72:1 | function declaration | 1 | | generic.go:74:1:80:1 | function declaration | 0 | -| main.go:5:1:5:30 | function declaration | 0 | -| main.go:7:1:9:1 | function declaration | 2 | -| main.go:11:1:11:14 | function declaration | 0 | +| main.go:9:1:9:30 | function declaration | 0 | +| main.go:11:1:13:1 | function declaration | 2 | +| main.go:15:1:15:14 | function declaration | 0 | | pkg1/embedding.go:10:1:12:1 | function declaration | 1 | | pkg1/embedding.go:14:1:16:1 | function declaration | 1 | | pkg1/embedding.go:30:1:32:1 | function declaration | 1 | | pkg1/embedding.go:40:1:61:1 | function declaration | 0 | | pkg1/promotedStructs.go:8:1:10:1 | function declaration | 1 | | pkg1/promotedStructs.go:17:1:19:1 | function declaration | 1 | -| pkg1/tst.go:33:1:35:1 | function declaration | 1 | -| pkg1/tst.go:37:1:37:26 | function declaration | 0 | -| pkg1/tst.go:39:1:57:1 | function declaration | 0 | +| pkg1/tst.go:35:1:37:1 | function declaration | 1 | +| pkg1/tst.go:39:1:39:26 | function declaration | 0 | +| pkg1/tst.go:41:1:59:1 | function declaration | 0 | +| pkg2/tst.go:20:1:20:32 | function declaration | 0 | | promoted.go:7:1:10:1 | function declaration | 0 | | promoted.go:12:1:15:1 | function declaration | 0 | | promoted.go:17:1:20:1 | function declaration | 0 | diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected index 48de9172b36..8ec8033d086 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected @@ -1,2 +1,2 @@ -failures testFailures +failures diff --git a/go/ql/test/library-tests/semmle/go/Types/StructFields.expected b/go/ql/test/library-tests/semmle/go/Types/StructFields.expected index 502b4fa07ad..1757e0cdaf9 100644 --- a/go/ql/test/library-tests/semmle/go/Types/StructFields.expected +++ b/go/ql/test/library-tests/semmle/go/Types/StructFields.expected @@ -20,8 +20,9 @@ | embedded.go:3:6:3:8 | Baz | embedded.go:3:10:5:1 | struct type | A | string | | embedded.go:7:6:7:8 | Qux | embedded.go:7:10:9:1 | struct type | A | string | | embedded.go:7:6:7:8 | Qux | embedded.go:7:10:9:1 | struct type | Baz | * Baz | -| embedded.go:12:6:12:14 | EmbedsBaz | embedded.go:12:16:15:1 | struct type | Baz | string | -| embedded.go:12:6:12:14 | EmbedsBaz | embedded.go:12:16:15:1 | struct type | Qux | Qux | +| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | A | string | +| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | Baz | string | +| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | Qux | Qux | | generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | arrayField | [10]T | | generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | mapField | [string]T | | generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | pointerField | * T | @@ -33,6 +34,8 @@ | generic.go:19:6:19:19 | GenericStruct2 | generic.go:19:42:22:1 | struct type | structField | GenericStruct1 | | generic.go:24:6:24:20 | GenericStruct2b | generic.go:24:39:26:1 | struct type | structField | GenericStruct2 | | generic.go:28:6:28:27 | CircularGenericStruct2 | generic.go:28:39:30:1 | struct type | pointerField | * CircularGenericStruct2 | +| main.go:17:6:17:20 | EmbedsNameClash | main.go:17:22:19:1 | struct type | NCField | string | +| main.go:17:6:17:20 | EmbedsNameClash | main.go:17:22:19:1 | struct type | NameClash | NameClash | | pkg1/embedding.go:19:6:19:13 | embedder | pkg1/embedding.go:19:15:19:28 | struct type | base | base | | pkg1/embedding.go:22:6:22:16 | ptrembedder | pkg1/embedding.go:22:18:22:32 | struct type | base | * base | | pkg1/embedding.go:25:6:25:14 | embedder2 | pkg1/embedding.go:25:16:25:33 | struct type | base | base | @@ -51,27 +54,30 @@ | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | pkg1/promotedStructs.go:22:14:22:24 | struct type | SField | string | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | pkg1/promotedStructs.go:25:14:25:24 | struct type | P | P | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | pkg1/promotedStructs.go:25:14:25:24 | struct type | PField | string | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | Bar | Bar | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | Foo | Foo | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | f | int | -| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | val | int | -| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | Bar | Bar | -| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | Foo | Foo | -| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | flag | bool | -| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | Bar | * Bar | -| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | Foo | * Foo | -| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | val | int | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | Bar | Bar | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | Foo | * Foo | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | flag | bool | -| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | val | int | -| pkg1/tst.go:24:6:24:8 | Foo | pkg1/tst.go:24:10:27:1 | struct type | flag | bool | -| pkg1/tst.go:24:6:24:8 | Foo | pkg1/tst.go:24:10:27:1 | struct type | val | int | -| pkg1/tst.go:29:6:29:8 | Bar | pkg1/tst.go:29:10:31:1 | struct type | flag | bool | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | Bar | Bar | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | Foo | Foo | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | f | int | +| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | val | int | +| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | Bar | Bar | +| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | Foo | Foo | +| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | flag | bool | +| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | Bar | * Bar | +| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | Foo | * Foo | +| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | val | int | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | Bar | Bar | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | Foo | * Foo | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | flag | bool | +| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | val | int | +| pkg1/tst.go:26:6:26:8 | Foo | pkg1/tst.go:26:10:29:1 | struct type | flag | bool | +| pkg1/tst.go:26:6:26:8 | Foo | pkg1/tst.go:26:10:29:1 | struct type | val | int | +| pkg1/tst.go:31:6:31:8 | Bar | pkg1/tst.go:31:10:33:1 | struct type | flag | bool | +| pkg1/tst.go:61:6:61:14 | NameClash | pkg1/tst.go:61:16:63:1 | struct type | NCField | string | +| pkg1/tst.go:61:6:61:14 | NameClash | pkg1/tst.go:61:16:63:1 | struct type | NameClash | NameClash | | pkg2/tst.go:3:6:3:6 | T | pkg2/tst.go:3:8:5:1 | struct type | g | int | | pkg2/tst.go:3:6:3:6 | T | pkg2/tst.go:7:8:9:1 | struct type | g | int | | pkg2/tst.go:7:6:7:6 | G | pkg2/tst.go:3:8:5:1 | struct type | g | int | | pkg2/tst.go:7:6:7:6 | G | pkg2/tst.go:7:8:9:1 | struct type | g | int | +| pkg2/tst.go:16:6:16:14 | NameClash | pkg2/tst.go:16:16:18:1 | struct type | NCField | string | | struct_tags.go:3:6:3:7 | S1 | struct_tags.go:3:9:6:1 | struct type | field1 | int | | struct_tags.go:3:6:3:7 | S1 | struct_tags.go:3:9:6:1 | struct type | field2 | int | | struct_tags.go:8:6:8:7 | S2 | struct_tags.go:8:9:11:1 | struct type | field1 | int | diff --git a/go/ql/test/library-tests/semmle/go/Types/Types.expected b/go/ql/test/library-tests/semmle/go/Types/Types.expected index 9c04442d7aa..ab34dd4d8ee 100644 --- a/go/ql/test/library-tests/semmle/go/Types/Types.expected +++ b/go/ql/test/library-tests/semmle/go/Types/Types.expected @@ -9,7 +9,7 @@ | depth.go:18:6:18:6 | d | d | | embedded.go:3:6:3:8 | Baz | Baz | | embedded.go:7:6:7:8 | Qux | Qux | -| embedded.go:12:6:12:14 | EmbedsBaz | EmbedsBaz | +| embedded.go:11:6:11:14 | EmbedsBaz | EmbedsBaz | | generic.go:3:6:3:19 | GenericStruct1 | GenericStruct1 | | generic.go:11:6:11:27 | CircularGenericStruct1 | CircularGenericStruct1 | | generic.go:15:6:15:31 | UsesCircularGenericStruct1 | UsesCircularGenericStruct1 | @@ -77,6 +77,7 @@ | interface.go:136:6:136:21 | testComparable21 | testComparable21 | | interface.go:137:6:137:21 | testComparable22 | testComparable22 | | interface.go:138:6:138:21 | testComparable23 | testComparable23 | +| main.go:17:6:17:20 | EmbedsNameClash | EmbedsNameClash | | pkg1/embedding.go:8:6:8:9 | base | base | | pkg1/embedding.go:19:6:19:13 | embedder | embedder | | pkg1/embedding.go:22:6:22:16 | ptrembedder | ptrembedder | @@ -95,14 +96,16 @@ | pkg1/promotedStructs.go:13:6:13:6 | P | P | | pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | SEmbedS | | pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | SEmbedP | -| pkg1/tst.go:3:6:3:6 | T | T | -| pkg1/tst.go:9:6:9:7 | T2 | T2 | -| pkg1/tst.go:14:6:14:7 | T3 | T3 | -| pkg1/tst.go:19:6:19:7 | T4 | T4 | -| pkg1/tst.go:24:6:24:8 | Foo | Foo | -| pkg1/tst.go:29:6:29:8 | Bar | Bar | +| pkg1/tst.go:5:6:5:6 | T | T | +| pkg1/tst.go:11:6:11:7 | T2 | T2 | +| pkg1/tst.go:16:6:16:7 | T3 | T3 | +| pkg1/tst.go:21:6:21:7 | T4 | T4 | +| pkg1/tst.go:26:6:26:8 | Foo | Foo | +| pkg1/tst.go:31:6:31:8 | Bar | Bar | +| pkg1/tst.go:61:6:61:14 | NameClash | NameClash | | pkg2/tst.go:3:6:3:6 | T | T | | pkg2/tst.go:7:6:7:6 | G | G | | pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | MixedExportedAndNot | +| pkg2/tst.go:16:6:16:14 | NameClash | NameClash | | struct_tags.go:3:6:3:7 | S1 | S1 | | struct_tags.go:8:6:8:7 | S2 | S2 | diff --git a/go/ql/test/library-tests/semmle/go/Types/embedded.go b/go/ql/test/library-tests/semmle/go/Types/embedded.go index c9c2cf46c2b..413290dbf1a 100644 --- a/go/ql/test/library-tests/semmle/go/Types/embedded.go +++ b/go/ql/test/library-tests/semmle/go/Types/embedded.go @@ -8,7 +8,6 @@ type Qux struct { *Baz } -// EmbedsBaz should have a field A but does not type EmbedsBaz struct { Qux Baz string diff --git a/go/ql/test/library-tests/semmle/go/Types/main.go b/go/ql/test/library-tests/semmle/go/Types/main.go index 1c7e1684725..de11cbd152f 100644 --- a/go/ql/test/library-tests/semmle/go/Types/main.go +++ b/go/ql/test/library-tests/semmle/go/Types/main.go @@ -1,6 +1,10 @@ package main -import "regexp" +import ( + "regexp" + + "github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1" +) func test(r *regexp.Regexp) {} @@ -9,3 +13,7 @@ func swap(x int, y int) (int, int) { } func main() {} + +type EmbedsNameClash struct { + pkg1.NameClash +} diff --git a/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go b/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go index 1b1920ff33a..598e711ff2c 100644 --- a/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go +++ b/go/ql/test/library-tests/semmle/go/Types/pkg1/tst.go @@ -1,5 +1,7 @@ package pkg1 +import "github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2" + type T struct { f int Foo @@ -55,3 +57,7 @@ func test(t T, t2 T2) { // methods of T2 // illegal: t2.half() } + +type NameClash struct { + pkg2.NameClash +} diff --git a/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go b/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go index af91e514b77..d1634851b6b 100644 --- a/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go +++ b/go/ql/test/library-tests/semmle/go/Types/pkg2/tst.go @@ -12,3 +12,9 @@ type MixedExportedAndNot interface { Exported() notExported() } + +type NameClash struct { + NCField string +} + +func (t NameClash) NCMethod() {} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index c1fc51bff04..bb71ed25c73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -160,11 +160,8 @@ predicate localMustFlowStep(Node node1, Node node2) { or node2.asExpr().(AssignExpr).getSource() = node1.asExpr() or - node1 = - unique(FlowSummaryNode n1 | - FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(), - node2.(FlowSummaryNode).getSummaryNode(), true, _) - ) + FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode()) } import Cached diff --git a/javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md b/javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md new file mode 100644 index 00000000000..e1db79e5c86 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md @@ -0,0 +1,6 @@ +--- +category: majorAnalysis +--- +* The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals. +* Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases. +* Regular expression related queries now account for unknown flags. diff --git a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll index b40f10d9369..0b84e9a734b 100644 --- a/javascript/ql/lib/semmle/javascript/StandardLibrary.qll +++ b/javascript/ql/lib/semmle/javascript/StandardLibrary.qll @@ -117,6 +117,12 @@ class StringReplaceCall extends DataFlow::MethodCallNode { */ predicate isGlobal() { this.getRegExp().isGlobal() or this.getMethodName() = "replaceAll" } + /** + * Holds if this is a global replacement, that is, the first argument is a regular expression + * with the `g` flag or unknown flags, or this is a call to `.replaceAll()`. + */ + predicate maybeGlobal() { this.getRegExp().maybeGlobal() or this.getMethodName() = "replaceAll" } + /** * Holds if this call to `replace` replaces `old` with `new`. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll index d88dab4d431..8a7d2d11b91 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll @@ -1685,6 +1685,9 @@ class RegExpCreationNode extends DataFlow::SourceNode { /** Holds if the constructed predicate has the `g` flag. */ predicate isGlobal() { RegExp::isGlobal(this.getFlags()) } + /** Holds if the constructed predicate has the `g` flag or unknown flags. */ + predicate maybeGlobal() { RegExp::maybeGlobal(this.tryGetFlags()) } + /** Gets a data flow node referring to this regular expression. */ private DataFlow::SourceNode getAReference(DataFlow::TypeTracker t) { t.start() and diff --git a/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll b/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll index 6b05e2c754d..13d5033458a 100644 --- a/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll +++ b/javascript/ql/lib/semmle/javascript/security/IncompleteBlacklistSanitizer.qll @@ -74,7 +74,7 @@ private StringReplaceCall getAStringReplaceMethodCall(StringReplaceCall n) { module HtmlSanitization { private predicate fixedGlobalReplacement(StringReplaceCallSequence chain) { forall(StringReplaceCall member | member = chain.getAMember() | - member.isGlobal() and member.getArgument(0) instanceof DataFlow::RegExpLiteralNode + member.maybeGlobal() and member.getArgument(0) instanceof DataFlow::RegExpCreationNode ) } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll index c783a9c3cfc..b302a025b2c 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextLoggingCustomizations.qll @@ -36,9 +36,12 @@ module CleartextLogging { */ class MaskingReplacer extends Barrier, StringReplaceCall { MaskingReplacer() { - this.isGlobal() and + this.maybeGlobal() and exists(this.getRawReplacement().getStringValue()) and - any(RegExpDot term).getLiteral() = this.getRegExp().asExpr() + exists(DataFlow::RegExpCreationNode regexpObj | + this.(StringReplaceCall).getRegExp() = regexpObj and + regexpObj.getRoot() = any(RegExpDot term).getRootTerm() + ) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll index 0ba2f26b24c..197b8594244 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll @@ -46,7 +46,7 @@ class Configuration extends TaintTracking::Configuration { // Replacing with "_" is likely to be exploitable not replace.getRawReplacement().getStringValue() = "_" and ( - replace.isGlobal() + replace.maybeGlobal() or // Non-global replace with a non-empty string can also prevent __proto__ by // inserting a chunk of text that doesn't fit anywhere in __proto__ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll index 291d6eebc1c..03cbd01b630 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll @@ -76,7 +76,7 @@ module RegExpInjection { */ class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall { MetacharEscapeSanitizer() { - this.isGlobal() and + this.maybeGlobal() and ( RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["{", "[", "+"]) or diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll index c24ea7f6110..8798c926086 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll @@ -221,10 +221,10 @@ module TaintedPath { this instanceof StringReplaceCall and input = this.getReceiver() and output = this and - not exists(RegExpLiteral literal, RegExpTerm term | - this.(StringReplaceCall).getRegExp().asExpr() = literal and - this.(StringReplaceCall).isGlobal() and - literal.getRoot() = term + not exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term | + this.(StringReplaceCall).getRegExp() = regexp and + this.(StringReplaceCall).maybeGlobal() and + regexp.getRoot() = term | term.getAMatchedString() = "/" or term.getAMatchedString() = "." or @@ -305,9 +305,9 @@ module TaintedPath { input = this.getReceiver() and output = this and this.isGlobal() and - exists(RegExpLiteral literal, RegExpTerm term | - this.getRegExp().asExpr() = literal and - literal.getRoot() = term and + exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term | + this.getRegExp() = regexp and + regexp.getRoot() = term and not term.getAMatchedString() = "/" | term.getAMatchedString() = "." or diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll index 77625874df9..8e753a5ef63 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll @@ -245,7 +245,7 @@ module UnsafeShellCommandConstruction { class ReplaceQuotesSanitizer extends Sanitizer, StringReplaceCall { ReplaceQuotesSanitizer() { this.getAReplacedString() = "'" and - this.isGlobal() and + this.maybeGlobal() and this.getRawReplacement().mayHaveStringValue(["'\\''", ""]) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll index fc2db8e9f87..a0def5b7b74 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll @@ -36,7 +36,7 @@ module Shared { */ class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall { MetacharEscapeSanitizer() { - this.isGlobal() and + this.maybeGlobal() and ( RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["<", "'", "\""]) or diff --git a/javascript/ql/src/Security/CWE-116/IncompleteSanitization.ql b/javascript/ql/src/Security/CWE-116/IncompleteSanitization.ql index dc92b24abef..7d0dc71a2a8 100644 --- a/javascript/ql/src/Security/CWE-116/IncompleteSanitization.ql +++ b/javascript/ql/src/Security/CWE-116/IncompleteSanitization.ql @@ -23,7 +23,7 @@ string metachar() { result = "'\"\\&<>\n\r\t*|{}[]%$".charAt(_) } /** Gets a string matched by `e` in a `replace` call. */ string getAMatchedString(DataFlow::Node e) { - result = e.(DataFlow::RegExpLiteralNode).getRoot().getAMatchedString() + result = e.(DataFlow::RegExpCreationNode).getRoot().getAMatchedString() or result = e.getStringValue() } @@ -52,8 +52,8 @@ predicate isSimpleAlt(RegExpAlt t) { forall(RegExpTerm ch | ch = t.getAChild() | * Holds if `mce` is of the form `x.replace(re, new)`, where `re` is a global * regular expression and `new` prefixes the matched string with a backslash. */ -predicate isBackslashEscape(StringReplaceCall mce, DataFlow::RegExpLiteralNode re) { - mce.isGlobal() and +predicate isBackslashEscape(StringReplaceCall mce, DataFlow::RegExpCreationNode re) { + mce.maybeGlobal() and re = mce.getRegExp() and ( // replacement with `\$&`, `\$1` or similar @@ -72,7 +72,7 @@ predicate allBackslashesEscaped(DataFlow::Node nd) { nd instanceof JsonStringifyCall or // check whether `nd` itself escapes backslashes - exists(DataFlow::RegExpLiteralNode rel | isBackslashEscape(nd, rel) | + exists(DataFlow::RegExpCreationNode rel | isBackslashEscape(nd, rel) | // if it's a complex regexp, we conservatively assume that it probably escapes backslashes not isSimple(rel.getRoot()) or getAMatchedString(rel) = "\\" @@ -143,12 +143,21 @@ predicate whitelistedRemoval(StringReplaceCall repl) { ) } +/** + * Gets a nice string representation of the pattern or value of the node. + */ +string getPatternOrValueString(DataFlow::Node node) { + if node instanceof DataFlow::RegExpConstructorInvokeNode + then result = "/" + node.(DataFlow::RegExpConstructorInvokeNode).getRoot() + "/" + else result = node.toString() +} + from StringReplaceCall repl, DataFlow::Node old, string msg where (old = repl.getArgument(0) or old = repl.getRegExp()) and ( - not repl.isGlobal() and - msg = "This replaces only the first occurrence of " + old + "." and + not repl.maybeGlobal() and + msg = "This replaces only the first occurrence of " + getPatternOrValueString(old) + "." and // only flag if this is likely to be a sanitizer or URL encoder or decoder exists(string m | m = getAMatchedString(old) | // sanitizer diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index d16f72d4172..997ee8971a5 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -65,8 +65,8 @@ predicate isCaseSensitiveMiddleware( arg = call.getArgument(0) and regexp.getAReference().flowsTo(arg) and exists(string flags | - flags = regexp.getFlags() and - not RegExp::isIgnoreCase(flags) + flags = regexp.tryGetFlags() and + not RegExp::maybeIgnoreCase(flags) ) ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 0022ca69c6b..6a45147a4e2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -1517,6 +1517,207 @@ nodes | TaintedPath.js:198:35:198:38 | path | | TaintedPath.js:198:35:198:38 | path | | TaintedPath.js:198:35:198:38 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:202:24:202:30 | req.url | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:211:24:211:30 | req.url | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | @@ -6680,6 +6881,262 @@ edges | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) | | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) | | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | +| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | | examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath | @@ -10499,6 +10956,9 @@ edges | TaintedPath.js:196:31:196:34 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:196:31:196:34 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:197:45:197:48 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:197:45:197:48 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | | TaintedPath.js:198:35:198:38 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:198:35:198:38 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value | +| TaintedPath.js:206:29:206:85 | path.re ... '), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:206:29:206:85 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value | +| TaintedPath.js:213:29:213:68 | path.re ... '), '') | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:213:29:213:68 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | +| TaintedPath.js:216:31:216:69 | path.re ... '), '') | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:216:31:216:69 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value | | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | This path depends on a $@. | examples/TaintedPath.js:8:28:8:34 | req.url | user-provided value | | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value | | handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js index d28549da0ec..fd768fecfff 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.js @@ -197,3 +197,25 @@ var server = http.createServer(function(req, res) { cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK cp.execFileSync("foobar", {cwd: path}); // NOT OK }); + +var server = http.createServer(function(req, res) { + let path = url.parse(req.url, true).query.path; + + // Removal of forward-slash or dots. + res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", 'g'), ''))); // OK + res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // NOT OK. + res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK -- Might be okay depending on what unknownFlags evaluates to. +}); + +var server = http.createServer(function(req, res) { + let path = url.parse(req.url, true).query.path; + + res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute) + + if (!pathModule.isAbsolute(path)) { + res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // NOT OK + res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // OK + res.write(fs.readFileSync(path.replace(new RegExp("[.]", unknownFlags()), ''))); // OK + } +}); + diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index b4022c8550c..f2fa354a305 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -319,6 +319,15 @@ nodes | lib/lib.js:626:29:626:32 | name | | lib/lib.js:629:25:629:28 | name | | lib/lib.js:629:25:629:28 | name | +| lib/lib.js:632:38:632:41 | name | +| lib/lib.js:632:38:632:41 | name | +| lib/lib.js:633:6:633:68 | sanitized | +| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | +| lib/lib.js:633:24:633:27 | name | +| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:634:22:634:30 | sanitized | +| lib/lib.js:634:22:634:30 | sanitized | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | | lib/subLib2/compiled-file.ts:4:25:4:28 | name | @@ -749,6 +758,14 @@ edges | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | +| lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name | +| lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name | +| lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized | +| lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized | +| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:633:6:633:68 | sanitized | +| lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | +| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | @@ -879,6 +896,8 @@ edges | lib/lib.js:609:10:609:25 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:609:2:609:26 | cp.exec ... + name) | shell command | | lib/lib.js:626:17:626:32 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:626:9:626:33 | cp.exec ... + name) | shell command | | lib/lib.js:629:13:629:28 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:629:5:629:29 | cp.exec ... + name) | shell command | +| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command | +| lib/lib.js:634:10:634:30 | "rm -rf ... nitized | lib/lib.js:632:38:632:41 | name | lib/lib.js:634:22:634:30 | sanitized | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command | | lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/compiled-file.ts:3:26:3:29 | name | library input | lib/subLib2/compiled-file.ts:4:5:4:29 | cp.exec ... + name) | shell command | | lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/special-file.js:3:28:3:31 | name | library input | lib/subLib2/special-file.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib3/my-file.ts:3:28:3:31 | name | library input | lib/subLib3/my-file.ts:4:2:4:26 | cp.exec ... + name) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js index 504de998c1c..09488f0a887 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction/lib/lib.js @@ -628,3 +628,14 @@ module.exports.veryIndeirect = function (name) { cp.exec("rm -rf " + name); // NOT OK } + +module.exports.sanitizer = function (name) { + var sanitized = "'" + name.replace(new RegExp("\'"), "'\\''") + "'" + cp.exec("rm -rf " + sanitized); // NOT OK + + var sanitized = "'" + name.replace(new RegExp("\'", 'g'), "'\\''") + "'" + cp.exec("rm -rf " + sanitized); // OK + + var sanitized = "'" + name.replace(new RegExp("\'", unknownFlags()), "'\\''") + "'" + cp.exec("rm -rf " + sanitized); // OK -- Most likely should be okay and not flagged to reduce false positives. +} diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index feec74921aa..9b764729c99 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -1148,6 +1148,12 @@ nodes | tst.js:501:33:501:63 | decodeU ... n.hash) | | tst.js:501:43:501:62 | window.location.hash | | tst.js:501:43:501:62 | window.location.hash | +| tst.js:508:7:508:39 | target | +| tst.js:508:16:508:39 | documen ... .search | +| tst.js:508:16:508:39 | documen ... .search | +| tst.js:509:18:509:23 | target | +| tst.js:509:18:509:54 | target. ... "), '') | +| tst.js:509:18:509:54 | target. ... "), '') | | typeahead.js:20:13:20:45 | target | | typeahead.js:20:22:20:45 | documen ... .search | | typeahead.js:20:22:20:45 | documen ... .search | @@ -2331,6 +2337,11 @@ edges | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | +| tst.js:508:7:508:39 | target | tst.js:509:18:509:23 | target | +| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target | +| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target | +| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') | +| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') | | typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | @@ -2623,6 +2634,7 @@ edges | tst.js:491:23:491:45 | locatio ... bstr(1) | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:491:23:491:35 | location.hash | user-provided value | | tst.js:494:18:494:40 | locatio ... bstr(1) | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:494:18:494:30 | location.hash | user-provided value | | tst.js:501:33:501:63 | decodeU ... n.hash) | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | Cross-site scripting vulnerability due to $@. | tst.js:501:43:501:62 | window.location.hash | user-provided value | +| tst.js:509:18:509:54 | target. ... "), '') | tst.js:508:16:508:39 | documen ... .search | tst.js:509:18:509:54 | target. ... "), '') | Cross-site scripting vulnerability due to $@. | tst.js:508:16:508:39 | documen ... .search | user-provided value | | typeahead.js:25:18:25:20 | val | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:25:18:25:20 | val | Cross-site scripting vulnerability due to $@. | typeahead.js:20:22:20:45 | documen ... .search | user-provided value | | v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value | | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:4:4:4:31 | "
" ...
" | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 3b1d10d5162..185cae0d2d3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -1160,6 +1160,12 @@ nodes | tst.js:501:33:501:63 | decodeU ... n.hash) | | tst.js:501:43:501:62 | window.location.hash | | tst.js:501:43:501:62 | window.location.hash | +| tst.js:508:7:508:39 | target | +| tst.js:508:16:508:39 | documen ... .search | +| tst.js:508:16:508:39 | documen ... .search | +| tst.js:509:18:509:23 | target | +| tst.js:509:18:509:54 | target. ... "), '') | +| tst.js:509:18:509:54 | target. ... "), '') | | typeahead.js:9:28:9:30 | loc | | typeahead.js:9:28:9:30 | loc | | typeahead.js:9:28:9:30 | loc | @@ -2393,6 +2399,11 @@ edges | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | +| tst.js:508:7:508:39 | target | tst.js:509:18:509:23 | target | +| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target | +| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target | +| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') | +| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js index 3a8c5992645..9a110d0bb72 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js @@ -503,3 +503,10 @@ function Foo() { }; Object.assign(this, obj); } + +function nonGlobalSanitizer() { + var target = document.location.search + $("#foo").html(target.replace(new RegExp("<|>"), '')); // NOT OK + $("#foo").html(target.replace(new RegExp("<|>", unknownFlags()), '')); // OK -- most likely good. We don't know what the flags are. + $("#foo").html(target.replace(new RegExp("<|>", "g"), '')); // OK +} diff --git a/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/DoubleEscaping.expected b/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/DoubleEscaping.expected index 651e9443b3a..9ec4549b7f6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/DoubleEscaping.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/DoubleEscaping.expected @@ -6,3 +6,4 @@ | tst.js:60:7:60:28 | s.repla ... '%25') | This replacement may double-escape '%' characters from $@. | tst.js:59:7:59:28 | s.repla ... '%26') | here | | tst.js:68:10:70:38 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:68:10:69:39 | s.repla ... apos;") | here | | tst.js:79:10:79:66 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:79:10:79:43 | s.repla ... epl[c]) | here | +| tst.js:99:10:101:49 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:99:10:100:51 | s.repla ... apos;") | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/tst.js b/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/tst.js index 76cfe80b238..4fe8c9d6f22 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-116/DoubleEscaping/tst.js @@ -94,3 +94,21 @@ function testWithCapturedVar(x) { function encodeDecodeEncode(s) { return goodEncode(goodDecode(goodEncode(s))); } + +function badEncode(s) { + return s.replace(new RegExp("\"", "g"), """) + .replace(new RegExp("\'", "g"), "'") + .replace(new RegExp("&", "g"), "&"); // NOT OK +} + +function goodEncode(s) { + return s.replace(new RegExp("\"", ""), """) + .replace(new RegExp("\'", ""), "'") + .replace(new RegExp("&", ""), "&"); // OK +} + +function goodEncode(s) { + return s.replace(new RegExp("\"", unknownFlags()), """) + .replace(new RegExp("\'", unknownFlags()), "'") + .replace(new RegExp("&", unknownFlags()), "&"); // OK +} diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected index 4223a4224d3..379ffbdc9c3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteBlacklistSanitizer.expected @@ -65,3 +65,9 @@ | tst.js:305:10:305:34 | s().rep ... ]/g,'') | This HTML sanitizer does not sanitize double quotes | | tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes | | tst.js:320:9:329:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes | +| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize ampersands | +| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize double quotes | +| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize single quotes | +| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize ampersands | +| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize double quotes | +| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize single quotes | diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected index 32400608814..96a48fec6cb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected @@ -39,3 +39,4 @@ | tst-multi-character-sanitization.js:145:13:145:90 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:145:30:145:30 | < |