From b4adfec2efee8d288bc01f5fee7f5fe5ada84274 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 5 Nov 2018 14:19:16 +0000 Subject: [PATCH 01/94] CPP: Add test case. --- .../PointlessSelfComparison.expected | 1 + .../BadAdditionOverflowCheck/test.cpp | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected index 016706c2338..1fb57cdc0b4 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected @@ -3,3 +3,4 @@ | test.cpp:83:10:83:15 | ... == ... | Self comparison. | | test.cpp:90:10:90:15 | ... == ... | Self comparison. | | test.cpp:118:7:118:32 | ... != ... | Self comparison. | +| test.cpp:145:2:145:30 | ... == ... | Self comparison. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp index 25ccbad42fe..a1f5add0e6e 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp @@ -123,3 +123,24 @@ int isSmallEnough(unsigned long long x) { // get compiled away on others. return x == (size_t)x && x == (u64)x; // GOOD } + +#define markRange(str, x, y) \ + if ((x) == (y)) { \ + str[x] = '^'; \ + } else { \ + int i; \ + str[x] = '<'; \ + for (i = x + 1; i < y; i++) { \ + str[i] = '-'; \ + } \ + str[y] = '>'; \ + } + +void useMarkRange(int offs) { + char buffer[100]; + + markRange(buffer, 10, 20); + markRange(buffer, 30, 30); + markRange(buffer, offs, offs + 10); + markRange(buffer, offs, offs); // GOOD (comparison is in the macro) [FALSE POSITIVE] +} From 3cb4211c7814b3ce98f9b1340bc114037a626610 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 5 Nov 2018 15:06:58 +0000 Subject: [PATCH 02/94] CPP: Exclude code in macro invocations. --- cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql | 1 + .../BadAdditionOverflowCheck/PointlessSelfComparison.expected | 1 - .../Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql index 4d0b4184e1d..cf7ba886366 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql +++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql @@ -18,4 +18,5 @@ from ComparisonOperation cmp where pointlessSelfComparison(cmp) and not nanTest(cmp) and not overflowTest(cmp) + and not cmp.isInMacroExpansion() select cmp, "Self comparison." diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected index 1fb57cdc0b4..016706c2338 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected @@ -3,4 +3,3 @@ | test.cpp:83:10:83:15 | ... == ... | Self comparison. | | test.cpp:90:10:90:15 | ... == ... | Self comparison. | | test.cpp:118:7:118:32 | ... != ... | Self comparison. | -| test.cpp:145:2:145:30 | ... == ... | Self comparison. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp index a1f5add0e6e..13fa493da27 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp @@ -142,5 +142,5 @@ void useMarkRange(int offs) { markRange(buffer, 10, 20); markRange(buffer, 30, 30); markRange(buffer, offs, offs + 10); - markRange(buffer, offs, offs); // GOOD (comparison is in the macro) [FALSE POSITIVE] + markRange(buffer, offs, offs); // GOOD (comparison is in the macro) } From 27fe996269c09d29ae28766bafacc75beb879d9b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 5 Nov 2018 15:11:17 +0000 Subject: [PATCH 03/94] CPP: Change note. --- change-notes/1.19/analysis-cpp.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index 4835afd0c70..73dffaba393 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -20,6 +20,7 @@ | Missing return statement (`cpp/missing-return`) | Visible by default | The precision of this query has been increased from 'medium' to 'high', which makes it visible by default in LGTM. It was 'medium' in release 1.17 and 1.18 because it had false positives due to an extractor bug that was fixed in 1.18. | | Missing return statement | Fewer false positive results | The query is now produces correct results when a function returns a template-dependent type. | | Call to memory access function may overflow buffer | More correct results | Array indexing with a negative index is now detected by this query. | +| Self comparison | Fewer false positive results | Code inside macro invocations is now excluded from the query. | | Suspicious call to memset | Fewer false positive results | Types involving decltype are now correctly compared. | | Suspicious add with sizeof | Fewer false positive results | Arithmetic with void pointers (where allowed) is now excluded from this query. | | Wrong type of arguments to formatting function | Fewer false positive results | False positive results involving typedefs have been removed. Expected argument types are determined more accurately, especially for wide string and pointer types. Custom (non-standard) formatting functions are also identified more accurately. | From 21887d7c6f90861569156d8e1df40f582cfdcf4a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 8 Nov 2018 15:03:30 +0100 Subject: [PATCH 04/94] C#: Refactor SSA liveness logic Simplify liveness analysis by avoiding the two extra copies of `liveAtRank()` (and other auxiliary predicates) for fields/captured variables analysis. --- .../src/semmle/code/csharp/dataflow/SSA.qll | 314 ++++++++---------- 1 file changed, 136 insertions(+), 178 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll index 09f1fa9f073..4c4da9cfe4c 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll @@ -319,59 +319,28 @@ module Ssa { } /** - * Same as `variableWrite()`, but extended to include implicit call definitions - * for fields and properties. + * Holds if source varible `v` is likely to be live at any node inside basic + * block `bb`. */ - private predicate variableWriteExt(BasicBlock bb, int i, SourceVariable v, boolean certain) { - variableWrite(bb, i, v, certain) + predicate likelyLive(BasicBlock bb, SourceVariable v) { + liveAtExit(bb, v, _) or - variableWriteExt(bb, i, v.(QualifiedFieldOrPropSourceVariable).getQualifier(), certain) - or - exists(Call c | - bb.getNode(i) = c.getAControlFlowNode() | - updatesNamedFieldOrProp(c, v, _) and - certain = false - ) - } - - /** - * Same as `ref()`, but extended to include implicit call definitions - * for fields and properties. - */ - private predicate refExt(BasicBlock bb, int i, SourceVariable v, RefKind k) { - exists(ReadKind rk | - variableRead(bb, i, v, _, rk) | - k = Read(rk) - ) - or - exists(boolean certain | - variableWriteExt(bb, i, v, certain) | - k = Write(certain) - ) - } - - /** - * Same as `refRank()`, but extended to include implicit call definitions - * for fields and properties. - */ - private int refRankExt(BasicBlock bb, int i, SourceVariable v, RefKind k) { - i = rank[result](int j | refExt(bb, j, v, _)) and - refExt(bb, i, v, k) + ref(bb, _, v, Read(_)) } /** * Holds if variable `v` is live in basic block `bb` at index `i`. - * The rank of `i` is `rnk` as defined by `refRankExt()`. + * The rank of `i` is `rnk` as defined by `refRank()`. */ - private predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk, ReadKind rk) { - rnk = refRankExt(bb, i, v, _) and + predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk, ReadKind rk) { + rnk = refRank(bb, i, v, _) and ( - rnk = max(refRankExt(bb, _, v, _)) and + rnk = max(refRank(bb, _, v, _)) and liveAtExit(bb, v, rk) or ref(bb, i, v, Read(rk)) or - exists(int j | liveAtRank(bb, j, v, rnk + 1, rk) | not refExt(bb, j, v, Write(true))) + exists(int j | liveAtRank(bb, j, v, rnk + 1, rk) | not ref(bb, j, v, Write(true))) ) } @@ -382,7 +351,7 @@ module Ssa { */ predicate liveAfterWrite(BasicBlock bb, int i, SourceVariable v, ReadKind rk) { exists (int rnk | - rnk = refRankExt(bb, i, v, Write(_)) | + rnk = refRank(bb, i, v, Write(_)) | liveAtRank(bb, i, v, rnk, rk) ) } @@ -1222,74 +1191,31 @@ module Ssa { setsOtherFieldOrProp(c, fp) and c = setter } + pragma[noinline] + predicate callAt(BasicBlock bb, int i, Call call) { + bb.getNode(i) = call.getAControlFlowNode() and + getARuntimeTarget(call).hasBody() + } + /** * Holds if `call` occurs in basic block `bb` at index `i`, `fp` has - * an update somewhere, and `fp` is accessed somewhere inside the callable - * to which `bb` belongs. + * an update somewhere, and `fp` is likely to be live in `bb` at index + * `i`. */ private predicate updateCandidate(BasicBlock bb, int i, TrackedFieldOrProp fp, Call call) { - bb.getNode(i) = call.getAControlFlowNode() and - call.getEnclosingCallable() = fp.getEnclosingCallable() and - relevantDefinition(_, fp.getAssignable(), _) - } - - /** - * Same as `ref()`, but extended to include implicit call definitions - * for fields and properties. - */ - private predicate refExt(BasicBlock bb, int i, TrackedFieldOrProp fp) { - ref(bb, i, fp, _) - or - updateCandidate(bb, i, fp, _) and + likelyLive(bb, fp) and + callAt(bb, i, call) and + relevantDefinition(_, fp.getAssignable(), _) and not ref(bb, i, fp, _) } - /** - * Same as `refRank()`, but extended to include implicit call definitions - * for fields and properties, and restricted to basic blocks that have - * a potential implicit call definition. - */ - private int refRankExt(BasicBlock bb, int i, TrackedFieldOrProp fp) { - updateCandidate(bb, _, fp, _) and - i = rank[result](int j | refExt(bb, j, fp)) and - refExt(bb, i, fp) - } - - /** - * Holds if field or property `fp` is live in basic block `bb` at index `i`. - * The rank of `i` is `rnk` as defined by `refRankExt()`. - */ - private predicate liveAtRank(BasicBlock bb, int i, TrackedFieldOrProp fp, int rnk) { - rnk = refRankExt(bb, i, fp) and - ( - rnk = max(refRankExt(bb, _, fp)) and - liveAtExit(bb, fp, _) - or - ref(bb, i, fp, Read(_)) - or - exists(int j | liveAtRank(bb, j, fp, rnk + 1) | not ref(bb, j, fp, Write(true))) - ) - } - - /** - * Holds if field or property `fp` is live after the potential update at call `c`. - */ - private predicate liveAfterUpdateCandidate(Call c, TrackedFieldOrProp fp) { - exists(BasicBlock bb, int i, int rnk | - updateCandidate(bb, i, fp, c) | - not ref(bb, i, fp, _) and - rnk = refRankExt(bb, i, fp) and - liveAtRank(bb, i, fp, rnk) - ) - } - /** * Holds if `c` is a relevant part of the call graph for * `updatesNamedFieldOrPropPart1` based on following edges in forward direction. */ private predicate pruneFromLeft(Callable c) { exists(Call call, TrackedFieldOrProp f | - liveAfterUpdateCandidate(call, f) and + updateCandidate(_, _, f, call) and c = getARuntimeTarget(call) and generalSetter(_, f.getAssignable(), _) ) @@ -1330,7 +1256,7 @@ module Ssa { pragma [noinline] private predicate updatesNamedFieldOrPropPart1Prefix0(Call call, TrackedFieldOrProp tfp, Callable c1, FieldOrProp fp) { - liveAfterUpdateCandidate(call, tfp) and + updateCandidate(_, _, tfp, call) and fp = tfp.getAssignable() and generalSetter(_, fp, _) and c1 = getARuntimeTarget(call) @@ -1353,7 +1279,7 @@ module Ssa { * may not alias with `this`. The actual update occurs in `setter`. */ pragma [noopt] - predicate updatesNamedFieldOrPropPart1(Call call, TrackedFieldOrProp tfp, Callable setter) { + private predicate updatesNamedFieldOrPropPart1(Call call, TrackedFieldOrProp tfp, Callable setter) { exists(Callable c1, Callable c2, FieldOrProp fp | updatesNamedFieldOrPropPart1Prefix(call, tfp, c1, setter, fp) and generalSetter(c2, fp, setter) | @@ -1365,10 +1291,79 @@ module Ssa { * Holds if `call` may change the value of `tfp` on `this`. The actual update occurs * in `setter`. */ - predicate updatesNamedFieldOrPropPart2(Call call, TrackedFieldOrProp tfp, Callable setter) { - liveAfterUpdateCandidate(call, tfp) and + private predicate updatesNamedFieldOrPropPart2(Call call, TrackedFieldOrProp tfp, Callable setter) { + updateCandidate(_, _, tfp, call) and setsOwnFieldOrPropTransitive(getARuntimeTarget(call), tfp.getAssignable(), setter) } + + private predicate updatesNamedFieldOrPropLikelyLive(BasicBlock bb, int i, TrackedFieldOrProp fp, Call call, Callable setter) { + updateCandidate(bb, i, fp, call) and + ( + updatesNamedFieldOrPropPart1(call, fp, setter) + or + updatesNamedFieldOrPropPart2(call, fp, setter) + ) + } + + private int firstRefAfterCall(BasicBlock bb, int i, TrackedFieldOrProp fp) { + updatesNamedFieldOrPropLikelyLive(bb, i, fp, _, _) and + result = min(int k | k > i and ref(bb, k, fp, _)) + } + + /** + * Holds if `call` may change the value of field or property `fp`. The actual + * update occurs in `setter`. + */ + cached + predicate updatesNamedFieldOrProp(Call c, TrackedFieldOrProp fp, Callable setter) { + forceCachingInSameStage() and + exists(BasicBlock bb, int i | + updatesNamedFieldOrPropLikelyLive(bb, i, fp, c, setter) | + not exists(firstRefAfterCall(bb, i, fp)) and + liveAtExit(bb, fp, _) + or + exists(int j | + j = firstRefAfterCall(bb, i, fp) | + liveAtRank(bb, j, fp, _, _) and + not ref(bb, j, fp, Write(true)) + ) + ) + } + + /** + * Same as `variableWrite()`, but extended to include implicit call definitions + * for fields and properties. + */ + private predicate variableWriteExt(BasicBlock bb, int i, SourceVariable v) { + ref(bb, i, v, Write(_)) + or + variableWriteExt(bb, i, v.(QualifiedFieldOrPropSourceVariable).getQualifier()) + or + exists(Call c | callAt(bb, i, c) | updatesNamedFieldOrProp(c, v, _)) + } + + private int firstRefAfterQualifiedDef(BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable q) { + variableWriteExt(bb, i, q) and + result = min(int k | k > i and ref(bb, k, q, _)) + } + + /** + * Holds if qualified field or property `q` is live after the (certain or + * uncertain) write at index `i` inside basic block `bb`. + */ + predicate liveAfterWriteQualified(BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable q) { + variableWriteExt(bb, i, q) and + ( + not exists(firstRefAfterQualifiedDef(bb, i, q)) and + liveAtExit(bb, q, _) + or + exists(int j | + j = firstRefAfterQualifiedDef(bb, i, q) | + liveAtRank(bb, j, q, _, _) and + not ref(bb, j, q, Write(true)) + ) + ) + } } private import FieldOrPropsImpl @@ -1440,72 +1435,22 @@ module Ssa { /** * Holds if `call` occurs in basic block `bb` at index `i`, captured variable - * `v` has an update somewhere, and `v` is accessed somewhere inside the callable - * to which `bb` belongs. + * `v` has an update somewhere, and `v` is likely to be live in `bb` at index + * `i`. */ private predicate updateCandidate(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v, Call call) { - bb.getNode(i) = call.getAControlFlowNode() and - call.getEnclosingCallable() = v.getEnclosingCallable() and + likelyLive(bb, v) and + callAt(bb, i, call) and relevantDefinition(_, v.getAssignable(), _) } - /** - * Same as `ref()`, but extended to include implicit call definitions - * for captured variables. - */ - private predicate refExt(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v) { - ref(bb, i, v, _) - or - updateCandidate(bb, i, v, _) and - not ref(bb, i, v, _) - } - - /** - * Same as `refRank()`, but extended to include implicit call definitions - * for captured variables, and restricted to basic blocks that have a - * potential implicit call definition. - */ - private int refRankExt(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v) { - updateCandidate(bb, _, v, _) and - i = rank[result](int j | refExt(bb, j, v)) and - refExt(bb, i, v) - } - - /** - * Holds if captured source variable `v` is live in basic block `bb` at index `i`. - * The rank of `i` is `rnk` as defined by `refRankExt()`. - */ - private predicate liveAtRank(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v, int rnk) { - rnk = refRankExt(bb, i, v) and - ( - rnk = max(refRankExt(bb, _, v)) and - liveAtExit(bb, v, _) - or - ref(bb, i, v, Read(_)) - or - exists(int j | liveAtRank(bb, j, v, rnk + 1) | not ref(bb, j, v, Write(true))) - ) - } - - /** - * Holds if captured source variable `v` is live after the potential update at call `c`. - */ - private predicate liveAfterUpdateCandidate(Call c, CapturedWrittenLocalScopeSourceVariable v) { - exists(BasicBlock bb, int i, int rnk | - updateCandidate(bb, i, v, c) | - not ref(bb, i, v, _) and - rnk = refRankExt(bb, i, v) and - liveAtRank(bb, i, v, rnk) - ) - } - /** * Holds if `c` is a relevant part of the call graph for * `updatesCapturedVariable` based on following edges in forward direction. */ private predicate pruneFromLeft(Callable c) { exists(Call call, CapturedWrittenLocalScopeSourceVariable v | - liveAfterUpdateCandidate(call, v) and + updateCandidate(_, _, v, call) and c = getARuntimeTarget(call) and relevantDefinition(_, v.getAssignable(), _) ) @@ -1551,7 +1496,7 @@ module Ssa { pragma [noinline] private predicate updatesCapturedVariablePrefix(Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable c, CapturedWrittenLocalScopeVariable captured) { - liveAfterUpdateCandidate(call, v) and + updateCandidate(_, _, v, call) and captured = v.getAssignable() and relevantDefinitionProj(_, captured) and c = getARuntimeTarget(call) @@ -1573,14 +1518,42 @@ module Ssa { ) } - // A non-cached helper predicate that is cached in a cached module further down, - // to make sure the predicate is evaluated in the same stage as other cached predicates - predicate updatesCapturedVariableNonCached(Call call, CapturedWrittenLocalScopeSourceVariable v, AssignableDefinition def) { + /** + * Holds if `call` may change the value of captured variable `v`. The actual + * update occurs in `def`. + */ + private predicate updatesCapturedVariableLikelyLive(BasicBlock bb, int i, Call call, LocalScopeSourceVariable v, AssignableDefinition def) { + updateCandidate(bb, i, v, call) and exists(Callable writer | relevantDefinition(writer, v.getAssignable(), def) | updatesCapturedVariableWriter(call, v, writer) ) } + + private int firstRefAfter(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v) { + updatesCapturedVariableLikelyLive(bb, i, _, v, _) and + result = min(int k | k > i and ref(bb, k, v, _)) + } + + /** + * Holds if `call` may change the value of captured variable `v`. The actual + * update occurs in `def`. + */ + cached + predicate updatesCapturedVariable(Call call, LocalScopeSourceVariable v, AssignableDefinition def) { + forceCachingInSameStage() and + exists(BasicBlock bb, int i | + updatesCapturedVariableLikelyLive(bb, i, call, v, def) | + not exists(firstRefAfter(bb, i, v)) and + liveAtExit(bb, v, _) + or + exists(int j | + j = firstRefAfter(bb, i, v) | + liveAtRank(bb, j, v, _, _) and + not ref(bb, j, v, Write(true)) + ) + ) + } } private import CapturedVariableImpl @@ -1830,6 +1803,8 @@ module Ssa { private import CapturedVariableLivenessImpl private cached module SsaImpl { + cached predicate forceCachingInSameStage() { any() } + /** * A data type representing SSA definitions. * @@ -1905,7 +1880,7 @@ module Ssa { exists(BasicBlock bb, int i | qdef.getSourceVariable() = v.getQualifier() and qdef.definesAt(bb, i) and - liveAfterWrite(bb, i, v, _) and + liveAfterWriteQualified(bb, i, v) and // Eliminate corner case where a call definition can overlap with a // qualifier definition: if method `M` updates field `F`, then a call // to `M` is both an update of `x.M` and `x.M.M`, so the former call @@ -1952,23 +1927,6 @@ module Ssa { def = TPhiNode(v, bb) and i = -1 } - /** - * Holds if `call` may change the value of field or property `fp`. The actual - * update occurs in `setter`. - */ - cached predicate updatesNamedFieldOrProp(Call call, TrackedFieldOrProp fp, Callable setter) { - updatesNamedFieldOrPropPart1(call, fp, setter) or - updatesNamedFieldOrPropPart2(call, fp, setter) - } - - /** - * Holds if `call` may change the value of captured variable `v`. The actual - * update occurs in `def`. - */ - cached predicate updatesCapturedVariable(Call call, LocalScopeSourceVariable v, AssignableDefinition def) { - updatesCapturedVariableNonCached(call, v, def) - } - cached predicate isCapturedVariableDefinitionFlowIn(ExplicitDefinition def, ImplicitEntryDefinition edef, Call c) { exists(BasicBlock bb, int i, LocalScopeSourceVariable v | definesAt(def, bb, i, v) | From 93b3165e86d2b2b99d8c1337b0984695ab2300e4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Nov 2018 16:08:06 +0000 Subject: [PATCH 05/94] CPP: Tag Magic*UseConstant queries. --- .../Best Practices/Magic Constants/MagicNumbersUseConstant.ql | 2 ++ .../Best Practices/Magic Constants/MagicStringsUseConstant.ql | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql b/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql index 1a9852990ff..2c8ceac2753 100644 --- a/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql +++ b/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/use-number-constant * @problem.severity recommendation + * @precision low + * @tags maintainability */ import cpp import MagicConstants diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql b/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql index 990de6048e5..9cd129c88dc 100644 --- a/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql +++ b/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/use-string-constant * @problem.severity recommendation + * @precision low + * @tags maintainability */ import cpp import MagicConstants From 850937efcc1dd417ef40c599e32a33616b89f242 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Nov 2018 16:21:18 +0000 Subject: [PATCH 06/94] CPP: Tag Include queries. --- cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql index c8480a037b6..42d5d910fb7 100644 --- a/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql +++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql @@ -4,7 +4,10 @@ * the included elements are used. * @kind problem * @id cpp/unused-includes - * @problem.severity warning + * @problem.severity recommendation + * @precision low + * @tags maintainability + * useless-code */ import cpp From bcb4ebffc30a4ae02b4e45ae96763eaa36aa77dd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Nov 2018 16:45:35 +0000 Subject: [PATCH 07/94] CPP: Tag NVI queries. --- cpp/ql/src/Best Practices/NVI.ql | 4 +++- cpp/ql/src/Best Practices/NVIHub.ql | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Best Practices/NVI.ql b/cpp/ql/src/Best Practices/NVI.ql index 5e5a20fd15a..723395769c3 100644 --- a/cpp/ql/src/Best Practices/NVI.ql +++ b/cpp/ql/src/Best Practices/NVI.ql @@ -4,7 +4,9 @@ * to enforce invariants that should hold for the whole hierarchy. * @kind problem * @id cpp/nvi - * @problem.severity warning + * @problem.severity recommendation + * @precision low + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/Best Practices/NVIHub.ql b/cpp/ql/src/Best Practices/NVIHub.ql index 6d4600b68f9..8f87c89809a 100644 --- a/cpp/ql/src/Best Practices/NVIHub.ql +++ b/cpp/ql/src/Best Practices/NVIHub.ql @@ -6,6 +6,9 @@ * dependencies or dependents. * @kind table * @id cpp/nvi-hub + * @problem.severity recommendation + * @precision low + * @tags maintainability */ import cpp From 1c27c5e5edf827c9c4d96edbb7890062c8cdae46 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Nov 2018 16:50:13 +0000 Subject: [PATCH 08/94] CPP: Tag Padding queries. --- .../Likely Bugs/Memory Management/Padding/More64BitWaste.ql | 2 ++ .../Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql | 2 ++ .../Memory Management/Padding/Suboptimal64BitType.ql | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql b/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql index c82d86aadfd..da5be6e494f 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/more-64-bit-waste * @problem.severity warning + * @tags maintainability + * portability */ import semmle.code.cpp.padding.Padding diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql b/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql index 95383e86fa5..1c1bce79457 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql @@ -5,6 +5,8 @@ * @kind problem * @id cpp/non-portable-printf * @problem.severity warning + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql b/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql index 8578324883a..1f52a265d0a 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql @@ -4,7 +4,8 @@ * that by reordering them one could reduce the amount of internal padding on a 64-bit architecture. * @kind problem * @id cpp/suboptimal-64-bit-type - * @problem.severity warning + * @problem.severity recommendation + * @tags efficiency */ import semmle.code.cpp.padding.Padding From 1d87c580b39892200422187b6870de26aa06d0be Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Wed, 8 Aug 2018 08:26:37 +0200 Subject: [PATCH 09/94] JS: introduce DefinedCustomAbstractValue --- .../dataflow/DefinedCustomAbstractValues.qll | 153 ++++++++++++++++++ .../dataflow/internal/AbstractValuesImpl.qll | 4 + .../DefinedCustomAbstractValue.expected | 2 + .../DefinedCustomAbstractValue.ql | 57 +++++++ .../DefinedCustomAbstractValueFlow.expected | 8 + .../DefinedCustomAbstractValueFlow.ql | 40 +++++ .../DefinedCustomAbstractValue/tst.js | 22 +++ 7 files changed, 286 insertions(+) create mode 100644 javascript/ql/src/semmle/javascript/dataflow/DefinedCustomAbstractValues.qll create mode 100644 javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected create mode 100644 javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql create mode 100644 javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.expected create mode 100644 javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql create mode 100644 javascript/ql/test/library-tests/DefinedCustomAbstractValue/tst.js diff --git a/javascript/ql/src/semmle/javascript/dataflow/DefinedCustomAbstractValues.qll b/javascript/ql/src/semmle/javascript/dataflow/DefinedCustomAbstractValues.qll new file mode 100644 index 00000000000..5f94b9ccea4 --- /dev/null +++ b/javascript/ql/src/semmle/javascript/dataflow/DefinedCustomAbstractValues.qll @@ -0,0 +1,153 @@ +/** + * Provides classes for working with analysis-specific abstract values. + * + * Implement a subclass of `CustomAbstractValueDefinition` When the builtin + * abstract values of `AbstractValues.qll` are not expressive enough. + * + * For performance reasons, all subclasses of `CustomAbstractValueDefinition` + * should be part of the standard library. + */ + +import javascript +private import internal.AbstractValuesImpl +private import InferredTypes + +/** + * An abstract representation of an analysis-specific value. + * + * Wraps a `CustomAbstractValueDefinition`. + */ +class DefinedCustomAbstractValue extends AbstractValue, TDefinedCustomAbstractValue { + + CustomAbstractValueDefinition def; + + DefinedCustomAbstractValue() { + this = TDefinedCustomAbstractValue(def) + } + + override InferredType getType() { + result = def.getType() + } + + override boolean getBooleanValue() { + result = def.getBooleanValue() + } + + override PrimitiveAbstractValue toPrimitive() { + result = def.toPrimitive() + } + + override predicate isCoercibleToNumber() { + def.isCoercibleToNumber() + } + + override predicate isIndefinite(DataFlow::Incompleteness cause) { + def.isIndefinite(cause) + } + + override DefiniteAbstractValue getAPrototype() { + result = def.getAPrototype() + } + + override predicate hasLocationInfo(string f, int startline, int startcolumn, int endline, int endcolumn) { + def.getLocation().hasLocationInfo(f, startline, startcolumn, endline, endcolumn) + } + + override string toString() { + result = def.toString() + } + + CustomAbstractValueDefinition getDefinition() { + result = def + } + + predicate shouldTrackProperties() { + def.shouldTrackProperties() + } + +} + +/** + * A node that induces an analysis-specific abstract value. + * + * Enables modular extensions of `AbstractValue`. + * + * For performance reasons, all subclasses of this class should be part + * of the standard library. + */ +abstract class CustomAbstractValueDefinition extends Locatable { + + /** + * Gets the type of some concrete value represented by the induced + * abstract value. + */ + abstract InferredType getType(); + + /** + * Gets the Boolean value that some concrete value represented by the + * induced abstract value coerces to. + */ + abstract boolean getBooleanValue(); + + /** + * Gets an abstract primitive value the induced abstract value coerces + * to. + * + * This abstractly models the `ToPrimitive` coercion described in the + * ECMAScript language specification. + */ + abstract PrimitiveAbstractValue toPrimitive(); + + /** + * Holds if the induced abstract value is coercible to a number, that + * is, it represents at least one concrete value for which the + * `ToNumber` conversion does not yield `NaN`. + */ + abstract predicate isCoercibleToNumber(); + + /** + * Holds if the induced abstract value is an indefinite value arising + * from the incompleteness `cause`. + */ + predicate isIndefinite(DataFlow::Incompleteness cause) { + none() + } + + /** + * Gets an abstract value that represents a prototype object of the + * induced abstract value. + */ + AbstractValue getAPrototype() { + exists (AbstractProtoProperty proto | + proto.getBase() = getAbstractValue() and + result = proto.getAValue() + ) + } + + /** + * Gets the induced abstract value. + */ + AbstractValue getAbstractValue() { + result.(DefinedCustomAbstractValue).getDefinition() = this + } + + abstract predicate shouldTrackProperties(); + +} + +/** + * Flow analysis for custom abstract values. + */ +class DefinedCustomAbstractValueNode extends DataFlow::AnalyzedNode, DataFlow::ValueNode { + + DefinedCustomAbstractValue val; + + DefinedCustomAbstractValueNode() { + val = TDefinedCustomAbstractValue(this.getAstNode()) + } + + override AbstractValue getALocalValue() { + result = val + } + +} \ No newline at end of file diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll index bd6c7ea996e..ae8c0b3b39a 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll @@ -6,6 +6,7 @@ import semmle.javascript.dataflow.AbstractValues private import semmle.javascript.dataflow.InferredTypes +import semmle.javascript.dataflow.DefinedCustomAbstractValues /** An abstract value inferred by the flow analysis. */ cached newtype TAbstractValue = @@ -101,6 +102,9 @@ cached newtype TAbstractValue = or /** A custom abstract value induced by `tag`. */ TCustomAbstractValue(CustomAbstractValueTag tag) + or + /** A custom abstract value induced by `def`. */ + TDefinedCustomAbstractValue(CustomAbstractValueDefinition def) /** * Gets a definite abstract value with the given type. diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected new file mode 100644 index 00000000000..3cf6829932b --- /dev/null +++ b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected @@ -0,0 +1,2 @@ +| tst.js:4:16:4:50 | { custo ... false } | tst.js:4:16:4:50 | { custo ... false } | false | false | +| tst.js:5:16:5:49 | { custo ... true } | tst.js:5:16:5:49 | { custo ... true } | false | false | diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql new file mode 100644 index 00000000000..689d04b3c19 --- /dev/null +++ b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql @@ -0,0 +1,57 @@ +import javascript +import semmle.javascript.dataflow.InferredTypes +import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps +import semmle.javascript.dataflow.internal.AbstractPropertiesImpl as AbstractPropertiesImpl +import semmle.javascript.dataflow.DefinedCustomAbstractValues + +class MyCustomAbstractValueDefinition extends CustomAbstractValueDefinition { + + DataFlow::ValueNode node; + + MyCustomAbstractValueDefinition() { + DataFlow::valueNode(this) = node and + node instanceof DataFlow::ObjectLiteralNode and + exists (DataFlow::PropWrite pwn | + pwn.writes(node, "custom", any(BooleanLiteral l | l.getValue() = "true").flow()) + ) + } + + override boolean getBooleanValue() { + result = true + } + + override predicate isCoercibleToNumber() { + none() + } + + override PrimitiveAbstractValue toPrimitive() { + result = TAbstractOtherString() + } + + override InferredType getType() { result = TTObject() } + + override predicate shouldTrackProperties() { + exists (DataFlow::PropWrite pwn | + pwn.writes(node, "trackProps", any(BooleanLiteral l | l.getValue() = "true").flow()) + ) + } + +} + +boolean flowProps(AbstractValue val) { + if FlowSteps::shouldTrackProperties(val) then + result = true + else + result = false +} + +boolean typeProps(AbstractValue val) { + if AbstractPropertiesImpl::shouldTrackProperties(val) then + result = true + else + result = false +} + +from MyCustomAbstractValueDefinition def, AbstractValue val +where def.getAbstractValue() = val +select def, val, flowProps(val), typeProps(val) diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.expected b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.expected new file mode 100644 index 00000000000..e75af733c53 --- /dev/null +++ b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.expected @@ -0,0 +1,8 @@ +| tst.js:4:16:4:50 | { custo ... false } | tst.js:4:16:4:50 | { custo ... false } | +| tst.js:5:16:5:49 | { custo ... true } | tst.js:5:16:5:49 | { custo ... true } | +| tst.js:15:9:15:21 | result = obj3 | tst.js:4:16:4:50 | { custo ... false } | +| tst.js:15:18:15:21 | obj3 | tst.js:4:16:4:50 | { custo ... false } | +| tst.js:18:9:18:21 | result = obj4 | tst.js:5:16:5:49 | { custo ... true } | +| tst.js:18:18:18:21 | obj4 | tst.js:5:16:5:49 | { custo ... true } | +| tst.js:21:5:21:10 | result | tst.js:4:16:4:50 | { custo ... false } | +| tst.js:21:5:21:10 | result | tst.js:5:16:5:49 | { custo ... true } | diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql new file mode 100644 index 00000000000..859ca79d0af --- /dev/null +++ b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql @@ -0,0 +1,40 @@ +import javascript +import semmle.javascript.dataflow.InferredTypes +import semmle.javascript.dataflow.DefinedCustomAbstractValues + +class MyCustomAbstractValueDefinition extends CustomAbstractValueDefinition { + + DataFlow::ValueNode node; + + MyCustomAbstractValueDefinition() { + DataFlow::valueNode(this) = node and + node instanceof DataFlow::ObjectLiteralNode and + exists (DataFlow::PropWrite pwn | + pwn.writes(node, "custom", any(BooleanLiteral l | l.getValue() = "true").flow()) + ) + } + + override boolean getBooleanValue() { + result = true + } + + override predicate isCoercibleToNumber() { + none() + } + + override PrimitiveAbstractValue toPrimitive() { + result = TAbstractOtherString() + } + + override InferredType getType() { result = TTObject() } + + override predicate shouldTrackProperties() { + none() + } + +} + +from AnalyzedValueNode n, MyCustomAbstractValueDefinition def, DefinedCustomAbstractValue val +where def.getAbstractValue() = val and + n.getAValue() = val +select n, val \ No newline at end of file diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/tst.js b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/tst.js new file mode 100644 index 00000000000..f89eaba4854 --- /dev/null +++ b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/tst.js @@ -0,0 +1,22 @@ +(function() { + var obj1 = { custom: false, trackProps: false }; + var obj2 = { custom: false, trackProps: true }; + var obj3 = { custom: true, trackProps: false }; + var obj4 = { custom: true, trackProps: true }; + + var result; + if (x1) { + result = obj1; + } + if (x2) { + result = obj2; + } + if (x3) { + result = obj3; + } + if (x4) { + result = obj4; + } + + result; +})(); From daed0653cb50a3ffa988d046a7675ae5762dc8b2 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Tue, 13 Nov 2018 11:29:35 +0100 Subject: [PATCH 10/94] JS: support property tracking of custom abstract values --- .../javascript/dataflow/internal/AbstractPropertiesImpl.qll | 3 ++- .../ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll | 3 ++- .../DefinedCustomAbstractValue.expected | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll index bcf572aae61..8af16f4b9d5 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll @@ -77,5 +77,6 @@ predicate shouldAlwaysTrackProperties(AbstractValue baseVal) { predicate shouldTrackProperties(AbstractValue baseVal) { shouldAlwaysTrackProperties(baseVal) or baseVal instanceof AbstractObjectLiteral or - baseVal instanceof AbstractInstance + baseVal instanceof AbstractInstance or + baseVal.(DefinedCustomAbstractValue).shouldTrackProperties() } diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll index f70f6ea20af..16ba5e9aa7d 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -14,7 +14,8 @@ import semmle.javascript.dataflow.Configuration */ predicate shouldTrackProperties(AbstractValue obj) { obj instanceof AbstractExportsObject or - obj instanceof AbstractModuleObject + obj instanceof AbstractModuleObject or + obj.(DefinedCustomAbstractValue).shouldTrackProperties() } /** diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected index 3cf6829932b..15298d15903 100644 --- a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected +++ b/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected @@ -1,2 +1,2 @@ | tst.js:4:16:4:50 | { custo ... false } | tst.js:4:16:4:50 | { custo ... false } | false | false | -| tst.js:5:16:5:49 | { custo ... true } | tst.js:5:16:5:49 | { custo ... true } | false | false | +| tst.js:5:16:5:49 | { custo ... true } | tst.js:5:16:5:49 | { custo ... true } | true | true | From f9612a8f2136258326b3e44a5fed70a5c6208c1c Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Wed, 14 Nov 2018 16:21:15 +0000 Subject: [PATCH 11/94] Minor updates for consistency --- .../Naming Conventions/ControlNamePrefixes.qhelp | 2 +- .../Naming Conventions/ControlNamePrefixes.ql | 4 ++-- .../Naming Conventions/DefaultControlNames.qhelp | 7 ++++--- .../Naming Conventions/DefaultControlNames.ql | 3 ++- .../Naming Conventions/VariableNameTooShort.qhelp | 2 +- .../Naming Conventions/VariableNameTooShort.ql | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp index faf3e92865c..2ad98182009 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp +++ b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp @@ -8,7 +8,7 @@ This makes the controls easier to find in Intellisense and also makes the purpos -

Give controls an appropriate prefix to indicate their type (e.g. txt for text boxes or rad for +

Give controls an appropriate prefix to indicate their type (for example, txt for text boxes or rad for radio buttons).

diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql index c45e91e117b..4c0814f6ae8 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql +++ b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.ql @@ -1,7 +1,7 @@ /** * @name ASP.NET control name prefixes - * @description This query checks that certain prefixes are used for naming fields for - * ASP.NET Web / HTML controls. + * @description Including standard prefixes in the field names of + * ASP.NET Web / HTML controls makes code easier to understand. * @kind problem * @problem.severity recommendation * @precision medium diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp index f16003b96ff..77562769526 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp +++ b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp @@ -3,11 +3,12 @@ "qhelp.dtd"> -

This rule identifies Windows form controls that have a default name such as textBox1 -.

+

This query identifies Windows form controls that have a default name such as textBox1 +. Replacing the default names with names that describe their purpose makes it much easier to for other +developers to understand your code.

-

Give controls meaningful names that relate to their purpose.

+

Give controls meaningful names that indicate their purpose.

diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql index c97f271d6d3..28a238febba 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql +++ b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql @@ -1,6 +1,7 @@ /** * @name Windows controls with generated names - * @description Finds fields, corresponding to windows-forms controls, with generated names (such as "label1" or "PictureBox4"). + * @description Replacing the generated names in windows forms with meaningful names + makes it easier for other developers to understand the code. * @kind problem * @problem.severity recommendation * @precision medium diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.qhelp b/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.qhelp index 4ba33ffdf09..41e1ac06449 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.qhelp +++ b/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.qhelp @@ -3,7 +3,7 @@ "qhelp.dtd"> -

Source code with lots of short variable names is likely to be hard to read.

+

Source code with lots of short variable names is likely to be difficult to read.

diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql b/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql index e7660b72825..90b31d1886e 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql +++ b/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql @@ -1,6 +1,6 @@ /** * @name Variable name is too short - * @description Variables should have meaningful names so that code is comprehensible. This query finds variable names that are too short. + * @description Using meaningful names for variables makes code easier to understand. * @kind problem * @problem.severity recommendation * @precision low From 39ef869e21fad7ff4a8cc4e3b1936734e4800ec6 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Wed, 14 Nov 2018 16:49:30 +0000 Subject: [PATCH 12/94] Fix partial edit - thanks Tom --- .../Bad Practices/Naming Conventions/DefaultControlNames.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp index 77562769526..e5fc96bbaba 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp +++ b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.qhelp @@ -4,7 +4,7 @@

This query identifies Windows form controls that have a default name such as textBox1 -. Replacing the default names with names that describe their purpose makes it much easier to for other +. Replacing the default names with names that describe their purpose makes it much easier for other developers to understand your code.

From 5cddabb1fdfd4677a98f06da6c787bdcd53bb186 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 14 Nov 2018 19:05:35 +0000 Subject: [PATCH 13/94] CPP: Add a test of AV Rule 165. --- .../AV Rule 165/AV Rule 165.expected | 10 +++++++ .../AV Rule 165/AV Rule 165.qlref | 1 + .../jsf/4.21 Operators/AV Rule 165/test.c | 27 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected create mode 100644 cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.qlref create mode 100644 cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected new file mode 100644 index 00000000000..8cbaac1f40b --- /dev/null +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected @@ -0,0 +1,10 @@ +| test.c:6:6:6:8 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:9:7:9:9 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:12:7:12:9 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:18:7:18:14 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:19:7:19:23 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:20:7:20:21 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:22:8:22:11 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:23:8:23:11 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:24:6:24:7 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:25:7:25:9 | - ... | The unary minus operator should not be applied to an unsigned expression. | diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.qlref b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.qlref new file mode 100644 index 00000000000..a6ee879dfe9 --- /dev/null +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.qlref @@ -0,0 +1 @@ +jsf/4.21 Operators/AV Rule 165.ql diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c new file mode 100644 index 00000000000..6845c418afc --- /dev/null +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c @@ -0,0 +1,27 @@ + +typedef unsigned int TUI; + +void f(int i, unsigned int ui, signed int si, TUI tui, volatile unsigned int vui, unsigned u, unsigned short us) { + i = -i; + i = -ui; // BAD + i = -si; + ui = -i; + ui = -ui; // BAD + ui = -si; + si = -i; + si = -ui; // BAD + si = -si; + + i = -(int)i; + i = -(unsigned int)i; // BAD [NOT DETECTED] + i = -(signed int)i; + ui = -(int)ui; // [FALSE POSITIVE] + ui = -(unsigned int)ui; // BAD + ui = -(signed int)ui; // [FALSE POSITIVE] + + tui = -tui; // BAD + vui = -vui; // BAD + u = -u; // BAD + us = -us; // BAD + ui = -(5U); // BAD [NOT DETECTED] +} From 3f428a88768fb074253e21af97b5ad22b7e2e74a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 14 Nov 2018 19:10:30 +0000 Subject: [PATCH 14/94] CPP: Fix for explicitly cast expressions. --- cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql | 2 +- .../jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected | 3 +-- .../test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql index ba2e452eade..e657be1844e 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql @@ -11,6 +11,6 @@ import cpp // see MISRA Rule 5-3-2 from UnaryMinusExpr ume -where ume.getOperand().getUnderlyingType().(IntegralType).isUnsigned() +where ume.getOperand().getExplicitlyConverted().getUnderlyingType().(IntegralType).isUnsigned() and not ume.getOperand() instanceof Literal select ume, "The unary minus operator should not be applied to an unsigned expression." diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected index 8cbaac1f40b..5a6e6a66eef 100644 --- a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/AV Rule 165.expected @@ -1,9 +1,8 @@ | test.c:6:6:6:8 | - ... | The unary minus operator should not be applied to an unsigned expression. | | test.c:9:7:9:9 | - ... | The unary minus operator should not be applied to an unsigned expression. | | test.c:12:7:12:9 | - ... | The unary minus operator should not be applied to an unsigned expression. | -| test.c:18:7:18:14 | - ... | The unary minus operator should not be applied to an unsigned expression. | +| test.c:16:6:16:21 | - ... | The unary minus operator should not be applied to an unsigned expression. | | test.c:19:7:19:23 | - ... | The unary minus operator should not be applied to an unsigned expression. | -| test.c:20:7:20:21 | - ... | The unary minus operator should not be applied to an unsigned expression. | | test.c:22:8:22:11 | - ... | The unary minus operator should not be applied to an unsigned expression. | | test.c:23:8:23:11 | - ... | The unary minus operator should not be applied to an unsigned expression. | | test.c:24:6:24:7 | - ... | The unary minus operator should not be applied to an unsigned expression. | diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c index 6845c418afc..26d53e5a0c3 100644 --- a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 165/test.c @@ -13,11 +13,11 @@ void f(int i, unsigned int ui, signed int si, TUI tui, volatile unsigned int vui si = -si; i = -(int)i; - i = -(unsigned int)i; // BAD [NOT DETECTED] + i = -(unsigned int)i; // BAD i = -(signed int)i; - ui = -(int)ui; // [FALSE POSITIVE] + ui = -(int)ui; ui = -(unsigned int)ui; // BAD - ui = -(signed int)ui; // [FALSE POSITIVE] + ui = -(signed int)ui; tui = -tui; // BAD vui = -vui; // BAD From 3028e85457f42b08fe03b79ae0ca861098e3ff27 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 14 Nov 2018 19:37:25 +0000 Subject: [PATCH 15/94] CPP: Add a test of AV Rule 164. --- .../AV Rule 164/AV Rule 164.expected | 7 +++++ .../AV Rule 164/AV Rule 164.qlref | 1 + .../jsf/4.21 Operators/AV Rule 164/test.c | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected create mode 100644 cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.qlref create mode 100644 cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected new file mode 100644 index 00000000000..250810dc1d4 --- /dev/null +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected @@ -0,0 +1,7 @@ +| test.c:3:2:3:9 | ... >> ... | AV Rule 164: The right-hand operand (here a value is -1) of this shift shall lie between 0 and 7. | +| test.c:6:2:6:8 | ... >> ... | AV Rule 164: The right-hand operand (here a value is 8) of this shift shall lie between 0 and 7. | +| test.c:8:2:8:9 | ... << ... | AV Rule 164: The right-hand operand (here a value is -1) of this shift shall lie between 0 and 7. | +| test.c:11:2:11:8 | ... << ... | AV Rule 164: The right-hand operand (here a value is 8) of this shift shall lie between 0 and 7. | +| test.c:18:2:18:9 | ... >> ... | AV Rule 164: The right-hand operand (here a value is -1) of this shift shall lie between 0 and 7. | +| test.c:21:2:21:8 | ... >> ... | AV Rule 164: The right-hand operand (here a value is 8) of this shift shall lie between 0 and 7. | +| test.c:23:2:23:25 | ... >> ... | AV Rule 164: The right-hand operand (here a value is -1) of this shift shall lie between 0 and 31. | diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.qlref b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.qlref new file mode 100644 index 00000000000..d6afaadc595 --- /dev/null +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.qlref @@ -0,0 +1 @@ +jsf/4.21 Operators/AV Rule 164.ql diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c new file mode 100644 index 00000000000..3589c6744a6 --- /dev/null +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c @@ -0,0 +1,28 @@ + +void f(unsigned char uc, signed char sc, int i) { + uc >> -1; // BAD + uc >> 0; + uc >> 7; + uc >> 8; // BAD + + uc << -1; // BAD + uc << 0; + uc << 7; + uc << 8; // BAD + + uc >>= -1; // BAD [NOT DETECTED] + uc >>= 0; // BAD [NOT DETECTED] + uc >>= 7; + uc >>= 8; // BAD [NOT DETECTED] + + sc >> -1; // BAD + sc >> 0; + sc >> 7; + sc >> 8; // BAD + + ((unsigned char)i) >> -1; // BAD + ((unsigned char)i) >> 0; + ((unsigned char)i) >> 7; + ((unsigned char)i) >> 8; // BAD [NOT DETECTED] +} + From d1adc0e3ecb8829632d208ee7444f66f1a19adfa Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 14 Nov 2018 19:43:24 +0000 Subject: [PATCH 16/94] CPP: Fix for explicitly cast expressions. --- cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql | 2 +- .../jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected | 3 ++- cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql index 5531028f466..714c7d6c4de 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql @@ -35,7 +35,7 @@ predicate constantValue(Expr e, int value) { predicate violation(BinaryBitwiseOperation op, int lhsBytes, int value) { (op instanceof LShiftExpr or op instanceof RShiftExpr) and constantValue(op.getRightOperand(), value) and - lhsBytes = op.getLeftOperand().getType().getSize() and + lhsBytes = op.getLeftOperand().getExplicitlyConverted().getType().getSize() and (value < 0 or value >= lhsBytes * 8) } diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected index 250810dc1d4..3033e746d69 100644 --- a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/AV Rule 164.expected @@ -4,4 +4,5 @@ | test.c:11:2:11:8 | ... << ... | AV Rule 164: The right-hand operand (here a value is 8) of this shift shall lie between 0 and 7. | | test.c:18:2:18:9 | ... >> ... | AV Rule 164: The right-hand operand (here a value is -1) of this shift shall lie between 0 and 7. | | test.c:21:2:21:8 | ... >> ... | AV Rule 164: The right-hand operand (here a value is 8) of this shift shall lie between 0 and 7. | -| test.c:23:2:23:25 | ... >> ... | AV Rule 164: The right-hand operand (here a value is -1) of this shift shall lie between 0 and 31. | +| test.c:23:2:23:25 | ... >> ... | AV Rule 164: The right-hand operand (here a value is -1) of this shift shall lie between 0 and 7. | +| test.c:26:2:26:24 | ... >> ... | AV Rule 164: The right-hand operand (here a value is 8) of this shift shall lie between 0 and 7. | diff --git a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c index 3589c6744a6..99cc6bd7db7 100644 --- a/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c +++ b/cpp/ql/test/query-tests/jsf/4.21 Operators/AV Rule 164/test.c @@ -23,6 +23,6 @@ void f(unsigned char uc, signed char sc, int i) { ((unsigned char)i) >> -1; // BAD ((unsigned char)i) >> 0; ((unsigned char)i) >> 7; - ((unsigned char)i) >> 8; // BAD [NOT DETECTED] + ((unsigned char)i) >> 8; // BAD } From eddc52852d8fe9dd5640733d636243e48857990b Mon Sep 17 00:00:00 2001 From: calum Date: Thu, 25 Oct 2018 15:36:34 +0100 Subject: [PATCH 17/94] C#: Convert security queries to path-problem and update qltest expected output. --- .../Security Features/CWE-022/TaintedPath.ql | 10 +++-- .../src/Security Features/CWE-022/ZipSlip.ql | 10 +++-- .../CWE-078/CommandInjection.ql | 10 +++-- .../CWE-078/StoredCommandInjection.ql | 10 +++-- .../Security Features/CWE-079/StoredXSS.ql | 6 ++- .../CWE-089/SecondOrderSqlInjection.ql | 10 +++-- .../Security Features/CWE-089/SqlInjection.ql | 6 ++- .../CWE-090/LDAPInjection.ql | 10 +++-- .../CWE-090/StoredLDAPInjection.ql | 10 +++-- .../CWE-094/CodeInjection.ql | 10 +++-- .../CWE-099/ResourceInjection.ql | 10 +++-- .../CWE-112/MissingXMLValidation.ql | 6 ++- .../Security Features/CWE-117/LogForging.ql | 10 +++-- .../CWE-201/ExposureInTransmittedData.ql | 10 +++-- .../CWE-209/ExceptionInformationExposure.ql | 10 +++-- .../CWE-312/CleartextStorage.ql | 10 +++-- .../CWE-327/DontInstallRootCert.ql | 10 +++-- .../CWE-359/ExposureOfPrivateInformation.ql | 10 +++-- .../Security Features/CWE-601/UrlRedirect.ql | 10 +++-- .../CWE-611/UntrustedDataInsecureXml.ql | 6 ++- .../CWE-643/StoredXPathInjection.ql | 10 +++-- .../CWE-643/XPathInjection.ql | 10 +++-- .../ql/src/Security Features/CWE-730/ReDoS.ql | 6 ++- .../CWE-730/RegexInjection.ql | 6 ++- .../CWE-798/HardcodedConnectionString.ql | 7 +++- .../CWE-798/HardcodedCredentials.ql | 15 ++++--- .../CWE-807/ConditionalBypass.ql | 6 ++- .../CWE-838/InappropriateEncoding.ql | 12 +++--- .../semmle/code/csharp/dataflow/DataFlow.qll | 6 +++ .../CWE-022/TaintedPath/TaintedPath.expected | 23 +++++++---- .../CWE-022/ZipSlip/ZipSlip.expected | 31 ++++++++++----- .../CWE-078/CommandInjection.expected | 23 +++++++---- .../CWE-078/StoredCommandInjection.expected | 5 ++- .../CWE-079/StoredXSS/StoredXSS.expected | 5 ++- .../CWE-089/SecondOrderSqlInjection.expected | 5 ++- .../CWE-089/SqlInjection.expected | 39 ++++++++++++++----- .../CWE-090/LDAPInjection.expected | 20 +++++++--- .../CWE-090/StoredLDAPInjection.expected | 5 ++- .../CWE-094/CodeInjection.expected | 8 +++- .../CWE-099/ResourceInjection.expected | 8 +++- .../CWE-112/MissingXMLValidation.expected | 21 +++++++--- .../CWE-117/LogForging.expected | 8 +++- .../ExposureInTransmittedData.expected | 25 +++++++----- .../ExceptionInformationExposure.expected | 13 ++++--- .../CWE-312/CleartextStorage.expected | 12 +++--- .../DontInstallRootCert.expected | 11 ++++-- .../ExposureOfPrivateInformation.expected | 8 ++-- .../CWE-611/UntrustedDataInsecureXml.expected | 6 ++- .../CWE-643/StoredXPathInjection.expected | 14 +++++-- .../CWE-643/XPathInjection.expected | 14 +++++-- .../CWE-730/ReDoS/ReDoS.expected | 27 ++++++++++--- .../CWE-730/ReDoSGlobalTimeout/ReDoS.expected | 3 ++ .../RegexInjection/RegexInjection.expected | 5 ++- .../HardcodedConnectionString.expected | 7 +++- .../CWE-798/HardcodedCredentials.expected | 19 +++++---- .../CWE-807/ConditionalBypass.expected | 25 ++++++++---- .../CWE-838/InappropriateEncoding.expected | 36 +++++++++++------ 57 files changed, 467 insertions(+), 221 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql b/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql index 76b940631a2..9d6e55e44c9 100644 --- a/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql +++ b/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql @@ -1,7 +1,7 @@ /** * @name Uncontrolled data used in path expression * @description Accessing paths influenced by users can allow an attacker to access unexpected resources. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/path-injection @@ -14,7 +14,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.TaintedPath::TaintedPath +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in a path.", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in a path.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql index 37969f0b6eb..1d93d480634 100644 --- a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql +++ b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql @@ -3,7 +3,7 @@ * @description Extracting files from a malicious zip archive without validating that the * destination file path is within the destination directory can cause files outside * the destination directory to be overwritten. - * @kind problem + * @kind path-problem * @id cs/zipslip * @problem.severity error * @precision high @@ -13,7 +13,9 @@ import csharp import semmle.code.csharp.security.dataflow.ZipSlip::ZipSlip +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration zipTaintTracking, DataFlow::Node source, DataFlow::Node sink -where zipTaintTracking.hasFlow(source, sink) -select sink, "Unsanitized zip archive $@, which may contain '..', is used in a file system operation.", source, "item path" +from TaintTrackingConfiguration zipTaintTracking, DataFlow::PathNode source, DataFlow::PathNode sink +where zipTaintTracking.hasFlowPath(source, sink) +select sink, source, sink, + "Unsanitized zip archive $@, which may contain '..', is used in a file system operation.", source, "item path" diff --git a/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql b/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql index 17dec56988f..316c0676113 100644 --- a/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql +++ b/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql @@ -2,7 +2,7 @@ * @name Uncontrolled command line * @description Using externally controlled strings in a command line may allow a malicious * user to change the meaning of the command. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/command-line-injection @@ -14,7 +14,9 @@ import csharp import semmle.code.csharp.security.dataflow.CommandInjection::CommandInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in a command.", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in a command.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql b/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql index acd883e106c..a74cbb10ce6 100644 --- a/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql +++ b/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql @@ -2,7 +2,7 @@ * @name Uncontrolled command line from stored user input * @description Using externally controlled strings in a command line may allow a malicious * user to change the meaning of the command. - * @kind problem + * @kind path-problem * @problem.severity error * @precision medium * @id cs/stored-command-line-injection @@ -15,6 +15,7 @@ import csharp import semmle.code.csharp.security.dataflow.flowsources.Stored import semmle.code.csharp.security.dataflow.CommandInjection::CommandInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { override predicate isSource(DataFlow::Node source) { @@ -22,6 +23,7 @@ class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { } } -from StoredTaintTrackingConfiguration c, StoredFlowSource source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in a command.", source, "Stored user-provided value" +from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in a command.", source, "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql b/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql index 91fe8b2616c..2909269df2a 100644 --- a/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql +++ b/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql @@ -2,7 +2,7 @@ * @name Stored cross-site scripting * @description Writing input from the database directly to a web page indicates a cross-site * scripting vulnerability if the data was originally user-provided. - * @kind problem + * @kind path-problem * @problem.severity error * @precision medium * @id cs/web/stored-xss @@ -13,6 +13,7 @@ import csharp import semmle.code.csharp.security.dataflow.flowsources.Stored import semmle.code.csharp.security.dataflow.XSS::XSS +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { override predicate isSource(DataFlow::Node source) { @@ -26,4 +27,5 @@ and if exists(sink.explanation()) then explanation = ": " + sink.explanation() + "." else explanation = "." -select sink, "$@ flows to here and is written to HTML or javascript" + explanation, source, "Stored user-provided value" +select sink, source.getPathNode(c), sink.getPathNode(c), + "$@ flows to here and is written to HTML or JavaScript" + explanation, source, "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql b/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql index b7fb79ccf37..d4d1c419241 100644 --- a/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql +++ b/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql @@ -2,7 +2,7 @@ * @name SQL query built from stored user-controlled sources * @description Building a SQL query from stored user-controlled sources is vulnerable to insertion * of malicious SQL code by the user. - * @kind problem + * @kind path-problem * @problem.severity error * @precision medium * @id cs/second-order-sql-injection @@ -13,6 +13,7 @@ import csharp import semmle.code.csharp.security.dataflow.SqlInjection import semmle.code.csharp.security.dataflow.flowsources.Stored +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph class StoredTaintTrackingConfiguration extends SqlInjection::TaintTrackingConfiguration { override predicate isSource(DataFlow::Node source) { @@ -20,6 +21,7 @@ class StoredTaintTrackingConfiguration extends SqlInjection::TaintTrackingConfig } } -from StoredTaintTrackingConfiguration c, DataFlow::Node source, DataFlow::Node sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in an SQL query.", source, "Stored user-provided value" +from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in an SQL query.", source, "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql b/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql index b3973132808..9bc70bd56b4 100644 --- a/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql +++ b/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql @@ -2,7 +2,7 @@ * @name SQL query built from user-controlled sources * @description Building a SQL query from user-controlled sources is vulnerable to insertion of * malicious SQL code by the user. -* @kind problem +* @kind path-problem * @problem.severity error * @precision high * @id cs/sql-injection @@ -12,7 +12,9 @@ import csharp import semmle.code.csharp.security.dataflow.SqlInjection::SqlInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, RemoteFlowSource source, Sink sink where c.hasFlow(source, sink) -select sink, "Query might include code from $@.", source, ("this " + source.getSourceType()) +select sink, source.getPathNode(c), sink.getPathNode(c), + "Query might include code from $@.", source, ("this " + source.getSourceType()) diff --git a/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql b/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql index b5688b7ac41..b2c1cfb7c93 100644 --- a/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql +++ b/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql @@ -2,7 +2,7 @@ * @name LDAP query built from user-controlled sources * @description Building an LDAP query from user-controlled sources is vulnerable to insertion of * malicious LDAP code by the user. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/ldap-injection @@ -11,7 +11,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.LDAPInjection::LDAPInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in an LDAP query.", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in an LDAP query.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql b/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql index 0cea7f63113..5d11e89e838 100644 --- a/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql +++ b/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql @@ -2,7 +2,7 @@ * @name LDAP query built from stored user-controlled sources * @description Building an LDAP query from stored user-controlled sources is vulnerable to * insertion of malicious LDAP code by the user. - * @kind problem + * @kind path-problem * @problem.severity error * @precision medium * @id cs/stored-ldap-injection @@ -12,6 +12,7 @@ import csharp import semmle.code.csharp.security.dataflow.LDAPInjection::LDAPInjection import semmle.code.csharp.security.dataflow.flowsources.Stored +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { override predicate isSource(DataFlow::Node source) { @@ -19,6 +20,7 @@ class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { } } -from StoredTaintTrackingConfiguration c, StoredFlowSource source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in an LDAP query.", source, "Stored user-provided value" +from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in an LDAP query.", source, "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql b/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql index d97498f0f12..a4447309b7c 100644 --- a/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql +++ b/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql @@ -2,7 +2,7 @@ * @name Improper control of generation of code * @description Treating externally controlled strings as code can allow an attacker to execute * malicious code. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/code-injection @@ -13,7 +13,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.CodeInjection::CodeInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is compiled as code.", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is compiled as code.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql b/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql index 9853f0c0098..3f842b1d4f4 100644 --- a/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql +++ b/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql @@ -2,7 +2,7 @@ * @name Resource injection * @description Building a resource descriptor from untrusted user input is vulnerable to a * malicious user providing an unintended resource. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/resource-injection @@ -11,7 +11,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.ResourceInjection::ResourceInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in a resource descriptor.", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in a resource descriptor.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql b/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql index ae4228a5c3a..67c8891fd7a 100644 --- a/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql +++ b/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql @@ -2,7 +2,7 @@ * @name Missing XML validation * @description User input should not be processed as XML without validating it against a known * schema. - * @kind problem + * @kind path-problem * @problem.severity recommendation * @precision high * @id cs/xml/missing-validation @@ -11,7 +11,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.MissingXMLValidation::MissingXMLValidation +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, Source source, Sink sink where c.hasFlow(source, sink) -select sink, "$@ flows to here and is processed as XML without validation because " + sink.getReason(), source, "User-provided value" +select sink, source.getPathNode(c), sink.getPathNode(c), + "$@ flows to here and is processed as XML without validation because " + sink.getReason(), source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-117/LogForging.ql b/csharp/ql/src/Security Features/CWE-117/LogForging.ql index 32068cf59e2..01985c85c8c 100644 --- a/csharp/ql/src/Security Features/CWE-117/LogForging.ql +++ b/csharp/ql/src/Security Features/CWE-117/LogForging.ql @@ -2,7 +2,7 @@ * @name Log entries created from user input * @description Building log entries from user-controlled sources is vulnerable to * insertion of forged log entries by a malicious user. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/log-forging @@ -11,7 +11,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.LogForging::LogForging +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to log entry.", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to log entry.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql b/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql index 3c2e9350a2d..482c9de2eab 100644 --- a/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql +++ b/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql @@ -1,7 +1,7 @@ /** * @name Information exposure through transmitted data * @description Transmitting sensitive information to the user is a potential security risk. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/sensitive-data-transmission @@ -15,6 +15,7 @@ import semmle.code.csharp.security.dataflow.XSS import semmle.code.csharp.security.dataflow.Email import semmle.code.csharp.frameworks.system.data.Common import semmle.code.csharp.frameworks.System +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph class TaintTrackingConfiguration extends TaintTracking::Configuration { TaintTrackingConfiguration() { @@ -49,6 +50,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } } -from TaintTrackingConfiguration configuration, DataFlow::Node source, DataFlow::Node sink -where configuration.hasFlow(source, sink) -select sink, "Sensitive information from $@ flows to here, and is transmitted to the user.", source, source.toString() +from TaintTrackingConfiguration configuration, DataFlow::PathNode source, DataFlow::PathNode sink +where configuration.hasFlowPath(source, sink) +select sink, source, sink, + "Sensitive information from $@ flows to here, and is transmitted to the user.", source, source.toString() diff --git a/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql b/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql index b895b50321b..935e1e15554 100644 --- a/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql +++ b/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql @@ -3,7 +3,7 @@ * @description Leaking information about an exception, such as messages and stack traces, to an * external user can expose implementation details that are useful to an attacker for * developing a subsequent exploit. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/information-exposure-through-exception @@ -15,6 +15,7 @@ import csharp import semmle.code.csharp.frameworks.System import semmle.code.csharp.security.dataflow.XSS +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph /** * A taint-tracking configuration for reasoning about stack traces that flow to web page outputs. @@ -56,6 +57,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { } } -from TaintTrackingConfiguration c, DataFlow::Node source, DataFlow::Node sink -where c.hasFlow(source, sink) -select sink, "Exception information from $@ flows to here, and is exposed to the user.", source, source.toString() +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "Exception information from $@ flows to here, and is exposed to the user.", source, source.toString() diff --git a/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql b/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql index e44ad181727..17d09cb368d 100644 --- a/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql +++ b/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql @@ -2,7 +2,7 @@ * @name Clear text storage of sensitive information * @description Sensitive information stored without encryption or hashing can expose it to an * attacker. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/cleartext-storage-of-sensitive-information @@ -13,7 +13,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.CleartextStorage::CleartextStorage +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "Sensitive data returned by $@ is stored here.", source, source.toString() +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "Sensitive data returned by $@ is stored here.", source, source.toString() diff --git a/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql b/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql index 412af8e43f7..d9f1dd3ef88 100644 --- a/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql +++ b/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql @@ -2,7 +2,7 @@ * @name Do not add certificates to the system root store. * @description Application- or user-specific certificates placed in the system root store could * weaken security for other processing running on the same system. - * @kind problem + * @kind path-problem * @id cs/adding-cert-to-root-store * @problem.severity error * @tags security @@ -10,6 +10,7 @@ */ import csharp import semmle.code.csharp.dataflow.DataFlow::DataFlow +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph class AddCertToRootStoreConfig extends DataFlow::Configuration { AddCertToRootStoreConfig() { this = "Adding Certificate To Root Store" } @@ -30,7 +31,8 @@ class AddCertToRootStoreConfig extends DataFlow::Configuration { } } -from Expr oc, Expr mc, AddCertToRootStoreConfig config -where config.hasFlow(DataFlow::exprNode(oc), DataFlow::exprNode(mc)) -select mc, "Certificate added to the root certificate store." +from DataFlow::PathNode oc, DataFlow::PathNode mc, AddCertToRootStoreConfig config +where config.hasFlowPath(oc, mc) +select mc, oc, mc, + "Certificate added to the root certificate store." diff --git a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql index 5b8dad5f931..d2d593f7025 100644 --- a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql +++ b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql @@ -2,7 +2,7 @@ * @name Exposure of private information * @description If private information is written to an external location, it may be accessible by * unauthorized persons. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/exposure-of-sensitive-information @@ -11,7 +11,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformation::ExposureOfPrivateInformation +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "Private data returned by $@ is written to an external location.", source, source.toString() +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "Private data returned by $@ is written to an external location.", source, source.toString() diff --git a/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql b/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql index b2a148e10a6..c499c9860fb 100644 --- a/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql +++ b/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql @@ -2,7 +2,7 @@ * @name URL redirection from remote source * @description URL redirection based on unvalidated user input * may cause redirection to malicious web sites. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/web/unvalidated-url-redirection @@ -11,7 +11,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.UrlRedirect::UrlRedirect +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "Untrusted URL redirection due to $@.", source, "user-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "Untrusted URL redirection due to $@.", source, "user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql b/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql index 09f8fa924be..fa1c5a93e99 100644 --- a/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql +++ b/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql @@ -1,7 +1,7 @@ /** * @name Untrusted XML is read insecurely * @description Untrusted XML is read with an insecure resolver and DTD processing enabled. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/xml/insecure-dtd-handling @@ -12,7 +12,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.XMLEntityInjection::XMLEntityInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, Source source, Sink sink where c.hasFlow(source, sink) -select sink, "$@ flows to here and is loaded insecurely as XML (" + sink.getReason() +").", source, "User-provided value" +select sink, source.getPathNode(c), sink.getPathNode(c), + "$@ flows to here and is loaded insecurely as XML (" + sink.getReason() +").", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql b/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql index 2dd94bd1fb3..adb34437b2b 100644 --- a/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql +++ b/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql @@ -2,7 +2,7 @@ * @name Stored XPath injection * @description Building an XPath expression from stored data which may have been provided by the * user is vulnerable to insertion of malicious code by the user. - * @kind problem + * @kind path-problem * @problem.severity error * @precision medium * @id cs/xml/stored-xpath-injection @@ -12,6 +12,7 @@ import csharp import semmle.code.csharp.security.dataflow.flowsources.Stored import semmle.code.csharp.security.dataflow.XPathInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph class StoredTaintTrackingConfiguration extends XPathInjection::TaintTrackingConfiguration { override @@ -20,6 +21,7 @@ class StoredTaintTrackingConfiguration extends XPathInjection::TaintTrackingConf } } -from StoredTaintTrackingConfiguration c, DataFlow::Node source, DataFlow::Node sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in an XPath expression.", source, "Stored user-provided value" +from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in an XPath expression.", source, "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql b/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql index 4206884d76c..6cc18e5dac0 100644 --- a/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql +++ b/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql @@ -2,7 +2,7 @@ * @name XPath injection * @description Building an XPath expression from user-controlled sources is vulnerable to insertion of * malicious code by the user. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/xml/xpath-injection @@ -11,7 +11,9 @@ */ import csharp import semmle.code.csharp.security.dataflow.XPathInjection::XPathInjection +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, "$@ flows to here and is used in an XPath expression.", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink, source, sink, + "$@ flows to here and is used in an XPath expression.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql index 9e75c1aa1bb..d0675f8c06f 100644 --- a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql +++ b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql @@ -2,7 +2,7 @@ * @name Denial of Service from comparison of user input against expensive regex * @description User input should not be matched against a regular expression that could require * exponential time on certain input. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/redos @@ -13,9 +13,11 @@ import csharp import semmle.code.csharp.security.dataflow.ReDoS::ReDoS import semmle.code.csharp.frameworks.system.text.RegularExpressions +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, Source source, DataFlow::Node sink where c.hasFlow(source, sink) // No global timeout set and not exists(RegexGlobalTimeout r) -select sink, "$@ flows to regular expression operation with dangerous regex.", source, "User-provided value" +select sink, source.getPathNode(c), sink.getPathNode(c), + "$@ flows to regular expression operation with dangerous regex.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql b/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql index 4e3bacc8b60..458fb366bd2 100644 --- a/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql +++ b/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql @@ -3,7 +3,7 @@ * @description User input should not be used in regular expressions without first being escaped, * otherwise a malicious user may be able to provide a regex that could require * exponential time on certain inputs. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/regex-injection @@ -14,9 +14,11 @@ import csharp import semmle.code.csharp.security.dataflow.RegexInjection::RegexInjection import semmle.code.csharp.frameworks.system.text.RegularExpressions +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, Source source, Sink sink where c.hasFlow(source, sink) // No global timeout set and not exists(RegexGlobalTimeout r) -select sink, "$@ flows to the construction of a regular expression.", source, "User-provided value" +select sink, source.getPathNode(c), sink.getPathNode(c), + "$@ flows to the construction of a regular expression.", source, "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql b/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql index a2376bdbd23..4585057055d 100644 --- a/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql +++ b/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql @@ -1,7 +1,7 @@ /** * @name Hard-coded connection string with credentials * @description Credentials are hard-coded in a connection string in the source code of the application. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/hardcoded-connection-string-credentials @@ -13,6 +13,7 @@ import csharp import semmle.code.csharp.frameworks.system.Data import semmle.code.csharp.security.dataflow.HardcodedCredentials +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph /** * A string literal containing a username or password field. @@ -49,4 +50,6 @@ class ConnectionStringTaintTrackingConfiguration extends TaintTracking::Configur from ConnectionStringTaintTrackingConfiguration c, DataFlow::Node source, DataFlow::Node sink where c.hasFlow(source, sink) -select source, "'ConnectionString' property includes hard-coded credentials set in $@.", any(Call call | call.getAnArgument() = sink.asExpr()) as call, call.toString() +select source, source.getPathNode(c), sink.getPathNode(c), + "'ConnectionString' property includes hard-coded credentials set in $@.", + any(Call call | call.getAnArgument() = sink.asExpr()) as call, call.toString() diff --git a/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql b/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql index 05f24d0810e..11ddc864418 100644 --- a/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql +++ b/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql @@ -1,7 +1,7 @@ /** * @name Hard-coded credentials * @description Credentials are hard coded in the source code of the application. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/hardcoded-credentials @@ -11,13 +11,18 @@ * external/cwe/cwe-798 */ import csharp -private import semmle.code.csharp.security.dataflow.HardcodedCredentials::HardcodedCredentials +import semmle.code.csharp.security.dataflow.HardcodedCredentials::HardcodedCredentials +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, Source source, Sink sink, string value -where c.hasFlow(source, sink) +where + c.hasFlow(source, sink) and // Print the source value if it's available - and if exists(source.asExpr().getValue()) then + if exists(source.asExpr().getValue()) then value = "The hard-coded value \"" + source.asExpr().getValue() + "\"" else value = "This hard-coded value" -select source, value + " flows to " + sink.getSinkDescription() + ".", sink, sink.getSinkName(), sink.getSupplementaryElement(), sink.getSupplementaryElement().toString() +select source, source.getPathNode(c), sink.getPathNode(c), + value + " flows to " + sink.getSinkDescription() + ".", + sink, sink.getSinkName(), sink.getSupplementaryElement(), + sink.getSupplementaryElement().toString() diff --git a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql index e2399be992b..013320f9252 100644 --- a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql +++ b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql @@ -2,7 +2,7 @@ * @name User-controlled bypass of sensitive method * @description User-controlled bypassing of sensitive methods may allow attackers to avoid * passing through authentication systems. - * @kind problem + * @kind path-problem * @problem.severity error * @precision high * @id cs/user-controlled-bypass @@ -13,8 +13,10 @@ */ import csharp import semmle.code.csharp.security.dataflow.ConditionalBypass::UserControlledBypassOfSensitiveMethod +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from Configuration config, Source source, Sink sink where config.hasFlow(source, sink) -select sink.getSensitiveMethodCall(), "Sensitive method may not be executed depending on $@, which flows from $@.", +select sink.getSensitiveMethodCall(), source.getPathNode(config), sink.getPathNode(config), + "Sensitive method may not be executed depending on $@, which flows from $@.", sink, "this condition", source, "user input" diff --git a/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql b/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql index d429bb0c0d2..9735cc52a63 100644 --- a/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql +++ b/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql @@ -2,7 +2,7 @@ * @name Inappropriate encoding * @description Using an inappropriate encoding may give unintended results and may * pose a security risk. -* @kind problem +* @kind path-problem * @problem.severity error * @precision low * @id cs/inappropriate-encoding @@ -20,6 +20,7 @@ import semmle.code.csharp.security.dataflow.SqlInjection import semmle.code.csharp.security.dataflow.XSS import semmle.code.csharp.security.dataflow.UrlRedirect import semmle.code.csharp.security.Sanitizers +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph /** * A configuration for specifying expressions that must be @@ -43,8 +44,8 @@ abstract class RequiresEncodingConfiguration extends TaintTracking::Configuratio * `sink`, where `sink` is an expression of kind `kind` that is required * to be encoded. */ - predicate hasWrongEncoding(Expr encodedValue, Expr sink, string kind) { - hasFlow(exprNode(encodedValue), exprNode(sink)) and + predicate hasWrongEncoding(PathNode encodedValue, PathNode sink, string kind) { + hasFlowPath(encodedValue, sink) and kind = this.getKind() } @@ -153,6 +154,7 @@ module EncodingConfigurations { } } -from RequiresEncodingConfiguration c, Expr encodedValue, Expr sink, string kind +from RequiresEncodingConfiguration c, PathNode encodedValue, PathNode sink, string kind where c.hasWrongEncoding(encodedValue, sink, kind) -select sink, "This " + kind + " may include data from a $@.", encodedValue, "possibly inappropriately encoded value" +select sink, encodedValue, sink, + "This " + kind + " may include data from a $@.", encodedValue, "possibly inappropriately encoded value" diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index 6843d67087b..d05ce2a4d81 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -35,6 +35,12 @@ module DataFlow { /** Gets the location of this node. */ Location getLocation() { none() } + + /** Gets the path node for this node. */ + PathNode getPathNode(Configuration config) { + result.getNode() = this and + result.getConfiguration() = config + } } /** diff --git a/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected b/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected index fce17c42bd0..8586fc5266d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected @@ -1,7 +1,16 @@ -| TaintedPath.cs:14:50:14:53 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | -| TaintedPath.cs:19:51:19:54 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | -| TaintedPath.cs:27:30:27:33 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | -| TaintedPath.cs:33:30:33:33 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | -| TaintedPath.cs:38:25:38:31 | access to local variable badPath | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | -| TaintedPath.cs:40:49:40:55 | access to local variable badPath | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | -| TaintedPath.cs:53:26:53:29 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | +edges +| TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:14:50:14:53 | access to local variable path | +| TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:19:51:19:54 | access to local variable path | +| TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:27:30:27:33 | access to local variable path | +| TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:33:30:33:33 | access to local variable path | +| TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:38:25:38:31 | access to local variable badPath | +| TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:40:49:40:55 | access to local variable badPath | +| TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:53:26:53:29 | access to local variable path | +#select +| TaintedPath.cs:14:50:14:53 | access to local variable path | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:14:50:14:53 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | +| TaintedPath.cs:19:51:19:54 | access to local variable path | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:19:51:19:54 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | +| TaintedPath.cs:27:30:27:33 | access to local variable path | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:27:30:27:33 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | +| TaintedPath.cs:33:30:33:33 | access to local variable path | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:33:30:33:33 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | +| TaintedPath.cs:38:25:38:31 | access to local variable badPath | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:38:25:38:31 | access to local variable badPath | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | +| TaintedPath.cs:40:49:40:55 | access to local variable badPath | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:40:49:40:55 | access to local variable badPath | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | +| TaintedPath.cs:53:26:53:29 | access to local variable path | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:53:26:53:29 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected b/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected index f9da54b1b80..2672f945a62 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected @@ -1,9 +1,22 @@ -| ZipSlip.cs:24:41:24:52 | access to local variable destFileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:19:31:19:44 | access to property FullName | item path | -| ZipSlip.cs:32:41:32:52 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:16:52:16:65 | access to property FullName | item path | -| ZipSlip.cs:36:45:36:56 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:16:52:16:65 | access to property FullName | item path | -| ZipSlip.cs:40:41:40:52 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:16:52:16:65 | access to property FullName | item path | -| ZipSlip.cs:69:74:69:85 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | -| ZipSlip.cs:76:71:76:82 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | -| ZipSlip.cs:83:57:83:68 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | -| ZipSlip.cs:91:58:91:69 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | -| ZipSlipBad.cs:10:29:10:40 | access to local variable destFileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBad.cs:9:59:9:72 | access to property FullName | item path | +edges +| ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:32:41:32:52 | access to local variable destFilePath | +| ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:36:45:36:56 | access to local variable destFilePath | +| ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:39:53:39:89 | call to method Combine | +| ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:40:41:40:52 | access to local variable destFilePath | +| ZipSlip.cs:19:31:19:44 | access to property FullName | ZipSlip.cs:24:41:24:52 | access to local variable destFileName | +| ZipSlip.cs:39:53:39:89 | call to method Combine | ZipSlip.cs:40:41:40:52 | access to local variable destFilePath | +| ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:69:74:69:85 | access to local variable destFilePath | +| ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:76:71:76:82 | access to local variable destFilePath | +| ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:83:57:83:68 | access to local variable destFilePath | +| ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:91:58:91:69 | access to local variable destFilePath | +| ZipSlipBad.cs:9:59:9:72 | access to property FullName | ZipSlipBad.cs:10:29:10:40 | access to local variable destFileName | +#select +| ZipSlip.cs:24:41:24:52 | access to local variable destFileName | ZipSlip.cs:19:31:19:44 | access to property FullName | ZipSlip.cs:24:41:24:52 | access to local variable destFileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:19:31:19:44 | access to property FullName | item path | +| ZipSlip.cs:32:41:32:52 | access to local variable destFilePath | ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:32:41:32:52 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:16:52:16:65 | access to property FullName | item path | +| ZipSlip.cs:36:45:36:56 | access to local variable destFilePath | ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:36:45:36:56 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:16:52:16:65 | access to property FullName | item path | +| ZipSlip.cs:40:41:40:52 | access to local variable destFilePath | ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:40:41:40:52 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:16:52:16:65 | access to property FullName | item path | +| ZipSlip.cs:69:74:69:85 | access to local variable destFilePath | ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:69:74:69:85 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | +| ZipSlip.cs:76:71:76:82 | access to local variable destFilePath | ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:76:71:76:82 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | +| ZipSlip.cs:83:57:83:68 | access to local variable destFilePath | ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:83:57:83:68 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | +| ZipSlip.cs:91:58:91:69 | access to local variable destFilePath | ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:91:58:91:69 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:62:72:62:85 | access to property FullName | item path | +| ZipSlipBad.cs:10:29:10:40 | access to local variable destFileName | ZipSlipBad.cs:9:59:9:72 | access to property FullName | ZipSlipBad.cs:10:29:10:40 | access to local variable destFileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBad.cs:9:59:9:72 | access to property FullName | item path | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected index 8870df306ea..7c2a68cec35 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected @@ -1,7 +1,16 @@ -| CommandInjection.cs:26:27:26:47 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | -| CommandInjection.cs:26:50:26:66 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | -| CommandInjection.cs:28:63:28:71 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | -| CommandInjection.cs:28:74:28:82 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | -| CommandInjection.cs:32:39:32:47 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | -| CommandInjection.cs:33:40:33:48 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | -| CommandInjection.cs:34:47:34:55 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | +edges +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:26:27:26:47 | ... + ... | +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:26:50:26:66 | ... + ... | +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:28:63:28:71 | access to local variable userInput | +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:28:74:28:82 | access to local variable userInput | +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:32:39:32:47 | access to local variable userInput | +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:33:40:33:48 | access to local variable userInput | +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:34:47:34:55 | access to local variable userInput | +#select +| CommandInjection.cs:26:27:26:47 | ... + ... | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:26:27:26:47 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | +| CommandInjection.cs:26:50:26:66 | ... + ... | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:26:50:26:66 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | +| CommandInjection.cs:28:63:28:71 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:28:63:28:71 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | +| CommandInjection.cs:28:74:28:82 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:28:74:28:82 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | +| CommandInjection.cs:32:39:32:47 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:32:39:32:47 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | +| CommandInjection.cs:33:40:33:48 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:33:40:33:48 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | +| CommandInjection.cs:34:47:34:55 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:34:47:34:55 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected index aaff4b464e4..8c41bafe5b5 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected @@ -1 +1,4 @@ -| StoredCommandInjection.cs:24:46:24:80 | ... + ... | $@ flows to here and is used in a command. | StoredCommandInjection.cs:24:54:24:80 | call to method GetString | Stored user-provided value | +edges +| StoredCommandInjection.cs:24:54:24:80 | call to method GetString | StoredCommandInjection.cs:24:46:24:80 | ... + ... | +#select +| StoredCommandInjection.cs:24:46:24:80 | ... + ... | StoredCommandInjection.cs:24:54:24:80 | call to method GetString | StoredCommandInjection.cs:24:46:24:80 | ... + ... | $@ flows to here and is used in a command. | StoredCommandInjection.cs:24:54:24:80 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected index fef8586c163..91263323cae 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected @@ -1 +1,4 @@ -| StoredXSS.cs:24:44:24:86 | ... + ... | $@ flows to here and is written to HTML or javascript. | StoredXSS.cs:24:60:24:86 | call to method GetString | Stored user-provided value | +edges +| StoredXSS.cs:24:60:24:86 | call to method GetString | StoredXSS.cs:24:44:24:86 | ... + ... | +#select +| StoredXSS.cs:24:44:24:86 | ... + ... | StoredXSS.cs:24:60:24:86 | call to method GetString | StoredXSS.cs:24:44:24:86 | ... + ... | $@ flows to here and is written to HTML or JavaScript. | StoredXSS.cs:24:60:24:86 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected index 272854d84a7..9789f8d2dd7 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected @@ -1 +1,4 @@ -| SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | $@ flows to here and is used in an SQL query. | SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | Stored user-provided value | +edges +| SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | +#select +| SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | $@ flows to here and is used in an SQL query. | SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected index 979c31c8b4d..cd94b55c638 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected @@ -1,9 +1,30 @@ -| SqlInjection.cs:39:50:39:55 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | this ASP.NET user input | -| SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | this ASP.NET user input | +edges +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:39:50:39:55 | access to local variable query1 | +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:49:62:49:81 | access to property Text | +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:61:62:61:81 | access to property Text | +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | +| SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | SqlInjection.cs:49:62:49:81 | access to property Text | +| SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | SqlInjection.cs:61:62:61:81 | access to property Text | +| SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | +| SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | +| SqlInjection.cs:49:62:49:81 | access to property Text | SqlInjection.cs:61:62:61:81 | access to property Text | +| SqlInjection.cs:49:62:49:81 | access to property Text | SqlInjection.cs:74:56:74:61 | access to local variable query1 | +| SqlInjection.cs:49:62:49:81 | access to property Text | SqlInjection.cs:75:55:75:60 | access to local variable query1 | +| SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | SqlInjection.cs:61:62:61:81 | access to property Text | +| SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | +| SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | +| SqlInjection.cs:61:62:61:81 | access to property Text | SqlInjection.cs:74:56:74:61 | access to local variable query1 | +| SqlInjection.cs:61:62:61:81 | access to property Text | SqlInjection.cs:75:55:75:60 | access to local variable query1 | +| SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | +| SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | +#select +| SqlInjection.cs:39:50:39:55 | access to local variable query1 | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:39:50:39:55 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:74:56:74:61 | access to local variable query1 | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:74:56:74:61 | access to local variable query1 | SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:74:56:74:61 | access to local variable query1 | SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:74:56:74:61 | access to local variable query1 | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:75:55:75:60 | access to local variable query1 | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:75:55:75:60 | access to local variable query1 | SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:75:55:75:60 | access to local variable query1 | SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | this ASP.NET user input | +| SqlInjection.cs:75:55:75:60 | access to local variable query1 | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | this ASP.NET user input | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected index 19247fa17e1..b41e03c73da 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected @@ -1,6 +1,14 @@ -| LDAPInjection.cs:16:54:16:78 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | -| LDAPInjection.cs:18:21:18:45 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | -| LDAPInjection.cs:25:21:25:45 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | -| LDAPInjection.cs:26:53:26:77 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | -| LDAPInjection.cs:29:48:29:70 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | -| LDAPInjection.cs:31:20:31:42 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +edges +| LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:16:54:16:78 | ... + ... | +| LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:18:21:18:45 | ... + ... | +| LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:25:21:25:45 | ... + ... | +| LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:26:53:26:77 | ... + ... | +| LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:29:48:29:70 | ... + ... | +| LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:31:20:31:42 | ... + ... | +#select +| LDAPInjection.cs:16:54:16:78 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:16:54:16:78 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +| LDAPInjection.cs:18:21:18:45 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:18:21:18:45 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +| LDAPInjection.cs:25:21:25:45 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:25:21:25:45 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +| LDAPInjection.cs:26:53:26:77 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:26:53:26:77 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +| LDAPInjection.cs:29:48:29:70 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:29:48:29:70 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +| LDAPInjection.cs:31:20:31:42 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:31:20:31:42 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected index eb80d16e9d4..8fd27bbc970 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected @@ -1 +1,4 @@ -| StoredLDAPInjection.cs:24:66:24:109 | ... + ... | $@ flows to here and is used in an LDAP query. | StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | Stored user-provided value | +edges +| StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | StoredLDAPInjection.cs:24:66:24:109 | ... + ... | +#select +| StoredLDAPInjection.cs:24:66:24:109 | ... + ... | StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | StoredLDAPInjection.cs:24:66:24:109 | ... + ... | $@ flows to here and is used in an LDAP query. | StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected index 07d9890dd50..aa41bff2494 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected @@ -1,2 +1,6 @@ -| CodeInjection.cs:31:64:31:67 | access to local variable code | $@ flows to here and is compiled as code. | CodeInjection.cs:25:23:25:45 | access to property QueryString | User-provided value | -| CodeInjection.cs:42:36:42:39 | access to local variable code | $@ flows to here and is compiled as code. | CodeInjection.cs:25:23:25:45 | access to property QueryString | User-provided value | +edges +| CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:31:64:31:67 | access to local variable code | +| CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:42:36:42:39 | access to local variable code | +#select +| CodeInjection.cs:31:64:31:67 | access to local variable code | CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:31:64:31:67 | access to local variable code | $@ flows to here and is compiled as code. | CodeInjection.cs:25:23:25:45 | access to property QueryString | User-provided value | +| CodeInjection.cs:42:36:42:39 | access to local variable code | CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:42:36:42:39 | access to local variable code | $@ flows to here and is compiled as code. | CodeInjection.cs:25:23:25:45 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected index f5e7edfc70d..df107579427 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected @@ -1,2 +1,6 @@ -| ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | $@ flows to here and is used in a resource descriptor. | ResourceInjection.cs:10:27:10:49 | access to property QueryString | User-provided value | -| ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | $@ flows to here and is used in a resource descriptor. | ResourceInjection.cs:10:27:10:49 | access to property QueryString | User-provided value | +edges +| ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | +| ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | +#select +| ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | $@ flows to here and is used in a resource descriptor. | ResourceInjection.cs:10:27:10:49 | access to property QueryString | User-provided value | +| ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | $@ flows to here and is used in a resource descriptor. | ResourceInjection.cs:10:27:10:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected b/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected index 210636ea370..b9732e9b44c 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected @@ -1,5 +1,16 @@ -| MissingXMLValidation.cs:18:26:18:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because there is no 'XmlReaderSettings' instance specifying schema validation. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | -| MissingXMLValidation.cs:23:26:23:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance does not specify the 'ValidationType' as 'Schema'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | -| MissingXMLValidation.cs:29:26:29:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance does not specify the 'ValidationType' as 'Schema'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | -| MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance specifies 'ProcessInlineSchema'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | -| MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance specifies 'ProcessSchemaLocation'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | +edges +| MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:18:26:18:58 | object creation of type StringReader | +| MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:23:26:23:58 | object creation of type StringReader | +| MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:29:26:29:58 | object creation of type StringReader | +| MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:37:26:37:58 | object creation of type StringReader | +| MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | +| MissingXMLValidation.cs:22:42:22:64 | object creation of type XmlReaderSettings | MissingXMLValidation.cs:23:61:23:72 | access to local variable badSettings1 | +| MissingXMLValidation.cs:27:42:27:64 | object creation of type XmlReaderSettings | MissingXMLValidation.cs:29:61:29:72 | access to local variable badSettings2 | +| MissingXMLValidation.cs:32:42:32:64 | object creation of type XmlReaderSettings | MissingXMLValidation.cs:37:61:37:72 | access to local variable goodSettings | +| MissingXMLValidation.cs:40:42:40:64 | object creation of type XmlReaderSettings | MissingXMLValidation.cs:47:61:47:72 | access to local variable badSettings3 | +#select +| MissingXMLValidation.cs:18:26:18:58 | object creation of type StringReader | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:18:26:18:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because there is no 'XmlReaderSettings' instance specifying schema validation. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | +| MissingXMLValidation.cs:23:26:23:58 | object creation of type StringReader | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:23:26:23:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance does not specify the 'ValidationType' as 'Schema'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | +| MissingXMLValidation.cs:29:26:29:58 | object creation of type StringReader | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:29:26:29:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance does not specify the 'ValidationType' as 'Schema'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | +| MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance specifies 'ProcessInlineSchema'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | +| MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance specifies 'ProcessSchemaLocation'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected b/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected index a17b4cbf24d..fdda0a73e98 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected @@ -1,2 +1,6 @@ -| LogForging.cs:22:21:22:43 | ... + ... | $@ flows to log entry. | LogForging.cs:19:27:19:49 | access to property QueryString | User-provided value | -| LogForging.cs:28:50:28:72 | ... + ... | $@ flows to log entry. | LogForging.cs:19:27:19:49 | access to property QueryString | User-provided value | +edges +| LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:22:21:22:43 | ... + ... | +| LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:28:50:28:72 | ... + ... | +#select +| LogForging.cs:22:21:22:43 | ... + ... | LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:22:21:22:43 | ... + ... | $@ flows to log entry. | LogForging.cs:19:27:19:49 | access to property QueryString | User-provided value | +| LogForging.cs:28:50:28:72 | ... + ... | LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:28:50:28:72 | ... + ... | $@ flows to log entry. | LogForging.cs:19:27:19:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected b/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected index 39baca89ce8..7f512300244 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected @@ -1,9 +1,16 @@ -| ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | access to local variable password | -| ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | call to method ToString | -| ExposureInTransmittedData.cs:24:32:24:41 | access to property Message | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:24:32:24:41 | access to property Message | access to property Message | -| ExposureInTransmittedData.cs:25:32:25:44 | call to method ToString | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:25:32:25:44 | call to method ToString | call to method ToString | -| ExposureInTransmittedData.cs:26:32:26:50 | access to indexer | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:26:32:26:38 | access to property Data | access to property Data | -| ExposureInTransmittedData.cs:33:53:33:53 | access to local variable p | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | -| ExposureInTransmittedData.cs:33:56:33:56 | access to local variable p | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | -| ExposureInTransmittedData.cs:34:24:34:52 | ... + ... | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | -| ExposureInTransmittedData.cs:35:27:35:27 | access to local variable p | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | +edges +| ExposureInTransmittedData.cs:26:32:26:38 | access to property Data | ExposureInTransmittedData.cs:26:32:26:50 | access to indexer | +| ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:33:53:33:53 | access to local variable p | +| ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:33:56:33:56 | access to local variable p | +| ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:34:24:34:52 | ... + ... | +| ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:35:27:35:27 | access to local variable p | +#select +| ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | access to local variable password | +| ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | call to method ToString | +| ExposureInTransmittedData.cs:24:32:24:41 | access to property Message | ExposureInTransmittedData.cs:24:32:24:41 | access to property Message | ExposureInTransmittedData.cs:24:32:24:41 | access to property Message | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:24:32:24:41 | access to property Message | access to property Message | +| ExposureInTransmittedData.cs:25:32:25:44 | call to method ToString | ExposureInTransmittedData.cs:25:32:25:44 | call to method ToString | ExposureInTransmittedData.cs:25:32:25:44 | call to method ToString | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:25:32:25:44 | call to method ToString | call to method ToString | +| ExposureInTransmittedData.cs:26:32:26:50 | access to indexer | ExposureInTransmittedData.cs:26:32:26:38 | access to property Data | ExposureInTransmittedData.cs:26:32:26:50 | access to indexer | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:26:32:26:38 | access to property Data | access to property Data | +| ExposureInTransmittedData.cs:33:53:33:53 | access to local variable p | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:33:53:33:53 | access to local variable p | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | +| ExposureInTransmittedData.cs:33:56:33:56 | access to local variable p | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:33:56:33:56 | access to local variable p | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | +| ExposureInTransmittedData.cs:34:24:34:52 | ... + ... | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:34:24:34:52 | ... + ... | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | +| ExposureInTransmittedData.cs:35:27:35:27 | access to local variable p | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:35:27:35:27 | access to local variable p | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | call to method GetField | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected b/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected index f4bfdef798b..734ac5b026c 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected @@ -1,5 +1,8 @@ -| ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | call to method ToString | -| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | access to local variable ex | -| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | access to local variable ex | -| ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | access to property StackTrace | -| ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | call to method ToString | +edges +| ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | +#select +| ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | call to method ToString | +| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | access to local variable ex | +| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | access to local variable ex | +| ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | access to property StackTrace | +| ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | call to method ToString | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected b/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected index a5a2ca8b2f9..8bf93c08f85 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected @@ -1,5 +1,7 @@ -| CleartextStorage.cs:14:50:14:59 | access to field accountKey | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:14:50:14:59 | access to field accountKey | access to field accountKey | -| CleartextStorage.cs:15:62:15:74 | call to method GetPassword | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | call to method GetPassword | -| CleartextStorage.cs:16:69:16:81 | call to method GetPassword | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:16:69:16:81 | call to method GetPassword | call to method GetPassword | -| CleartextStorage.cs:17:50:17:63 | call to method GetAccountID | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:17:50:17:63 | call to method GetAccountID | call to method GetAccountID | -| CleartextStorage.cs:25:21:25:33 | call to method GetPassword | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:25:21:25:33 | call to method GetPassword | call to method GetPassword | +edges +#select +| CleartextStorage.cs:14:50:14:59 | access to field accountKey | CleartextStorage.cs:14:50:14:59 | access to field accountKey | CleartextStorage.cs:14:50:14:59 | access to field accountKey | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:14:50:14:59 | access to field accountKey | access to field accountKey | +| CleartextStorage.cs:15:62:15:74 | call to method GetPassword | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | call to method GetPassword | +| CleartextStorage.cs:16:69:16:81 | call to method GetPassword | CleartextStorage.cs:16:69:16:81 | call to method GetPassword | CleartextStorage.cs:16:69:16:81 | call to method GetPassword | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:16:69:16:81 | call to method GetPassword | call to method GetPassword | +| CleartextStorage.cs:17:50:17:63 | call to method GetAccountID | CleartextStorage.cs:17:50:17:63 | call to method GetAccountID | CleartextStorage.cs:17:50:17:63 | call to method GetAccountID | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:17:50:17:63 | call to method GetAccountID | call to method GetAccountID | +| CleartextStorage.cs:25:21:25:33 | call to method GetPassword | CleartextStorage.cs:25:21:25:33 | call to method GetPassword | CleartextStorage.cs:25:21:25:33 | call to method GetPassword | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:25:21:25:33 | call to method GetPassword | call to method GetPassword | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected b/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected index fb8bf1f0ea2..c766b3581ea 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected @@ -1,3 +1,8 @@ -| Test.cs:20:13:20:17 | access to local variable store | Certificate added to the root certificate store. | -| Test.cs:30:13:30:17 | access to local variable store | Certificate added to the root certificate store. | -| Test.cs:75:13:75:17 | access to local variable store | Certificate added to the root certificate store. | +edges +| Test.cs:17:31:17:59 | object creation of type X509Store | Test.cs:20:13:20:17 | access to local variable store | +| Test.cs:27:31:27:86 | object creation of type X509Store | Test.cs:30:13:30:17 | access to local variable store | +| Test.cs:72:31:72:86 | object creation of type X509Store | Test.cs:75:13:75:17 | access to local variable store | +#select +| Test.cs:20:13:20:17 | access to local variable store | Test.cs:17:31:17:59 | object creation of type X509Store | Test.cs:20:13:20:17 | access to local variable store | Certificate added to the root certificate store. | +| Test.cs:30:13:30:17 | access to local variable store | Test.cs:27:31:27:86 | object creation of type X509Store | Test.cs:30:13:30:17 | access to local variable store | Certificate added to the root certificate store. | +| Test.cs:75:13:75:17 | access to local variable store | Test.cs:72:31:72:86 | object creation of type X509Store | Test.cs:75:13:75:17 | access to local variable store | Certificate added to the root certificate store. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected b/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected index 96397029155..09d661ed9c7 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected @@ -1,3 +1,5 @@ -| ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | access to indexer | -| ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | call to method getTelephone | -| ExposureOfPrivateInformation.cs:24:21:24:36 | call to method getTelephone | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:24:21:24:36 | call to method getTelephone | call to method getTelephone | +edges +#select +| ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | access to indexer | +| ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | call to method getTelephone | +| ExposureOfPrivateInformation.cs:24:21:24:36 | call to method getTelephone | ExposureOfPrivateInformation.cs:24:21:24:36 | call to method getTelephone | ExposureOfPrivateInformation.cs:24:21:24:36 | call to method getTelephone | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:24:21:24:36 | call to method getTelephone | call to method getTelephone | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected b/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected index 59363eed855..6dd51cf91ed 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected @@ -1 +1,5 @@ -| Test.cs:13:50:13:84 | access to indexer | $@ flows to here and is loaded insecurely as XML (DTD processing is enabled with an insecure resolver). | Test.cs:13:50:13:72 | access to property QueryString | User-provided value | +edges +| Test.cs:13:50:13:72 | access to property QueryString | Test.cs:13:50:13:84 | access to indexer | +| Test.cs:18:38:18:60 | object creation of type XmlReaderSettings | Test.cs:23:55:23:62 | access to local variable settings | +#select +| Test.cs:13:50:13:84 | access to indexer | Test.cs:13:50:13:72 | access to property QueryString | Test.cs:13:50:13:84 | access to indexer | $@ flows to here and is loaded insecurely as XML (DTD processing is enabled with an insecure resolver). | Test.cs:13:50:13:72 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected index 8054b637031..0b2c001a155 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected @@ -1,4 +1,10 @@ -| StoredXPathInjection.cs:27:45:27:148 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | Stored user-provided value | -| StoredXPathInjection.cs:27:45:27:148 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | Stored user-provided value | -| StoredXPathInjection.cs:30:41:30:144 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | Stored user-provided value | -| StoredXPathInjection.cs:30:41:30:144 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | Stored user-provided value | +edges +| StoredXPathInjection.cs:24:39:24:65 | call to method GetString | StoredXPathInjection.cs:27:45:27:148 | ... + ... | +| StoredXPathInjection.cs:24:39:24:65 | call to method GetString | StoredXPathInjection.cs:30:41:30:144 | ... + ... | +| StoredXPathInjection.cs:25:39:25:65 | call to method GetString | StoredXPathInjection.cs:27:45:27:148 | ... + ... | +| StoredXPathInjection.cs:25:39:25:65 | call to method GetString | StoredXPathInjection.cs:30:41:30:144 | ... + ... | +#select +| StoredXPathInjection.cs:27:45:27:148 | ... + ... | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | StoredXPathInjection.cs:27:45:27:148 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | Stored user-provided value | +| StoredXPathInjection.cs:27:45:27:148 | ... + ... | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | StoredXPathInjection.cs:27:45:27:148 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | Stored user-provided value | +| StoredXPathInjection.cs:30:41:30:144 | ... + ... | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | StoredXPathInjection.cs:30:41:30:144 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | Stored user-provided value | +| StoredXPathInjection.cs:30:41:30:144 | ... + ... | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | StoredXPathInjection.cs:30:41:30:144 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected index 31f05d8da31..7106a842df1 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected @@ -1,4 +1,10 @@ -| XPathInjection.cs:16:33:16:136 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:12:27:12:49 | access to property QueryString | User-provided value | -| XPathInjection.cs:16:33:16:136 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | -| XPathInjection.cs:19:29:19:132 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:12:27:12:49 | access to property QueryString | User-provided value | -| XPathInjection.cs:19:29:19:132 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +edges +| XPathInjection.cs:12:27:12:49 | access to property QueryString | XPathInjection.cs:16:33:16:136 | ... + ... | +| XPathInjection.cs:12:27:12:49 | access to property QueryString | XPathInjection.cs:19:29:19:132 | ... + ... | +| XPathInjection.cs:13:27:13:49 | access to property QueryString | XPathInjection.cs:16:33:16:136 | ... + ... | +| XPathInjection.cs:13:27:13:49 | access to property QueryString | XPathInjection.cs:19:29:19:132 | ... + ... | +#select +| XPathInjection.cs:16:33:16:136 | ... + ... | XPathInjection.cs:12:27:12:49 | access to property QueryString | XPathInjection.cs:16:33:16:136 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:12:27:12:49 | access to property QueryString | User-provided value | +| XPathInjection.cs:16:33:16:136 | ... + ... | XPathInjection.cs:13:27:13:49 | access to property QueryString | XPathInjection.cs:16:33:16:136 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | +| XPathInjection.cs:19:29:19:132 | ... + ... | XPathInjection.cs:12:27:12:49 | access to property QueryString | XPathInjection.cs:19:29:19:132 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:12:27:12:49 | access to property QueryString | User-provided value | +| XPathInjection.cs:19:29:19:132 | ... + ... | XPathInjection.cs:13:27:13:49 | access to property QueryString | XPathInjection.cs:19:29:19:132 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected index 86e0282dddf..69cd0591560 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected @@ -1,5 +1,22 @@ -| ExponentialRegex.cs:17:40:17:48 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | -| ExponentialRegex.cs:18:42:18:50 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | -| ExponentialRegex.cs:21:139:21:147 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | -| ExponentialRegex.cs:24:43:24:51 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | -| ExponentialRegex.cs:26:21:26:29 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | +edges +| ExponentialRegex.cs:9:55:9:83 | "^(([a-z])+.)+[A-Z]([a-z])+$" | ExponentialRegex.cs:24:19:24:34 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:9:55:9:83 | "^(([a-z])+.)+[A-Z]([a-z])+$" | ExponentialRegex.cs:26:32:26:47 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:9:55:9:83 | "^(([a-z])+.)+[A-Z]([a-z])+$" | ExponentialRegex.cs:30:32:30:47 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:17:40:17:48 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:18:42:18:50 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:21:139:21:147 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:24:43:24:51 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:26:21:26:29 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:28:47:28:55 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:29:90:29:98 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:30:21:30:29 | access to local variable userInput | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:32:57:32:65 | access to local variable userInput | +| ExponentialRegex.cs:24:19:24:34 | access to field JAVA_CLASS_REGEX | ExponentialRegex.cs:26:32:26:47 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:24:19:24:34 | access to field JAVA_CLASS_REGEX | ExponentialRegex.cs:30:32:30:47 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:26:32:26:47 | access to field JAVA_CLASS_REGEX | ExponentialRegex.cs:30:32:30:47 | access to field JAVA_CLASS_REGEX | +#select +| ExponentialRegex.cs:17:40:17:48 | access to local variable userInput | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:17:40:17:48 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | +| ExponentialRegex.cs:18:42:18:50 | access to local variable userInput | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:18:42:18:50 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | +| ExponentialRegex.cs:21:139:21:147 | access to local variable userInput | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:21:139:21:147 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | +| ExponentialRegex.cs:24:43:24:51 | access to local variable userInput | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:24:43:24:51 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | +| ExponentialRegex.cs:26:21:26:29 | access to local variable userInput | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:26:21:26:29 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected index e69de29bb2d..3c7330c9035 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected @@ -0,0 +1,3 @@ +edges +| ExponentialRegex.cs:15:28:15:50 | access to property QueryString | ExponentialRegex.cs:18:40:18:48 | access to local variable userInput | +#select diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected index c3638ab2608..50b64034e09 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected @@ -1 +1,4 @@ -| RegexInjection.cs:16:19:16:23 | access to local variable regex | $@ flows to the construction of a regular expression. | RegexInjection.cs:12:24:12:46 | access to property QueryString | User-provided value | +edges +| RegexInjection.cs:12:24:12:46 | access to property QueryString | RegexInjection.cs:16:19:16:23 | access to local variable regex | +#select +| RegexInjection.cs:16:19:16:23 | access to local variable regex | RegexInjection.cs:12:24:12:46 | access to property QueryString | RegexInjection.cs:16:19:16:23 | access to local variable regex | $@ flows to the construction of a regular expression. | RegexInjection.cs:12:24:12:46 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected index 6854cbafe32..985c4d67e31 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected @@ -1,2 +1,5 @@ -| HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | 'ConnectionString' property includes hard-coded credentials set in $@. | HardcodedCredentials.cs:56:30:56:64 | object creation of type SqlConnection | object creation of type SqlConnection | -| HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | 'ConnectionString' property includes hard-coded credentials set in $@. | HardcodedCredentials.cs:58:31:58:64 | object creation of type SqlConnection | object creation of type SqlConnection | +edges +| HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | +#select +| HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | 'ConnectionString' property includes hard-coded credentials set in $@. | HardcodedCredentials.cs:56:30:56:64 | object creation of type SqlConnection | object creation of type SqlConnection | +| HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | 'ConnectionString' property includes hard-coded credentials set in $@. | HardcodedCredentials.cs:58:31:58:64 | object creation of type SqlConnection | object creation of type SqlConnection | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected index 0aa0caa94f6..0276293a89a 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected @@ -1,8 +1,11 @@ -| HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | The hard-coded value "myPa55word" flows to $@ which is compared against $@. | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | "myPa55word" | HardcodedCredentials.cs:17:13:17:20 | access to local variable password | access to local variable password | -| HardcodedCredentials.cs:33:19:33:28 | "username" | The hard-coded value "username" flows to the $@ parameter in $@. | HardcodedCredentials.cs:33:19:33:28 | "username" | name | HardcodedCredentials.cs:31:31:45:13 | object creation of type MembershipUser | object creation of type MembershipUser | -| HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | The hard-coded value "myNewPa55word" flows to the $@ parameter in $@. | HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | newPassword | HardcodedCredentials.cs:47:9:47:54 | call to method ChangePassword | call to method ChangePassword | -| HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | This hard-coded value flows to the $@ parameter in $@. | HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | rawData | HardcodedCredentials.cs:51:33:53:25 | object creation of type X509Certificate2 | object creation of type X509Certificate2 | -| HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | The hard-coded value "myPa55word" flows to the $@ parameter in $@. | HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | password | HardcodedCredentials.cs:51:33:53:25 | object creation of type X509Certificate2 | object creation of type X509Certificate2 | -| HardcodedCredentials.cs:76:31:76:42 | "myusername" | The hard-coded value "myusername" flows to the $@ parameter in $@. | HardcodedCredentials.cs:76:31:76:42 | "myusername" | username | HardcodedCredentials.cs:76:9:76:57 | call to method CreateUser | call to method CreateUser | -| HardcodedCredentials.cs:76:45:76:56 | "mypassword" | The hard-coded value "mypassword" flows to the $@ parameter in $@. | HardcodedCredentials.cs:76:45:76:56 | "mypassword" | password | HardcodedCredentials.cs:76:9:76:57 | call to method CreateUser | call to method CreateUser | -| TestHardcodedCredentials.cs:26:19:26:28 | "username" | The hard-coded value "username" flows to the $@ parameter in $@. | TestHardcodedCredentials.cs:26:19:26:28 | "username" | name | TestHardcodedCredentials.cs:24:31:38:13 | object creation of type MembershipUser | object creation of type MembershipUser | +edges +| HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | +#select +| HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | The hard-coded value "myPa55word" flows to $@ which is compared against $@. | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | "myPa55word" | HardcodedCredentials.cs:17:13:17:20 | access to local variable password | access to local variable password | +| HardcodedCredentials.cs:33:19:33:28 | "username" | HardcodedCredentials.cs:33:19:33:28 | "username" | HardcodedCredentials.cs:33:19:33:28 | "username" | The hard-coded value "username" flows to the $@ parameter in $@. | HardcodedCredentials.cs:33:19:33:28 | "username" | name | HardcodedCredentials.cs:31:31:45:13 | object creation of type MembershipUser | object creation of type MembershipUser | +| HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | The hard-coded value "myNewPa55word" flows to the $@ parameter in $@. | HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | newPassword | HardcodedCredentials.cs:47:9:47:54 | call to method ChangePassword | call to method ChangePassword | +| HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | This hard-coded value flows to the $@ parameter in $@. | HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | rawData | HardcodedCredentials.cs:51:33:53:25 | object creation of type X509Certificate2 | object creation of type X509Certificate2 | +| HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | The hard-coded value "myPa55word" flows to the $@ parameter in $@. | HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | password | HardcodedCredentials.cs:51:33:53:25 | object creation of type X509Certificate2 | object creation of type X509Certificate2 | +| HardcodedCredentials.cs:76:31:76:42 | "myusername" | HardcodedCredentials.cs:76:31:76:42 | "myusername" | HardcodedCredentials.cs:76:31:76:42 | "myusername" | The hard-coded value "myusername" flows to the $@ parameter in $@. | HardcodedCredentials.cs:76:31:76:42 | "myusername" | username | HardcodedCredentials.cs:76:9:76:57 | call to method CreateUser | call to method CreateUser | +| HardcodedCredentials.cs:76:45:76:56 | "mypassword" | HardcodedCredentials.cs:76:45:76:56 | "mypassword" | HardcodedCredentials.cs:76:45:76:56 | "mypassword" | The hard-coded value "mypassword" flows to the $@ parameter in $@. | HardcodedCredentials.cs:76:45:76:56 | "mypassword" | password | HardcodedCredentials.cs:76:9:76:57 | call to method CreateUser | call to method CreateUser | +| TestHardcodedCredentials.cs:26:19:26:28 | "username" | TestHardcodedCredentials.cs:26:19:26:28 | "username" | TestHardcodedCredentials.cs:26:19:26:28 | "username" | The hard-coded value "username" flows to the $@ parameter in $@. | TestHardcodedCredentials.cs:26:19:26:28 | "username" | name | TestHardcodedCredentials.cs:24:31:38:13 | object creation of type MembershipUser | object creation of type MembershipUser | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected b/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected index af5a1417fa5..f04e8969bfc 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected @@ -1,8 +1,17 @@ -| ConditionalBypass.cs:19:13:19:33 | call to method login | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:18:13:18:30 | ... == ... | this condition | ConditionalBypass.cs:14:26:14:48 | access to property QueryString | user input | -| ConditionalBypass.cs:25:13:25:33 | call to method login | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:24:13:24:45 | call to method Equals | this condition | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | user input | -| ConditionalBypass.cs:31:13:31:33 | call to method login | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:29:13:29:40 | ... == ... | this condition | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | user input | -| ConditionalBypass.cs:35:13:35:39 | call to method reCheckAuth | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:29:13:29:40 | ... == ... | this condition | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | user input | -| ConditionalBypass.cs:48:13:48:33 | call to method login | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:46:13:46:46 | ... == ... | this condition | ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | user input | -| ConditionalBypass.cs:53:13:53:33 | call to method login | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:51:13:51:29 | access to property HostName | this condition | ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | user input | -| ConditionalBypass.cs:75:13:75:33 | call to method login | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:74:13:74:40 | ... == ... | this condition | ConditionalBypass.cs:72:34:72:52 | access to property Cookies | user input | -| ConditionalBypass.cs:87:13:87:33 | call to method login | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:86:13:86:40 | ... == ... | this condition | ConditionalBypass.cs:85:34:85:52 | access to property Cookies | user input | +edges +| ConditionalBypass.cs:14:26:14:48 | access to property QueryString | ConditionalBypass.cs:18:13:18:30 | ... == ... | +| ConditionalBypass.cs:21:34:21:52 | access to property Cookies | ConditionalBypass.cs:24:13:24:45 | call to method Equals | +| ConditionalBypass.cs:21:34:21:52 | access to property Cookies | ConditionalBypass.cs:29:13:29:40 | ... == ... | +| ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | ConditionalBypass.cs:46:13:46:46 | ... == ... | +| ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | ConditionalBypass.cs:51:13:51:29 | access to property HostName | +| ConditionalBypass.cs:72:34:72:52 | access to property Cookies | ConditionalBypass.cs:74:13:74:40 | ... == ... | +| ConditionalBypass.cs:85:34:85:52 | access to property Cookies | ConditionalBypass.cs:86:13:86:40 | ... == ... | +#select +| ConditionalBypass.cs:19:13:19:33 | call to method login | ConditionalBypass.cs:14:26:14:48 | access to property QueryString | ConditionalBypass.cs:18:13:18:30 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:18:13:18:30 | ... == ... | this condition | ConditionalBypass.cs:14:26:14:48 | access to property QueryString | user input | +| ConditionalBypass.cs:25:13:25:33 | call to method login | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | ConditionalBypass.cs:24:13:24:45 | call to method Equals | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:24:13:24:45 | call to method Equals | this condition | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | user input | +| ConditionalBypass.cs:31:13:31:33 | call to method login | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | ConditionalBypass.cs:29:13:29:40 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:29:13:29:40 | ... == ... | this condition | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | user input | +| ConditionalBypass.cs:35:13:35:39 | call to method reCheckAuth | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | ConditionalBypass.cs:29:13:29:40 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:29:13:29:40 | ... == ... | this condition | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | user input | +| ConditionalBypass.cs:48:13:48:33 | call to method login | ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | ConditionalBypass.cs:46:13:46:46 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:46:13:46:46 | ... == ... | this condition | ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | user input | +| ConditionalBypass.cs:53:13:53:33 | call to method login | ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | ConditionalBypass.cs:51:13:51:29 | access to property HostName | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:51:13:51:29 | access to property HostName | this condition | ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | user input | +| ConditionalBypass.cs:75:13:75:33 | call to method login | ConditionalBypass.cs:72:34:72:52 | access to property Cookies | ConditionalBypass.cs:74:13:74:40 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:74:13:74:40 | ... == ... | this condition | ConditionalBypass.cs:72:34:72:52 | access to property Cookies | user input | +| ConditionalBypass.cs:87:13:87:33 | call to method login | ConditionalBypass.cs:85:34:85:52 | access to property Cookies | ConditionalBypass.cs:86:13:86:40 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:86:13:86:40 | ... == ... | this condition | ConditionalBypass.cs:85:34:85:52 | access to property Cookies | user input | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected index bd909a8d5cd..9fea9d5d65b 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected @@ -1,12 +1,24 @@ -| HtmlEncode.cs:12:28:12:65 | ... + ... | This HTML expression may include data from a $@. | HtmlEncode.cs:12:40:12:65 | call to method UrlEncode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | This SQL expression may include data from a $@. | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | This SQL expression may include data from a $@. | InappropriateEncoding.cs:68:16:68:42 | call to method Replace | possibly inappropriately encoded value | -| InappropriateEncoding.cs:33:22:33:34 | call to method Encode | This HTML expression may include data from a $@. | InappropriateEncoding.cs:33:22:33:34 | call to method Encode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:34:22:34:49 | call to method UrlEncode | This HTML expression may include data from a $@. | InappropriateEncoding.cs:34:22:34:49 | call to method UrlEncode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:35:22:35:73 | call to method UrlEncode | This HTML expression may include data from a $@. | InappropriateEncoding.cs:35:22:35:73 | call to method UrlEncode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:37:32:37:43 | access to local variable encodedValue | This HTML expression may include data from a $@. | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:38:22:38:59 | ... + ... | This HTML expression may include data from a $@. | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:39:22:39:71 | call to method Format | This HTML expression may include data from a $@. | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | possibly inappropriately encoded value | -| InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | This URL expression may include data from a $@. | InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | possibly inappropriately encoded value | -| SqlEncode.cs:17:46:17:50 | access to local variable query | This SQL expression may include data from a $@. | SqlEncode.cs:16:62:16:87 | call to method Replace | possibly inappropriately encoded value | -| UrlEncode.cs:12:31:12:69 | ... + ... | This URL expression may include data from a $@. | UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | possibly inappropriately encoded value | +edges +| HtmlEncode.cs:12:40:12:65 | call to method UrlEncode | HtmlEncode.cs:12:28:12:65 | ... + ... | +| InappropriateEncoding.cs:15:28:15:40 | call to method Encode | InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | +| InappropriateEncoding.cs:15:28:15:40 | call to method Encode | InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | +| InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:37:32:37:43 | access to local variable encodedValue | +| InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:38:22:38:59 | ... + ... | +| InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:39:22:39:71 | call to method Format | +| InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | +| InappropriateEncoding.cs:68:16:68:42 | call to method Replace | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | +| SqlEncode.cs:16:62:16:87 | call to method Replace | SqlEncode.cs:17:46:17:50 | access to local variable query | +| UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | UrlEncode.cs:12:31:12:69 | ... + ... | +#select +| HtmlEncode.cs:12:28:12:65 | ... + ... | HtmlEncode.cs:12:40:12:65 | call to method UrlEncode | HtmlEncode.cs:12:28:12:65 | ... + ... | This HTML expression may include data from a $@. | HtmlEncode.cs:12:40:12:65 | call to method UrlEncode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | This SQL expression may include data from a $@. | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | InappropriateEncoding.cs:68:16:68:42 | call to method Replace | InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | This SQL expression may include data from a $@. | InappropriateEncoding.cs:68:16:68:42 | call to method Replace | possibly inappropriately encoded value | +| InappropriateEncoding.cs:33:22:33:34 | call to method Encode | InappropriateEncoding.cs:33:22:33:34 | call to method Encode | InappropriateEncoding.cs:33:22:33:34 | call to method Encode | This HTML expression may include data from a $@. | InappropriateEncoding.cs:33:22:33:34 | call to method Encode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:34:22:34:49 | call to method UrlEncode | InappropriateEncoding.cs:34:22:34:49 | call to method UrlEncode | InappropriateEncoding.cs:34:22:34:49 | call to method UrlEncode | This HTML expression may include data from a $@. | InappropriateEncoding.cs:34:22:34:49 | call to method UrlEncode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:35:22:35:73 | call to method UrlEncode | InappropriateEncoding.cs:35:22:35:73 | call to method UrlEncode | InappropriateEncoding.cs:35:22:35:73 | call to method UrlEncode | This HTML expression may include data from a $@. | InappropriateEncoding.cs:35:22:35:73 | call to method UrlEncode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:37:32:37:43 | access to local variable encodedValue | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:37:32:37:43 | access to local variable encodedValue | This HTML expression may include data from a $@. | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:38:22:38:59 | ... + ... | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:38:22:38:59 | ... + ... | This HTML expression may include data from a $@. | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:39:22:39:71 | call to method Format | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:39:22:39:71 | call to method Format | This HTML expression may include data from a $@. | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | possibly inappropriately encoded value | +| InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | This URL expression may include data from a $@. | InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | possibly inappropriately encoded value | +| SqlEncode.cs:17:46:17:50 | access to local variable query | SqlEncode.cs:16:62:16:87 | call to method Replace | SqlEncode.cs:17:46:17:50 | access to local variable query | This SQL expression may include data from a $@. | SqlEncode.cs:16:62:16:87 | call to method Replace | possibly inappropriately encoded value | +| UrlEncode.cs:12:31:12:69 | ... + ... | UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | UrlEncode.cs:12:31:12:69 | ... + ... | This URL expression may include data from a $@. | UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | possibly inappropriately encoded value | From e908b090fdc9bf308d147b58a3771d10932dfc8b Mon Sep 17 00:00:00 2001 From: calum Date: Mon, 29 Oct 2018 11:44:58 +0000 Subject: [PATCH 18/94] C#: Always use PathNode in a path-problem query. --- .../src/Security Features/CWE-022/TaintedPath.ql | 4 ++-- .../ql/src/Security Features/CWE-022/ZipSlip.ql | 4 ++-- .../CWE-078/CommandInjection.ql | 4 ++-- .../CWE-078/StoredCommandInjection.ql | 4 ++-- .../src/Security Features/CWE-079/StoredXSS.ql | 12 ++++++------ .../CWE-089/SecondOrderSqlInjection.ql | 4 ++-- .../Security Features/CWE-089/SqlInjection.ql | 8 ++++---- .../Security Features/CWE-090/LDAPInjection.ql | 4 ++-- .../CWE-090/StoredLDAPInjection.ql | 4 ++-- .../Security Features/CWE-094/CodeInjection.ql | 4 ++-- .../CWE-099/ResourceInjection.ql | 4 ++-- .../CWE-112/MissingXMLValidation.ql | 8 ++++---- .../src/Security Features/CWE-117/LogForging.ql | 4 ++-- .../CWE-201/ExposureInTransmittedData.ql | 4 ++-- .../CWE-209/ExceptionInformationExposure.ql | 4 ++-- .../CWE-312/CleartextStorage.ql | 4 ++-- .../CWE-359/ExposureOfPrivateInformation.ql | 4 ++-- .../src/Security Features/CWE-601/UrlRedirect.ql | 4 ++-- .../CWE-611/UntrustedDataInsecureXml.ql | 8 ++++---- .../CWE-643/StoredXPathInjection.ql | 4 ++-- .../Security Features/CWE-643/XPathInjection.ql | 4 ++-- csharp/ql/src/Security Features/CWE-730/ReDoS.ql | 8 ++++---- .../Security Features/CWE-730/RegexInjection.ql | 8 ++++---- .../CWE-798/HardcodedConnectionString.ql | 8 ++++---- .../CWE-798/HardcodedCredentials.ql | 7 +++++-- .../CWE-807/ConditionalBypass.ql | 6 +++--- .../src/Security Features/InsecureRandomness.ql | 10 ++++++---- .../src/semmle/code/csharp/dataflow/DataFlow.qll | 6 ------ .../CWE-338/InsecureRandomness.expected | 16 +++++++++++++--- 29 files changed, 91 insertions(+), 82 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql b/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql index 9d6e55e44c9..d08cc2ca564 100644 --- a/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql +++ b/csharp/ql/src/Security Features/CWE-022/TaintedPath.ql @@ -18,5 +18,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in a path.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in a path.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql index 1d93d480634..fc687c1d6b2 100644 --- a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql +++ b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql @@ -17,5 +17,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration zipTaintTracking, DataFlow::PathNode source, DataFlow::PathNode sink where zipTaintTracking.hasFlowPath(source, sink) -select sink, source, sink, - "Unsanitized zip archive $@, which may contain '..', is used in a file system operation.", source, "item path" +select sink.getNode(), source, sink, + "Unsanitized zip archive $@, which may contain '..', is used in a file system operation.", source.getNode(), "item path" diff --git a/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql b/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql index 316c0676113..337d191eae1 100644 --- a/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql +++ b/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql @@ -18,5 +18,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in a command.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in a command.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql b/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql index a74cbb10ce6..be51a9e347e 100644 --- a/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql +++ b/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql @@ -25,5 +25,5 @@ class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in a command.", source, "Stored user-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in a command.", source.getNode(), "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql b/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql index 2909269df2a..80f16f35d4a 100644 --- a/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql +++ b/csharp/ql/src/Security Features/CWE-079/StoredXSS.ql @@ -21,11 +21,11 @@ class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { } } -from StoredTaintTrackingConfiguration c, StoredFlowSource source, Sink sink, string explanation -where c.hasFlow(source, sink) +from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink, string explanation +where c.hasFlowPath(source, sink) and - if exists(sink.explanation()) - then explanation = ": " + sink.explanation() + "." + if exists(sink.getNode().(Sink).explanation()) + then explanation = ": " + sink.getNode().(Sink).explanation() + "." else explanation = "." -select sink, source.getPathNode(c), sink.getPathNode(c), - "$@ flows to here and is written to HTML or JavaScript" + explanation, source, "Stored user-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is written to HTML or JavaScript" + explanation, source.getNode(), "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql b/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql index d4d1c419241..3e533dfd993 100644 --- a/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql +++ b/csharp/ql/src/Security Features/CWE-089/SecondOrderSqlInjection.ql @@ -23,5 +23,5 @@ class StoredTaintTrackingConfiguration extends SqlInjection::TaintTrackingConfig from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in an SQL query.", source, "Stored user-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in an SQL query.", source.getNode(), "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql b/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql index 9bc70bd56b4..f06eab7ef37 100644 --- a/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql +++ b/csharp/ql/src/Security Features/CWE-089/SqlInjection.ql @@ -14,7 +14,7 @@ import csharp import semmle.code.csharp.security.dataflow.SqlInjection::SqlInjection import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, RemoteFlowSource source, Sink sink -where c.hasFlow(source, sink) -select sink, source.getPathNode(c), sink.getPathNode(c), - "Query might include code from $@.", source, ("this " + source.getSourceType()) +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, + "Query might include code from $@.", source, ("this " + source.getNode().(RemoteFlowSource).getSourceType()) diff --git a/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql b/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql index b2c1cfb7c93..669e82e1d7e 100644 --- a/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql +++ b/csharp/ql/src/Security Features/CWE-090/LDAPInjection.ql @@ -15,5 +15,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in an LDAP query.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in an LDAP query.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql b/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql index 5d11e89e838..846ad8735ac 100644 --- a/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql +++ b/csharp/ql/src/Security Features/CWE-090/StoredLDAPInjection.ql @@ -22,5 +22,5 @@ class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in an LDAP query.", source, "Stored user-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in an LDAP query.", source.getNode(), "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql b/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql index a4447309b7c..de26ec087e1 100644 --- a/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql +++ b/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql @@ -17,5 +17,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is compiled as code.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is compiled as code.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql b/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql index 3f842b1d4f4..50b3bc2c45f 100644 --- a/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql +++ b/csharp/ql/src/Security Features/CWE-099/ResourceInjection.ql @@ -15,5 +15,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in a resource descriptor.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in a resource descriptor.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql b/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql index 67c8891fd7a..e2c051f260e 100644 --- a/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql +++ b/csharp/ql/src/Security Features/CWE-112/MissingXMLValidation.ql @@ -13,7 +13,7 @@ import csharp import semmle.code.csharp.security.dataflow.MissingXMLValidation::MissingXMLValidation import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, source.getPathNode(c), sink.getPathNode(c), - "$@ flows to here and is processed as XML without validation because " + sink.getReason(), source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, + "$@ flows to here and is processed as XML without validation because " + sink.getNode().(Sink).getReason(), source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-117/LogForging.ql b/csharp/ql/src/Security Features/CWE-117/LogForging.ql index 01985c85c8c..010a46f0650 100644 --- a/csharp/ql/src/Security Features/CWE-117/LogForging.ql +++ b/csharp/ql/src/Security Features/CWE-117/LogForging.ql @@ -15,5 +15,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to log entry.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to log entry.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql b/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql index 482c9de2eab..13377c0e39d 100644 --- a/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql +++ b/csharp/ql/src/Security Features/CWE-201/ExposureInTransmittedData.ql @@ -52,5 +52,5 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { from TaintTrackingConfiguration configuration, DataFlow::PathNode source, DataFlow::PathNode sink where configuration.hasFlowPath(source, sink) -select sink, source, sink, - "Sensitive information from $@ flows to here, and is transmitted to the user.", source, source.toString() +select sink.getNode(), source, sink, + "Sensitive information from $@ flows to here, and is transmitted to the user.", source.getNode(), source.toString() diff --git a/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql b/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql index 935e1e15554..92e0a2c2905 100644 --- a/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql +++ b/csharp/ql/src/Security Features/CWE-209/ExceptionInformationExposure.ql @@ -59,5 +59,5 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "Exception information from $@ flows to here, and is exposed to the user.", source, source.toString() +select sink.getNode(), source, sink, + "Exception information from $@ flows to here, and is exposed to the user.", source.getNode(), source.toString() diff --git a/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql b/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql index 17d09cb368d..86a40318b83 100644 --- a/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql +++ b/csharp/ql/src/Security Features/CWE-312/CleartextStorage.ql @@ -17,5 +17,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "Sensitive data returned by $@ is stored here.", source, source.toString() +select sink.getNode(), source, sink, + "Sensitive data returned by $@ is stored here.", source.getNode(), source.toString() diff --git a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql index d2d593f7025..430dcd0c5ce 100644 --- a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql +++ b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql @@ -15,5 +15,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "Private data returned by $@ is written to an external location.", source, source.toString() +select sink.getNode(), source, sink, + "Private data returned by $@ is written to an external location.", source.getNode(), source.toString() diff --git a/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql b/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql index c499c9860fb..e951bba312d 100644 --- a/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql +++ b/csharp/ql/src/Security Features/CWE-601/UrlRedirect.ql @@ -15,5 +15,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "Untrusted URL redirection due to $@.", source, "user-provided value" +select sink.getNode(), source, sink, + "Untrusted URL redirection due to $@.", source.getNode(), "user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql b/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql index fa1c5a93e99..6458534cbf4 100644 --- a/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql +++ b/csharp/ql/src/Security Features/CWE-611/UntrustedDataInsecureXml.ql @@ -14,7 +14,7 @@ import csharp import semmle.code.csharp.security.dataflow.XMLEntityInjection::XMLEntityInjection import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) -select sink, source.getPathNode(c), sink.getPathNode(c), - "$@ flows to here and is loaded insecurely as XML (" + sink.getReason() +").", source, "User-provided value" +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, + "$@ flows to here and is loaded insecurely as XML (" + sink.getNode().(Sink).getReason() +").", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql b/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql index adb34437b2b..3734533d9f0 100644 --- a/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql +++ b/csharp/ql/src/Security Features/CWE-643/StoredXPathInjection.ql @@ -23,5 +23,5 @@ class StoredTaintTrackingConfiguration extends XPathInjection::TaintTrackingConf from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in an XPath expression.", source, "Stored user-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in an XPath expression.", source.getNode(), "Stored user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql b/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql index 6cc18e5dac0..e5eba0b9db4 100644 --- a/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql +++ b/csharp/ql/src/Security Features/CWE-643/XPathInjection.ql @@ -15,5 +15,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink, source, sink, - "$@ flows to here and is used in an XPath expression.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to here and is used in an XPath expression.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql index d0675f8c06f..bb159cc0c6a 100644 --- a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql +++ b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql @@ -15,9 +15,9 @@ import semmle.code.csharp.security.dataflow.ReDoS::ReDoS import semmle.code.csharp.frameworks.system.text.RegularExpressions import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, DataFlow::Node sink -where c.hasFlow(source, sink) +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) // No global timeout set and not exists(RegexGlobalTimeout r) -select sink, source.getPathNode(c), sink.getPathNode(c), - "$@ flows to regular expression operation with dangerous regex.", source, "User-provided value" +select sink.getNode().(Sink), source, sink, + "$@ flows to regular expression operation with dangerous regex.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql b/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql index 458fb366bd2..2582acc7ebe 100644 --- a/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql +++ b/csharp/ql/src/Security Features/CWE-730/RegexInjection.ql @@ -16,9 +16,9 @@ import semmle.code.csharp.security.dataflow.RegexInjection::RegexInjection import semmle.code.csharp.frameworks.system.text.RegularExpressions import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink -where c.hasFlow(source, sink) +from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) // No global timeout set and not exists(RegexGlobalTimeout r) -select sink, source.getPathNode(c), sink.getPathNode(c), - "$@ flows to the construction of a regular expression.", source, "User-provided value" +select sink.getNode(), source, sink, + "$@ flows to the construction of a regular expression.", source.getNode(), "User-provided value" diff --git a/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql b/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql index 4585057055d..481268366cb 100644 --- a/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql +++ b/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql @@ -48,8 +48,8 @@ class ConnectionStringTaintTrackingConfiguration extends TaintTracking::Configur } } -from ConnectionStringTaintTrackingConfiguration c, DataFlow::Node source, DataFlow::Node sink -where c.hasFlow(source, sink) -select source, source.getPathNode(c), sink.getPathNode(c), +from ConnectionStringTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select source.getNode(), source, sink, "'ConnectionString' property includes hard-coded credentials set in $@.", - any(Call call | call.getAnArgument() = sink.asExpr()) as call, call.toString() + any(Call call | call.getAnArgument() = sink.getNode().asExpr()) as call, call.toString() diff --git a/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql b/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql index 11ddc864418..11d4307d05e 100644 --- a/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql +++ b/csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql @@ -14,15 +14,18 @@ import csharp import semmle.code.csharp.security.dataflow.HardcodedCredentials::HardcodedCredentials import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from TaintTrackingConfiguration c, Source source, Sink sink, string value +from TaintTrackingConfiguration c, Source source, Sink sink, DataFlow::PathNode sourcePath, DataFlow::PathNode sinkPath, + string value where + source = sourcePath.getNode() and + sink = sinkPath.getNode() and c.hasFlow(source, sink) and // Print the source value if it's available if exists(source.asExpr().getValue()) then value = "The hard-coded value \"" + source.asExpr().getValue() + "\"" else value = "This hard-coded value" -select source, source.getPathNode(c), sink.getPathNode(c), +select source, sourcePath, sinkPath, value + " flows to " + sink.getSinkDescription() + ".", sink, sink.getSinkName(), sink.getSupplementaryElement(), sink.getSupplementaryElement().toString() diff --git a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql index 013320f9252..6b8dd7aee44 100644 --- a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql +++ b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql @@ -15,8 +15,8 @@ import csharp import semmle.code.csharp.security.dataflow.ConditionalBypass::UserControlledBypassOfSensitiveMethod import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph -from Configuration config, Source source, Sink sink -where config.hasFlow(source, sink) -select sink.getSensitiveMethodCall(), source.getPathNode(config), sink.getPathNode(config), +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode().(Sink).getSensitiveMethodCall(), source, sink, "Sensitive method may not be executed depending on $@, which flows from $@.", sink, "this condition", source, "user input" diff --git a/csharp/ql/src/Security Features/InsecureRandomness.ql b/csharp/ql/src/Security Features/InsecureRandomness.ql index b03b49f2264..5b270a76013 100644 --- a/csharp/ql/src/Security Features/InsecureRandomness.ql +++ b/csharp/ql/src/Security Features/InsecureRandomness.ql @@ -3,7 +3,7 @@ * @description Using a cryptographically weak pseudo-random number generator to generate a * security sensitive value may allow an attacker to predict what sensitive value will * be generated. - * @kind problem + * @kind path-problem * @problem.severity warning * @precision high * @id cs/insecure-randomness @@ -12,6 +12,7 @@ */ import csharp import semmle.code.csharp.frameworks.Test +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph module Random { import semmle.code.csharp.dataflow.flowsources.Remote @@ -103,6 +104,7 @@ module Random { } } -from Random::TaintTrackingConfiguration randomTracking, Random::Source source, Random::Sink sink -where randomTracking.hasFlow(source, sink) -select sink, "Cryptographically insecure random number is generated at $@ and used here in a security context.", source, source.toString() +from Random::TaintTrackingConfiguration randomTracking, DataFlow::PathNode source, DataFlow::PathNode sink +where randomTracking.hasFlowPath(source, sink) +select sink.getNode(), source, sink, + "Cryptographically insecure random number is generated at $@ and used here in a security context.", source.getNode(), source.toString() diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index d05ce2a4d81..6843d67087b 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -35,12 +35,6 @@ module DataFlow { /** Gets the location of this node. */ Location getLocation() { none() } - - /** Gets the path node for this node. */ - PathNode getPathNode(Configuration config) { - result.getNode() = this and - result.getConfiguration() = config - } } /** diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected index 215587f5754..dd5727c7a46 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected @@ -1,3 +1,13 @@ -| InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:28:29:28:43 | call to method Next | call to method Next | -| InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:60:31:60:39 | call to method Next | call to method Next | -| InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:72:31:72:39 | call to method Next | call to method Next | +edges +| InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:29:27:29:61 | call to method GetString | +| InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:31:16:31:32 | call to method ToString | +| InsecureRandomness.cs:29:27:29:61 | call to method GetString | InsecureRandomness.cs:31:16:31:32 | call to method ToString | +| InsecureRandomness.cs:31:16:31:32 | call to method ToString | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | +| InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:62:16:62:32 | call to method ToString | +| InsecureRandomness.cs:62:16:62:32 | call to method ToString | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | +| InsecureRandomness.cs:72:31:72:39 | call to method Next | InsecureRandomness.cs:74:16:74:21 | access to local variable result | +| InsecureRandomness.cs:74:16:74:21 | access to local variable result | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | +#select +| InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:28:29:28:43 | call to method Next | call to method Next | +| InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:60:31:60:39 | call to method Next | call to method Next | +| InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | InsecureRandomness.cs:72:31:72:39 | call to method Next | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:72:31:72:39 | call to method Next | call to method Next | From cf4b04a3ee4feec1506964deed784267e50c553c Mon Sep 17 00:00:00 2001 From: calum Date: Fri, 16 Nov 2018 11:52:20 +0000 Subject: [PATCH 19/94] C#: Address review comments - adding .getNode() where appropriate. --- .../CWE-327/DontInstallRootCert.ql | 2 +- .../CWE-359/ExposureOfPrivateInformation.ql | 2 +- .../CWE-807/ConditionalBypass.ql | 2 +- .../CWE-838/InappropriateEncoding.ql | 4 +- .../Security Features/InsecureRandomness.ql | 2 +- .../CWE-601/UrlRedirect/UrlRedirect.expected | 44 +++++++++++++------ 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql b/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql index d9f1dd3ef88..3a4293fddac 100644 --- a/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql +++ b/csharp/ql/src/Security Features/CWE-327/DontInstallRootCert.ql @@ -33,6 +33,6 @@ class AddCertToRootStoreConfig extends DataFlow::Configuration { from DataFlow::PathNode oc, DataFlow::PathNode mc, AddCertToRootStoreConfig config where config.hasFlowPath(oc, mc) -select mc, oc, mc, +select mc.getNode(), oc, mc, "Certificate added to the root certificate store." diff --git a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql index 430dcd0c5ce..9f952f4db50 100644 --- a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql +++ b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql @@ -16,4 +16,4 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) select sink.getNode(), source, sink, - "Private data returned by $@ is written to an external location.", source.getNode(), source.toString() + "Private data returned by $@ is written to an external location.", source.getNode(), source.getNode().toString() diff --git a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql index 6b8dd7aee44..cf16ee88306 100644 --- a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql +++ b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql @@ -19,4 +19,4 @@ from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode().(Sink).getSensitiveMethodCall(), source, sink, "Sensitive method may not be executed depending on $@, which flows from $@.", - sink, "this condition", source, "user input" + sink.getNode(), "this condition", source.getNode(), "user input" diff --git a/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql b/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql index 9735cc52a63..133f1f3b3b2 100644 --- a/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql +++ b/csharp/ql/src/Security Features/CWE-838/InappropriateEncoding.ql @@ -156,5 +156,5 @@ module EncodingConfigurations { from RequiresEncodingConfiguration c, PathNode encodedValue, PathNode sink, string kind where c.hasWrongEncoding(encodedValue, sink, kind) -select sink, encodedValue, sink, - "This " + kind + " may include data from a $@.", encodedValue, "possibly inappropriately encoded value" +select sink.getNode(), encodedValue, sink, + "This " + kind + " may include data from a $@.", encodedValue.getNode(), "possibly inappropriately encoded value" diff --git a/csharp/ql/src/Security Features/InsecureRandomness.ql b/csharp/ql/src/Security Features/InsecureRandomness.ql index 5b270a76013..37dd0f1d481 100644 --- a/csharp/ql/src/Security Features/InsecureRandomness.ql +++ b/csharp/ql/src/Security Features/InsecureRandomness.ql @@ -107,4 +107,4 @@ module Random { from Random::TaintTrackingConfiguration randomTracking, DataFlow::PathNode source, DataFlow::PathNode sink where randomTracking.hasFlowPath(source, sink) select sink.getNode(), source, sink, - "Cryptographically insecure random number is generated at $@ and used here in a security context.", source.getNode(), source.toString() + "Cryptographically insecure random number is generated at $@ and used here in a security context.", source.getNode(), source.getNode().toString() diff --git a/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected b/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected index eec21ad90a1..97a7725ef1b 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected @@ -1,14 +1,30 @@ -| UrlRedirect.cs:14:31:14:61 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:14:31:14:53 | access to property QueryString | user-provided value | -| UrlRedirect.cs:39:44:39:74 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:39:44:39:66 | access to property QueryString | user-provided value | -| UrlRedirect.cs:40:47:40:77 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:40:47:40:69 | access to property QueryString | user-provided value | -| UrlRedirect.cs:49:29:49:31 | access to local variable url | Untrusted URL redirection due to $@. | UrlRedirect.cs:24:22:24:44 | access to property QueryString | user-provided value | -| UrlRedirectCore.cs:18:22:18:26 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | -| UrlRedirectCore.cs:21:44:21:48 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | -| UrlRedirectCore.cs:27:46:27:50 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | -| UrlRedirectCore.cs:33:66:33:70 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | -| UrlRedirectCore.cs:36:49:36:53 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | -| UrlRedirectCore.cs:39:69:39:73 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | -| UrlRedirectCore.cs:42:39:42:53 | ... + ... | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | -| UrlRedirectCore.cs:50:28:50:32 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value | -| UrlRedirectCore.cs:55:32:55:45 | object creation of type Uri | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value | -| UrlRedirectCore.cs:58:31:58:35 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value | +edges +| UrlRedirect.cs:14:31:14:53 | access to property QueryString | UrlRedirect.cs:14:31:14:61 | access to indexer | +| UrlRedirect.cs:24:22:24:44 | access to property QueryString | UrlRedirect.cs:49:29:49:31 | access to local variable url | +| UrlRedirect.cs:39:44:39:66 | access to property QueryString | UrlRedirect.cs:39:44:39:74 | access to indexer | +| UrlRedirect.cs:40:47:40:69 | access to property QueryString | UrlRedirect.cs:40:47:40:77 | access to indexer | +| UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:18:22:18:26 | access to parameter value | +| UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:21:44:21:48 | call to operator implicit conversion | +| UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:27:46:27:50 | call to operator implicit conversion | +| UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:33:66:33:70 | access to parameter value | +| UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:36:49:36:53 | call to operator implicit conversion | +| UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:39:69:39:73 | access to parameter value | +| UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:42:39:42:53 | ... + ... | +| UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:50:28:50:32 | access to parameter value | +| UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:55:32:55:45 | object creation of type Uri | +| UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:58:31:58:35 | access to parameter value | +#select +| UrlRedirect.cs:14:31:14:61 | access to indexer | UrlRedirect.cs:14:31:14:53 | access to property QueryString | UrlRedirect.cs:14:31:14:61 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:14:31:14:53 | access to property QueryString | user-provided value | +| UrlRedirect.cs:39:44:39:74 | access to indexer | UrlRedirect.cs:39:44:39:66 | access to property QueryString | UrlRedirect.cs:39:44:39:74 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:39:44:39:66 | access to property QueryString | user-provided value | +| UrlRedirect.cs:40:47:40:77 | access to indexer | UrlRedirect.cs:40:47:40:69 | access to property QueryString | UrlRedirect.cs:40:47:40:77 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:40:47:40:69 | access to property QueryString | user-provided value | +| UrlRedirect.cs:49:29:49:31 | access to local variable url | UrlRedirect.cs:24:22:24:44 | access to property QueryString | UrlRedirect.cs:49:29:49:31 | access to local variable url | Untrusted URL redirection due to $@. | UrlRedirect.cs:24:22:24:44 | access to property QueryString | user-provided value | +| UrlRedirectCore.cs:18:22:18:26 | access to parameter value | UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:18:22:18:26 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | +| UrlRedirectCore.cs:21:44:21:48 | call to operator implicit conversion | UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:21:44:21:48 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | +| UrlRedirectCore.cs:27:46:27:50 | call to operator implicit conversion | UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:27:46:27:50 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | +| UrlRedirectCore.cs:33:66:33:70 | access to parameter value | UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:33:66:33:70 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | +| UrlRedirectCore.cs:36:49:36:53 | call to operator implicit conversion | UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:36:49:36:53 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | +| UrlRedirectCore.cs:39:69:39:73 | access to parameter value | UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:39:69:39:73 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | +| UrlRedirectCore.cs:42:39:42:53 | ... + ... | UrlRedirectCore.cs:15:44:15:48 | value | UrlRedirectCore.cs:42:39:42:53 | ... + ... | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value | +| UrlRedirectCore.cs:50:28:50:32 | access to parameter value | UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:50:28:50:32 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value | +| UrlRedirectCore.cs:55:32:55:45 | object creation of type Uri | UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:55:32:55:45 | object creation of type Uri | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value | +| UrlRedirectCore.cs:58:31:58:35 | access to parameter value | UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:58:31:58:35 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value | From 0e5d23e78bb375d6cbffa411f15fa828964f968e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Nov 2018 20:42:07 +0000 Subject: [PATCH 20/94] CPP: Add a test of LimitedScopeFile. --- .../LimitedScopeFile.expected | 2 ++ .../LimitedScopeFile/LimitedScopeFile.qlref | 1 + .../LOC-3/Rule 13/LimitedScopeFile/file1.c | 25 +++++++++++++++++++ .../LOC-3/Rule 13/LimitedScopeFile/file2.c | 10 ++++++++ 4 files changed, 38 insertions(+) create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.qlref create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file2.c diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected new file mode 100644 index 00000000000..5c1e1357cba --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected @@ -0,0 +1,2 @@ +| file1.c:3:5:3:14 | globalInt1 | The global variable globalInt1 is not accessed outside of file1.c and could be made static. | +| file1.c:5:5:5:14 | globalInt3 | The global variable globalInt3 is not accessed outside of file1.c and could be made static. | diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.qlref b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.qlref new file mode 100644 index 00000000000..5e38f12f938 --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.qlref @@ -0,0 +1 @@ +JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c new file mode 100644 index 00000000000..0adba5cfbcb --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c @@ -0,0 +1,25 @@ +// file1.c + +int globalInt1; // BAD [only accessed in this file] +int globalInt2; // GOOD [accessed in file1.c and file2.c] +int globalInt3; // GOOD [referenced in file1.h] [FALSE POSITIVE] +int globalInt4; // GOOD [only accessed in one function, should be function scope instead] +int globalInt5; // GOOD [not accessed] + +static int staticInt1; // GOOD [static] + +void file1Func1() +{ + globalInt1++; + globalInt2++; + globalInt3++; + globalInt4++; + staticInt1++; +} + +void file1Func2() +{ + globalInt1++; + globalInt3++; + staticInt1++; +} diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file2.c b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file2.c new file mode 100644 index 00000000000..6da3ce01615 --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file2.c @@ -0,0 +1,10 @@ +// file2.c + +#include "file1.h" + +extern int globalInt2; + +void file2Func() +{ + globalInt2++; +} From e253ab54d7a69547f98441b939fa00783485ae02 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Nov 2018 22:18:55 +0000 Subject: [PATCH 21/94] CPP: Exclude variables that are part of an interface. --- cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql | 1 + .../LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected | 1 - .../query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql index a895174e215..8367fb996fe 100644 --- a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql +++ b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql @@ -12,5 +12,6 @@ from GlobalVariable v where forex(VariableAccess va | va.getTarget() = v | va.getFile() = v.getDefinitionLocation().getFile()) and not v.hasSpecifier("static") and strictcount(v.getAnAccess().getEnclosingFunction()) > 1 // If = 1, variable should be function-scope. + and not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere select v, "The global variable " + v.getName() + " is not accessed outside of " + v.getFile().getBaseName() + " and could be made static." diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected index 5c1e1357cba..2bdd09e89df 100644 --- a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/LimitedScopeFile.expected @@ -1,2 +1 @@ | file1.c:3:5:3:14 | globalInt1 | The global variable globalInt1 is not accessed outside of file1.c and could be made static. | -| file1.c:5:5:5:14 | globalInt3 | The global variable globalInt3 is not accessed outside of file1.c and could be made static. | diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c index 0adba5cfbcb..96e8dc7ce86 100644 --- a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.c @@ -2,7 +2,7 @@ int globalInt1; // BAD [only accessed in this file] int globalInt2; // GOOD [accessed in file1.c and file2.c] -int globalInt3; // GOOD [referenced in file1.h] [FALSE POSITIVE] +int globalInt3; // GOOD [referenced in file1.h] int globalInt4; // GOOD [only accessed in one function, should be function scope instead] int globalInt5; // GOOD [not accessed] From 1cba1d0b1a777b858170b1ab26b3cfe40bb8b447 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Nov 2018 22:19:47 +0000 Subject: [PATCH 22/94] CPP: Modify similar query as well. --- cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql b/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql index ea3f09d1161..4335bf18cc4 100644 --- a/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql +++ b/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql @@ -12,5 +12,6 @@ from GlobalVariable v where forex(VariableAccess va | va.getTarget() = v | va.getFile() = v.getDefinitionLocation().getFile()) and not v.hasSpecifier("static") and strictcount(v.getAnAccess().getEnclosingFunction()) > 1 // If = 1, variable should be function-scope. + and not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere select v, "The global variable " + v.getName() + " is not accessed outside of " + v.getFile().getBaseName() + " and could be made static." From b70c572e34eb9178fb7de4cc388b56b96c215149 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Nov 2018 20:42:28 +0000 Subject: [PATCH 23/94] CPP: Add a test for LimitedScopeFunction. --- .../LimitedScopeFunction.expected | 5 +++ .../LimitedScopeFunction.qlref | 1 + .../LOC-3/Rule 13/LimitedScopeFunction/test.c | 44 +++++++++++++++++++ .../LOC-3/Rule 13/LimitedScopeFunction/test.h | 3 ++ 4 files changed, 53 insertions(+) create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.qlref create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.h diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected new file mode 100644 index 00000000000..c84f3c488b5 --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected @@ -0,0 +1,5 @@ +| test.c:8:5:8:14 | globalInt4 | The variable globalInt4 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | +| test.c:9:5:9:14 | globalInt5 | The variable globalInt5 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | +| test.c:10:5:10:14 | globalInt6 | The variable globalInt6 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | +| test.c:14:5:14:14 | globalInt9 | The variable globalInt9 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | +| test.c:17:5:17:13 | externInt | The variable externInt is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.qlref b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.qlref new file mode 100644 index 00000000000..c5e632ca9b6 --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.qlref @@ -0,0 +1 @@ +JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c new file mode 100644 index 00000000000..f877ead8f47 --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c @@ -0,0 +1,44 @@ +// test.c + +#include "test.h" + +int globalInt1; // GOOD [used in func1, func2] +int globalInt2; // GOOD [used in func1, func2] +int globalInt3; // GOOD [used in func1, func2] +int globalInt4; // BAD [only used in func1] +int globalInt5; // BAD [only used in func1] +int globalInt6; // BAD [only used in func1] +int globalInt7; // GOOD [not used, should be reported by another query] +int globalInt8; // GOOD [used at file level] +int *addrGlobalInt8 = &globalInt8; // GOOD [used in func1, func2] +int globalInt9; // GOOD [used at file level and in func1] [FALSE POSITIVE] +int *addrGlobalInt9 = &globalInt9; // GOOD [used in func1, func2] + +int externInt; // GOOD [extern'd so could be part of an interface] [FALSE POSITIVE] + +void func1() +{ + int *ptr3 = &globalInt3; + int *ptr6 = &globalInt6; + int i8 = *addrGlobalInt8; + + globalInt1 = globalInt2; + globalInt4 = globalInt5; + externInt = globalInt9; +} + +void func2() +{ + int *ptr1 = &globalInt3; + int i8 = *addrGlobalInt8; + + globalInt1 = globalInt2; +} + +void func3() +{ + static int staticInt; // GOOD [declared in local scope] + int i; + + i = staticInt; +} diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.h b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.h new file mode 100644 index 00000000000..3aa12e4d9a7 --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.h @@ -0,0 +1,3 @@ +// test.h + +extern int externInt; \ No newline at end of file From 2d07410f97caa1cc370b1ef71b94016cf8d70641 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Nov 2018 21:24:18 +0000 Subject: [PATCH 24/94] CPP: Exclude variables that are part of an interface. --- cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql | 3 ++- .../Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected | 1 - .../JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql index 40fa3b48a2d..3a5b6411187 100644 --- a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql +++ b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql @@ -10,5 +10,6 @@ import cpp from GlobalVariable v, Function f where v.getAnAccess().getEnclosingFunction() = f and - strictcount(v.getAnAccess().getEnclosingFunction()) = 1 + strictcount(v.getAnAccess().getEnclosingFunction()) = 1 and + not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere select v, "The variable " + v.getName() + " is only accessed in $@ and should be scoped accordingly.", f, f.getName() diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected index c84f3c488b5..533f2f01d0f 100644 --- a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected @@ -2,4 +2,3 @@ | test.c:9:5:9:14 | globalInt5 | The variable globalInt5 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | | test.c:10:5:10:14 | globalInt6 | The variable globalInt6 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | | test.c:14:5:14:14 | globalInt9 | The variable globalInt9 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | -| test.c:17:5:17:13 | externInt | The variable externInt is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c index f877ead8f47..71f9b6492a6 100644 --- a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c @@ -14,7 +14,7 @@ int *addrGlobalInt8 = &globalInt8; // GOOD [used in func1, func2] int globalInt9; // GOOD [used at file level and in func1] [FALSE POSITIVE] int *addrGlobalInt9 = &globalInt9; // GOOD [used in func1, func2] -int externInt; // GOOD [extern'd so could be part of an interface] [FALSE POSITIVE] +int externInt; // GOOD [extern'd so could be part of an interface] void func1() { From 9f688eb7e252fee3cfc045d6b0b3f1ea82ee5998 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Nov 2018 22:48:30 +0000 Subject: [PATCH 25/94] CPP: Exclude variables that have non-function accesses. --- cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql | 1 + .../Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected | 1 - .../query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql index 3a5b6411187..b54e824be05 100644 --- a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql +++ b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql @@ -11,5 +11,6 @@ import cpp from GlobalVariable v, Function f where v.getAnAccess().getEnclosingFunction() = f and strictcount(v.getAnAccess().getEnclosingFunction()) = 1 and + forall(VariableAccess a | a = v.getAnAccess() | exists(a.getEnclosingFunction())) and not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere select v, "The variable " + v.getName() + " is only accessed in $@ and should be scoped accordingly.", f, f.getName() diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected index 533f2f01d0f..d5bffb07061 100644 --- a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/LimitedScopeFunction.expected @@ -1,4 +1,3 @@ | test.c:8:5:8:14 | globalInt4 | The variable globalInt4 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | | test.c:9:5:9:14 | globalInt5 | The variable globalInt5 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | | test.c:10:5:10:14 | globalInt6 | The variable globalInt6 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | -| test.c:14:5:14:14 | globalInt9 | The variable globalInt9 is only accessed in $@ and should be scoped accordingly. | test.c:19:6:19:10 | func1 | func1 | diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c index 71f9b6492a6..a2089446ca7 100644 --- a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFunction/test.c @@ -11,7 +11,7 @@ int globalInt6; // BAD [only used in func1] int globalInt7; // GOOD [not used, should be reported by another query] int globalInt8; // GOOD [used at file level] int *addrGlobalInt8 = &globalInt8; // GOOD [used in func1, func2] -int globalInt9; // GOOD [used at file level and in func1] [FALSE POSITIVE] +int globalInt9; // GOOD [used at file level and in func1] int *addrGlobalInt9 = &globalInt9; // GOOD [used in func1, func2] int externInt; // GOOD [extern'd so could be part of an interface] From a51b9847b2aef3c18e20d3c0544f45c9c75d2dd7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Nov 2018 21:31:51 +0000 Subject: [PATCH 26/94] CPP: Modify similar query as well. --- cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql b/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql index b6358d41c82..87c0e20e92c 100644 --- a/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql +++ b/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql @@ -10,5 +10,7 @@ import cpp from GlobalVariable v, Function f where v.getAnAccess().getEnclosingFunction() = f and - strictcount(v.getAnAccess().getEnclosingFunction()) = 1 + strictcount(v.getAnAccess().getEnclosingFunction()) = 1 and + forall(VariableAccess a | a = v.getAnAccess() | exists(a.getEnclosingFunction())) and + not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere select v, "The variable " + v.getName() + " is only accessed in $@ and should be scoped accordingly.", f, f.getName() From db175f55840250b0f80a04d1101190b355825511 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Mon, 19 Nov 2018 09:00:38 +0000 Subject: [PATCH 27/94] JavaScript: Sort change notes alphabetically. --- change-notes/1.19/analysis-javascript.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index 63679cb0174..a971235eadc 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -4,8 +4,6 @@ * Modelling of taint flow through array operations has been improved. This may give additional results for the security queries. -* The taint tracking library now recognizes additional sanitization patterns. This may give fewer false-positive results for the security queries. - * Support for AMD modules has been improved. This may give additional results for the security queries as well as any queries that use type inference on code bases that use such modules. * Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following features: @@ -13,6 +11,8 @@ - outbound network access, for example through the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) - the [lodash](https://lodash.com), [underscore](https://underscorejs.org/), [async](https://www.npmjs.com/package/async) and [async-es](https://www.npmjs.com/package/async-es) libraries +* The taint tracking library now recognizes additional sanitization patterns. This may give fewer false-positive results for the security queries. + * Type inference for function calls has been improved. This may give additional results for queries that rely on type inference. * Where applicable, path explanations have been added to the security queries. @@ -36,11 +36,13 @@ | **Query** | **Expected impact** | **Change** | |--------------------------------|----------------------------|----------------------------------------------| | Client side cross-site scripting | More results | This rule now also flags HTML injection in the body of an email. | +| Client-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. | | Information exposure through a stack trace | More results | This rule now also flags cases where the entire exception object (including the stack trace) may be exposed. | | Missing CSRF middleware | Fewer false-positive results | This rule now recognizes additional CSRF protection middlewares. | | Regular expression injection | Fewer false-positive results | This rule now identifies calls to `String.prototype.search` with more precision. | | Remote property injection | Fewer results | The precision of this rule has been revised to "medium". Results are no longer shown on LGTM by default. | | Self assignment | Fewer false-positive results | This rule now ignores self-assignments preceded by a JSDoc comment with a `@type` tag. | +| Server-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. | | Server-side URL redirect | More results | This rule now recognizes redirection calls in more cases. | | Unbound event handler receiver | Fewer false-positive results | This rule now recognizes additional ways class methods can be bound. | | Uncontrolled data used in remote request | More results | This rule now recognizes additional kinds of requests. | @@ -49,15 +51,13 @@ | Unused variable, import, function or class | Fewer results | This rule now flags import statements with multiple unused imports once. | | Useless assignment to local variable | Fewer false-positive results | This rule now recognizes additional ways default values can be set. | | Whitespace contradicts operator precedence | Fewer false-positive results | This rule no longer flags operators with asymmetric whitespace. | -| Client-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. | -| Server-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. | ## Changes to QL libraries -* The flow configuration framework now supports distinguishing and tracking different kinds of taint, specified by an extensible class `FlowLabel` (which can also be referred to by its alias `TaintKind`). - -* The `DataFlow::ThisNode` class now corresponds to the implicit receiver parameter of a function, as opposed to an indivdual `this` expression. This means `getALocalSource` now maps all `this` expressions within a given function to the same source. The data-flow node associated with a `ThisExpr` can no longer be cast to `DataFlow::SourceNode` or `DataFlow::ThisNode` - it is recomended to use `getALocalSource` before casting or instead of casting. +* A `DataFlow::ParameterNode` instance now exists for all function parameters. Previously, unused parameters did not have a corresponding dataflow node. * `ReactComponent::getAThisAccess` has been renamed to `getAThisNode`. The old name is still usable but is deprecated. It no longer gets individual `this` expressions, but the `ThisNode` mentioned above. -* A `DataFlow::ParameterNode` instance now exists for all function parameters. Previously, unused parameters did not have a corresponding dataflow node. +* The `DataFlow::ThisNode` class now corresponds to the implicit receiver parameter of a function, as opposed to an indivdual `this` expression. This means `getALocalSource` now maps all `this` expressions within a given function to the same source. The data-flow node associated with a `ThisExpr` can no longer be cast to `DataFlow::SourceNode` or `DataFlow::ThisNode` - it is recomended to use `getALocalSource` before casting or instead of casting. + +* The flow configuration framework now supports distinguishing and tracking different kinds of taint, specified by an extensible class `FlowLabel` (which can also be referred to by its alias `TaintKind`). From 1b59a28be0c087c502111a70f82b7448e58e5181 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Mon, 19 Nov 2018 09:07:04 +0000 Subject: [PATCH 28/94] JavaScript: Downgrade a few "error" rules to "warning". For all of these queries, the results we tend to see in practice are certainly worth investigating, but aren't crashing bugs, so making them warnings seems more appropriate. --- change-notes/1.19/analysis-javascript.md | 5 +++++ javascript/ql/src/DOM/AmbiguousIdAttribute.ql | 2 +- javascript/ql/src/DOM/ConflictingAttributes.ql | 2 +- javascript/ql/src/Declarations/MissingVarDecl.ql | 2 +- javascript/ql/src/Expressions/DuplicateCondition.ql | 2 +- javascript/ql/src/Expressions/DuplicateSwitchCase.ql | 2 +- 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index a971235eadc..d190d16dc14 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -35,10 +35,15 @@ | **Query** | **Expected impact** | **Change** | |--------------------------------|----------------------------|----------------------------------------------| +| Ambiguous HTML id attribute | Lower severity | The severity of this rule has been revised to "warning". | | Client side cross-site scripting | More results | This rule now also flags HTML injection in the body of an email. | | Client-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. | +| Conflicting HTML element attributes | Lower severity | The severity of this rule has been revised to "warning". | +| Duplicate 'if' condition | Lower severity | The severity of this rule has been revised to "warning". | +| Duplicate switch case | Lower severity | The severity of this rule has been revised to "warning". | | Information exposure through a stack trace | More results | This rule now also flags cases where the entire exception object (including the stack trace) may be exposed. | | Missing CSRF middleware | Fewer false-positive results | This rule now recognizes additional CSRF protection middlewares. | +| Missing variable declaration | Lower severity | The severity of this rule has been revised to "warning". | | Regular expression injection | Fewer false-positive results | This rule now identifies calls to `String.prototype.search` with more precision. | | Remote property injection | Fewer results | The precision of this rule has been revised to "medium". Results are no longer shown on LGTM by default. | | Self assignment | Fewer false-positive results | This rule now ignores self-assignments preceded by a JSDoc comment with a `@type` tag. | diff --git a/javascript/ql/src/DOM/AmbiguousIdAttribute.ql b/javascript/ql/src/DOM/AmbiguousIdAttribute.ql index 8e9e7a6a2f7..f0304515731 100644 --- a/javascript/ql/src/DOM/AmbiguousIdAttribute.ql +++ b/javascript/ql/src/DOM/AmbiguousIdAttribute.ql @@ -4,7 +4,7 @@ * same id attribute, it may be interpreted differently * by different browsers. * @kind problem - * @problem.severity error + * @problem.severity warning * @id js/duplicate-html-id * @tags maintainability * correctness diff --git a/javascript/ql/src/DOM/ConflictingAttributes.ql b/javascript/ql/src/DOM/ConflictingAttributes.ql index e0f2094899f..9e4cf1cdccd 100644 --- a/javascript/ql/src/DOM/ConflictingAttributes.ql +++ b/javascript/ql/src/DOM/ConflictingAttributes.ql @@ -3,7 +3,7 @@ * @description If an HTML element has two attributes with the same name * but different values, its behavior may be browser-dependent. * @kind problem - * @problem.severity error + * @problem.severity warning * @id js/conflicting-html-attribute * @tags maintainability * correctness diff --git a/javascript/ql/src/Declarations/MissingVarDecl.ql b/javascript/ql/src/Declarations/MissingVarDecl.ql index 8bc0cf92d0a..4a180408cb5 100644 --- a/javascript/ql/src/Declarations/MissingVarDecl.ql +++ b/javascript/ql/src/Declarations/MissingVarDecl.ql @@ -3,7 +3,7 @@ * @description If a variable is not declared as a local variable, it becomes a global variable * by default, which may be unintentional and could lead to unexpected behavior. * @kind problem - * @problem.severity error + * @problem.severity warning * @id js/missing-variable-declaration * @tags reliability * maintainability diff --git a/javascript/ql/src/Expressions/DuplicateCondition.ql b/javascript/ql/src/Expressions/DuplicateCondition.ql index 8eb5d606aba..02872ae16dc 100644 --- a/javascript/ql/src/Expressions/DuplicateCondition.ql +++ b/javascript/ql/src/Expressions/DuplicateCondition.ql @@ -3,7 +3,7 @@ * @description If two conditions in an 'if'-'else if' chain are identical, the * second condition will never hold. * @kind problem - * @problem.severity error + * @problem.severity warning * @id js/duplicate-condition * @tags maintainability * correctness diff --git a/javascript/ql/src/Expressions/DuplicateSwitchCase.ql b/javascript/ql/src/Expressions/DuplicateSwitchCase.ql index 1361c60b6e6..57a04fcaf3e 100644 --- a/javascript/ql/src/Expressions/DuplicateSwitchCase.ql +++ b/javascript/ql/src/Expressions/DuplicateSwitchCase.ql @@ -3,7 +3,7 @@ * @description If two cases in a switch statement have the same label, the second case * will never be executed. * @kind problem - * @problem.severity error + * @problem.severity warning * @id js/duplicate-switch-case * @tags maintainability * correctness From 73ad3f5c8aa2e91ac61be9a3d763d10208902bdc Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Thu, 15 Nov 2018 16:44:05 +0000 Subject: [PATCH 29/94] JavaScript: Tweak `JSLint` library to avoid bad join order. --- .../ql/src/semmle/javascript/linters/JSLint.qll | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/javascript/ql/src/semmle/javascript/linters/JSLint.qll b/javascript/ql/src/semmle/javascript/linters/JSLint.qll index 1cf6730ab18..136122f01bd 100644 --- a/javascript/ql/src/semmle/javascript/linters/JSLint.qll +++ b/javascript/ql/src/semmle/javascript/linters/JSLint.qll @@ -9,6 +9,11 @@ private string getDirectiveName(SlashStarComment c) { result = c.getText().regexpCapture("(?s)\\s*(\\w+)\\b.*", 1) } +/** Gets a function at the specified location. */ +private Function getFunctionAt(string filepath, int startline, int startcolumn, int endline, int endcolumn) { + result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) +} + /** A JSLint directive. */ abstract class JSLintDirective extends SlashStarComment { /** @@ -36,7 +41,7 @@ abstract class JSLintDirective extends SlashStarComment { private Function getASurroundingFunction() { exists (string path, int fsl, int fsc, int fel, int fec, int dsl, int dsc, int del, int dec | - result.getLocation().hasLocationInfo(path, fsl, fsc, fel, fec) and + result = getFunctionAt(path, fsl, fsc, fel, fec) and this.getLocation().hasLocationInfo(path, dsl, dsc, del, dec) | // the function starts before this directive (fsl < dsl or (fsl = dsl and fsc <= dsc)) @@ -96,6 +101,11 @@ abstract class JSLintGlobal extends Linting::GlobalDeclaration, JSLintDirective override predicate appliesTo(ExprOrStmt s) { JSLintDirective.super.appliesTo(s) } + + override predicate declaresGlobalForAccess(GlobalVarAccess gva) { + declaresGlobal(gva.getName(), _) and + getScope() = gva.getContainer().getEnclosingContainer*() + } } /** A JSLint `global` directive. */ From 01611d4d9625ed72305e3024a6657cb4f11dd736 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 11:15:51 +0000 Subject: [PATCH 30/94] CPP: Add a test for OffsetUseBeforeRangeCheck.ql. --- .../OffsetUseBeforeRangeCheck.expected | 5 ++ .../OffsetUseBeforeRangeCheck.qlref | 1 + .../OffsetUseBeforeRangeCheck/test.cpp | 50 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected create mode 100644 cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.qlref create mode 100644 cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected new file mode 100644 index 00000000000..4ff46689c07 --- /dev/null +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected @@ -0,0 +1,5 @@ +| test.cpp:11:10:11:18 | access to array | This use of offset 'i' should follow the $@. | test.cpp:11:32:11:45 | ... < ... | range check | +| test.cpp:15:7:15:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:15:29:15:42 | ... < ... | range check | +| test.cpp:33:28:33:36 | access to array | This use of offset 'i' should follow the $@. | test.cpp:33:50:33:67 | ... < ... | range check | +| test.cpp:35:32:35:40 | access to array | This use of offset 'i' should follow the $@. | test.cpp:35:54:35:67 | ... < ... | range check | +| test.cpp:39:8:39:16 | access to array | This use of offset 'i' should follow the $@. | test.cpp:39:30:39:47 | ... < ... | range check | diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.qlref b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.qlref new file mode 100644 index 00000000000..d934901f174 --- /dev/null +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.qlref @@ -0,0 +1 @@ +Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp new file mode 100644 index 00000000000..6503eb9472e --- /dev/null +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp @@ -0,0 +1,50 @@ + +void test(char *buffer, int bufferSize) +{ + int i; + + // skip whitespace + i = 0; + while ((i < bufferSize) && (buffer[i] == ' ')) { i++; } // GOOD + + i = 0; + while ((buffer[i] == ' ') && (i < bufferSize)) { i++; } // BAD + + // check for 'x' + if ((i < bufferSize) && (buffer[i] == 'x')) {} // GOOD + if ((buffer[i] == 'x') && (i < bufferSize)) {} // BAD + + if ((bufferSize > i) && (buffer[i] == 'x')) {} // GOOD + if ((buffer[i] == 'x') && (bufferSize > i)) {} // BAD [NOT DETECTED] + + if ((i <= bufferSize - 1) && (buffer[i] == 'x')) {} // GOOD + if ((buffer[i] == 'x') && (i <= bufferSize - 1)) {} // BAD [NOT DETECTED] + + if ((bufferSize >= i + 1) && (buffer[i] == 'x')) {} // GOOD + if ((buffer[i] == 'x') && (bufferSize >= i + 1)) {} // BAD [NOT DETECTED] + + if ((i < bufferSize) && (true) && (buffer[i] == 'x')) {} // GOOD + if ((buffer[i] == 'x') && (true) && (i < bufferSize)) {} // BAD [NOT DETECTED] + + if ((i < bufferSize - 1) && (buffer[i + 1] == 'x')) {} // GOOD + if ((buffer[i + 1] == 'x') && (i < bufferSize - 1)) {} // BAD [NOT DETECTED] + + if ((i < bufferSize) && (buffer[i] == 'x') && (i < bufferSize - 1)) {} // GOOD + if ((i < bufferSize) && ((buffer[i] == 'x') && (i < bufferSize - 1))) {} // GOOD [FALSE POSITIVE] + if ((i < bufferSize + 1) && (buffer[i] == 'x') && (i < bufferSize)) {} // BAD [NOT DETECTED] + if ((i < bufferSize + 1) && ((buffer[i] == 'x') && (i < bufferSize))) {} // BAD + + // look for 'ab' + for (i = 0; i < bufferSize; i++) { + if ((buffer[i] == 'a') && (i < bufferSize - 1) && (buffer[i + 1] == 'b')) // GOOD [FALSE POSITIVE] + break; + } + + if ((i < bufferSize) && (buffer[i])) {} // GOOD + if ((buffer[i]) && (i < bufferSize)) {} // BAD [NOT DETECTED] + + if ((i < bufferSize) && (buffer[i] + 1 == 'x')) {} // GOOD + if ((buffer[i] + 1 == 'x') && (i < bufferSize)) {} // BAD [NOT DETECTED] + + if ((buffer != 0) && (i < bufferSize)) {} // GOOD +} From 6cdfaeea3c3e7228cd3950501fa93e101f277013 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 11:46:34 +0000 Subject: [PATCH 31/94] CPP: getAChild() -> getAChild*(). --- .../Likely Errors/OffsetUseBeforeRangeCheck.ql | 2 +- .../OffsetUseBeforeRangeCheck.expected | 5 +++++ .../Likely Errors/OffsetUseBeforeRangeCheck/test.cpp | 10 +++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql index 872f01d4421..65d7b953918 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql +++ b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql @@ -15,7 +15,7 @@ import cpp from Variable v, LogicalAndExpr andexpr, ArrayExpr access, LTExpr rangecheck where access.getArrayOffset() = v.getAnAccess() - and andexpr.getLeftOperand().getAChild() = access + and andexpr.getLeftOperand().getAChild*() = access and andexpr.getRightOperand() = rangecheck and rangecheck.getLeftOperand() = v.getAnAccess() and not access.isInMacroExpansion() diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected index 4ff46689c07..9af033bc749 100644 --- a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected @@ -1,5 +1,10 @@ | test.cpp:11:10:11:18 | access to array | This use of offset 'i' should follow the $@. | test.cpp:11:32:11:45 | ... < ... | range check | | test.cpp:15:7:15:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:15:29:15:42 | ... < ... | range check | +| test.cpp:27:7:27:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:27:39:27:52 | ... < ... | range check | +| test.cpp:32:27:32:35 | access to array | This use of offset 'i' should follow the $@. | test.cpp:32:49:32:66 | ... < ... | range check | | test.cpp:33:28:33:36 | access to array | This use of offset 'i' should follow the $@. | test.cpp:33:50:33:67 | ... < ... | range check | +| test.cpp:34:31:34:39 | access to array | This use of offset 'i' should follow the $@. | test.cpp:34:53:34:66 | ... < ... | range check | | test.cpp:35:32:35:40 | access to array | This use of offset 'i' should follow the $@. | test.cpp:35:54:35:67 | ... < ... | range check | | test.cpp:39:8:39:16 | access to array | This use of offset 'i' should follow the $@. | test.cpp:39:30:39:47 | ... < ... | range check | +| test.cpp:44:7:44:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:44:22:44:35 | ... < ... | range check | +| test.cpp:47:7:47:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:47:33:47:46 | ... < ... | range check | diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp index 6503eb9472e..884e592b8a9 100644 --- a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp @@ -24,14 +24,14 @@ void test(char *buffer, int bufferSize) if ((buffer[i] == 'x') && (bufferSize >= i + 1)) {} // BAD [NOT DETECTED] if ((i < bufferSize) && (true) && (buffer[i] == 'x')) {} // GOOD - if ((buffer[i] == 'x') && (true) && (i < bufferSize)) {} // BAD [NOT DETECTED] + if ((buffer[i] == 'x') && (true) && (i < bufferSize)) {} // BAD if ((i < bufferSize - 1) && (buffer[i + 1] == 'x')) {} // GOOD if ((buffer[i + 1] == 'x') && (i < bufferSize - 1)) {} // BAD [NOT DETECTED] - if ((i < bufferSize) && (buffer[i] == 'x') && (i < bufferSize - 1)) {} // GOOD + if ((i < bufferSize) && (buffer[i] == 'x') && (i < bufferSize - 1)) {} // GOOD [FALSE POSITIVE] if ((i < bufferSize) && ((buffer[i] == 'x') && (i < bufferSize - 1))) {} // GOOD [FALSE POSITIVE] - if ((i < bufferSize + 1) && (buffer[i] == 'x') && (i < bufferSize)) {} // BAD [NOT DETECTED] + if ((i < bufferSize + 1) && (buffer[i] == 'x') && (i < bufferSize)) {} // BAD if ((i < bufferSize + 1) && ((buffer[i] == 'x') && (i < bufferSize))) {} // BAD // look for 'ab' @@ -41,10 +41,10 @@ void test(char *buffer, int bufferSize) } if ((i < bufferSize) && (buffer[i])) {} // GOOD - if ((buffer[i]) && (i < bufferSize)) {} // BAD [NOT DETECTED] + if ((buffer[i]) && (i < bufferSize)) {} // BAD if ((i < bufferSize) && (buffer[i] + 1 == 'x')) {} // GOOD - if ((buffer[i] + 1 == 'x') && (i < bufferSize)) {} // BAD [NOT DETECTED] + if ((buffer[i] + 1 == 'x') && (i < bufferSize)) {} // BAD if ((buffer != 0) && (i < bufferSize)) {} // GOOD } From e72505707be1e647fda52b31e3160996be5db38e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 11:49:22 +0000 Subject: [PATCH 32/94] CPP: Check for a range check before the use. --- .../OffsetUseBeforeRangeCheck.ql | 31 +++++++++++++++---- .../OffsetUseBeforeRangeCheck.expected | 4 --- .../OffsetUseBeforeRangeCheck/test.cpp | 8 ++--- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql index 65d7b953918..6e468314478 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql +++ b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql @@ -13,10 +13,29 @@ import cpp -from Variable v, LogicalAndExpr andexpr, ArrayExpr access, LTExpr rangecheck -where access.getArrayOffset() = v.getAnAccess() - and andexpr.getLeftOperand().getAChild*() = access - and andexpr.getRightOperand() = rangecheck - and rangecheck.getLeftOperand() = v.getAnAccess() - and not access.isInMacroExpansion() +predicate beforeArrayAccess(Variable v, ArrayExpr access, Expr before) { + exists(LogicalAndExpr andexpr | + access.getArrayOffset() = v.getAnAccess() and + andexpr.getRightOperand().getAChild*() = access and + andexpr.getLeftOperand() = before + ) +} + +predicate afterArrayAccess(Variable v, ArrayExpr access, Expr after) { + exists(LogicalAndExpr andexpr | + access.getArrayOffset() = v.getAnAccess() and + andexpr.getLeftOperand().getAChild*() = access and + andexpr.getRightOperand() = after + ) +} + +from Variable v, ArrayExpr access, LTExpr rangecheck +where + afterArrayAccess(v, access, rangecheck) and + rangecheck.getLeftOperand() = v.getAnAccess() and + not access.isInMacroExpansion() and + not exists(LTExpr altcheck | + beforeArrayAccess(v, access, altcheck) and + altcheck.getLeftOperand() = v.getAnAccess() + ) select access, "This use of offset '" + v.getName() + "' should follow the $@.", rangecheck, "range check" diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected index 9af033bc749..7b74afa93ff 100644 --- a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/OffsetUseBeforeRangeCheck.expected @@ -1,10 +1,6 @@ | test.cpp:11:10:11:18 | access to array | This use of offset 'i' should follow the $@. | test.cpp:11:32:11:45 | ... < ... | range check | | test.cpp:15:7:15:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:15:29:15:42 | ... < ... | range check | | test.cpp:27:7:27:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:27:39:27:52 | ... < ... | range check | -| test.cpp:32:27:32:35 | access to array | This use of offset 'i' should follow the $@. | test.cpp:32:49:32:66 | ... < ... | range check | -| test.cpp:33:28:33:36 | access to array | This use of offset 'i' should follow the $@. | test.cpp:33:50:33:67 | ... < ... | range check | -| test.cpp:34:31:34:39 | access to array | This use of offset 'i' should follow the $@. | test.cpp:34:53:34:66 | ... < ... | range check | -| test.cpp:35:32:35:40 | access to array | This use of offset 'i' should follow the $@. | test.cpp:35:54:35:67 | ... < ... | range check | | test.cpp:39:8:39:16 | access to array | This use of offset 'i' should follow the $@. | test.cpp:39:30:39:47 | ... < ... | range check | | test.cpp:44:7:44:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:44:22:44:35 | ... < ... | range check | | test.cpp:47:7:47:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:47:33:47:46 | ... < ... | range check | diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp index 884e592b8a9..0c7baf7b7ff 100644 --- a/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp @@ -29,10 +29,10 @@ void test(char *buffer, int bufferSize) if ((i < bufferSize - 1) && (buffer[i + 1] == 'x')) {} // GOOD if ((buffer[i + 1] == 'x') && (i < bufferSize - 1)) {} // BAD [NOT DETECTED] - if ((i < bufferSize) && (buffer[i] == 'x') && (i < bufferSize - 1)) {} // GOOD [FALSE POSITIVE] - if ((i < bufferSize) && ((buffer[i] == 'x') && (i < bufferSize - 1))) {} // GOOD [FALSE POSITIVE] - if ((i < bufferSize + 1) && (buffer[i] == 'x') && (i < bufferSize)) {} // BAD - if ((i < bufferSize + 1) && ((buffer[i] == 'x') && (i < bufferSize))) {} // BAD + if ((i < bufferSize) && (buffer[i] == 'x') && (i < bufferSize - 1)) {} // GOOD + if ((i < bufferSize) && ((buffer[i] == 'x') && (i < bufferSize - 1))) {} // GOOD + if ((i < bufferSize + 1) && (buffer[i] == 'x') && (i < bufferSize)) {} // BAD [NOT DETECTED] + if ((i < bufferSize + 1) && ((buffer[i] == 'x') && (i < bufferSize))) {} // BAD [NOT DETECTED] // look for 'ab' for (i = 0; i < bufferSize; i++) { From cf279783255482f7d5958e986944e90b50b44622 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 10:26:34 +0000 Subject: [PATCH 33/94] CPP: Give OffsetUseBeforeRangeCheck.ql a precision. --- .../Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql index 6e468314478..7a7e589fb34 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql +++ b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/offset-use-before-range-check * @problem.severity warning + * @precision medium * @tags reliability * security * external/cwe/cwe-120 From 6021d2499d7f8ea84912cc90690b58cb6987c858 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Mon, 19 Nov 2018 12:24:19 +0000 Subject: [PATCH 34/94] JavaScript: Remove accidentally committed `.actual` file. --- javascript/ql/src/Security/CWE-089/SqlInjection.actual | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 javascript/ql/src/Security/CWE-089/SqlInjection.actual diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.actual b/javascript/ql/src/Security/CWE-089/SqlInjection.actual deleted file mode 100644 index e69de29bb2d..00000000000 From 646bb01a5f317c76fc6d361fc2fecce33dabf623 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 14:04:14 +0000 Subject: [PATCH 35/94] CPP: Change note. --- change-notes/1.19/analysis-cpp.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index f22f5dc638f..98fb53a635f 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -15,6 +15,7 @@ | **Query** | **Expected impact** | **Change** | |----------------------------|------------------------|------------------------------------------------------------------| +| Array offset used before range check | More results and fewer false positive results | The query now recognizes array accesses in different positions within the expression. False positives where the range is checked before and after the array access have been fixed. | | Empty branch of conditional | Fewer false positive results | The query now recognizes commented blocks more reliably. | | Expression has no effect | Fewer false positive results | Expressions in template instantiations are now excluded from this query. | | Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. Also fixed an issue where false positives could occur if the destructor body was not in the snapshot. | From 6a14748af8fb15db34eced3b2bad56dfd1ecabca Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 14:25:11 +0000 Subject: [PATCH 36/94] CPP: Add recommended test. --- .../Arithmetic/BadAdditionOverflowCheck/test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp index 13fa493da27..cb206d6ec51 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp @@ -144,3 +144,9 @@ void useMarkRange(int offs) { markRange(buffer, offs, offs + 10); markRange(buffer, offs, offs); // GOOD (comparison is in the macro) } + +#define MY_MACRO(x) (x) + +void myMacroTest(int x) { + MY_MACRO(x == x); // BAD [NOT DETECTED] +} From 33130b98005a5c4f91436e17017a174270b2a7e0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 14:39:28 +0000 Subject: [PATCH 37/94] CPP: Apply recommended fix. --- .../Likely Bugs/Arithmetic/PointlessSelfComparison.ql | 9 ++++++++- .../PointlessSelfComparison.expected | 1 + .../Arithmetic/BadAdditionOverflowCheck/test.cpp | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql index cf7ba886366..9671508449a 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql +++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql @@ -18,5 +18,12 @@ from ComparisonOperation cmp where pointlessSelfComparison(cmp) and not nanTest(cmp) and not overflowTest(cmp) - and not cmp.isInMacroExpansion() + and not exists(MacroInvocation mi | + // cmp is in mi + mi.getAnExpandedElement() = cmp and + + // and cmp was apparently not passed in as a macro parameter + cmp.getLocation().getStartLine() = mi.getLocation().getStartLine() and + cmp.getLocation().getStartColumn() = mi.getLocation().getStartColumn() + ) select cmp, "Self comparison." diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected index 016706c2338..2318c286c60 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected @@ -3,3 +3,4 @@ | test.cpp:83:10:83:15 | ... == ... | Self comparison. | | test.cpp:90:10:90:15 | ... == ... | Self comparison. | | test.cpp:118:7:118:32 | ... != ... | Self comparison. | +| test.cpp:151:11:151:16 | ... == ... | Self comparison. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp index cb206d6ec51..4669b709bc4 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp @@ -148,5 +148,5 @@ void useMarkRange(int offs) { #define MY_MACRO(x) (x) void myMacroTest(int x) { - MY_MACRO(x == x); // BAD [NOT DETECTED] + MY_MACRO(x == x); // BAD } From d18a7012f5a7cd7e9fb0747f63a0feb970848cf2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 16:08:32 +0000 Subject: [PATCH 38/94] CPP: Add a test case. --- .../4.13 Functions/AV Rule 114/AV Rule 114.expected | 2 ++ .../query-tests/jsf/4.13 Functions/AV Rule 114/test.c | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected index f0435acd0a5..88f0cc1cc3c 100644 --- a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected +++ b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected @@ -1,6 +1,8 @@ | test.c:8:5:8:14 | declaration | Function f2 should return a value of type int but does not return a value here | | test.c:25:9:25:14 | ExprStmt | Function f4 should return a value of type int but does not return a value here | | test.c:39:9:39:14 | ExprStmt | Function f6 should return a value of type int but does not return a value here | +| test.c:95:2:95:20 | if (...) ... | Function f13_func should return a value of type int but does not return a value here | +| test.c:95:2:95:20 | if (...) ... | Function f13_func should return a value of type void but does not return a value here | | test.cpp:16:1:18:1 | { ... } | Function g2 should return a value of type MyValue but does not return a value here | | test.cpp:48:2:48:26 | if (...) ... | Function g7 should return a value of type MyValue but does not return a value here | | test.cpp:74:1:76:1 | { ... } | Function g10 should return a value of type second but does not return a value here | diff --git a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c index 79f9e0ffaa3..f9599bff7cf 100644 --- a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c +++ b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c @@ -84,3 +84,13 @@ int f12(int x) // ... } } + +void f13() +{ + f13_func(); // implicitly declared here +} + +void f13_func(int x) +{ + if (x < 10) return; // GOOD [FALSE POSITIVE] +} From 5cae65295df2dc26103abbaaa1e2a77a7c1aebdc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 19 Nov 2018 16:04:45 +0000 Subject: [PATCH 39/94] CPP: Fix FPs from AV Rule 114.ql. --- cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql | 2 ++ .../jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected | 2 -- cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql index 600d4a6abf0..06e760481c9 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql @@ -38,6 +38,8 @@ predicate functionImperfectlyExtracted(Function f) { exists(CompilerError e | f.getBlock().getLocation().subsumes(e.getLocation())) or exists(ErrorExpr ee | ee.getEnclosingFunction() = f) + or + count(f.getType()) > 1 } from Stmt stmt, string msg, Function f, ControlFlowNode blame diff --git a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected index 88f0cc1cc3c..f0435acd0a5 100644 --- a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected +++ b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/AV Rule 114.expected @@ -1,8 +1,6 @@ | test.c:8:5:8:14 | declaration | Function f2 should return a value of type int but does not return a value here | | test.c:25:9:25:14 | ExprStmt | Function f4 should return a value of type int but does not return a value here | | test.c:39:9:39:14 | ExprStmt | Function f6 should return a value of type int but does not return a value here | -| test.c:95:2:95:20 | if (...) ... | Function f13_func should return a value of type int but does not return a value here | -| test.c:95:2:95:20 | if (...) ... | Function f13_func should return a value of type void but does not return a value here | | test.cpp:16:1:18:1 | { ... } | Function g2 should return a value of type MyValue but does not return a value here | | test.cpp:48:2:48:26 | if (...) ... | Function g7 should return a value of type MyValue but does not return a value here | | test.cpp:74:1:76:1 | { ... } | Function g10 should return a value of type second but does not return a value here | diff --git a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c index f9599bff7cf..63ce8288fe4 100644 --- a/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c +++ b/cpp/ql/test/query-tests/jsf/4.13 Functions/AV Rule 114/test.c @@ -92,5 +92,5 @@ void f13() void f13_func(int x) { - if (x < 10) return; // GOOD [FALSE POSITIVE] + if (x < 10) return; // GOOD } From fc6e9be75ac07c775b3138272db8edc2773a9e51 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Tue, 20 Nov 2018 07:12:48 +0000 Subject: [PATCH 40/94] Fix incorrect tag --- .../Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp index 2ad98182009..2b31cb13e54 100644 --- a/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp +++ b/csharp/ql/src/Bad Practices/Naming Conventions/ControlNamePrefixes.qhelp @@ -8,7 +8,7 @@ This makes the controls easier to find in Intellisense and also makes the purpos -

Give controls an appropriate prefix to indicate their type (for example, txt for text boxes or rad for +

Give controls an appropriate prefix to indicate their type (for example, txt for text boxes or rad for radio buttons).

From ee7a6af7c74fb0d8a382a91975ca4fdefae430ca Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Tue, 20 Nov 2018 08:37:23 +0100 Subject: [PATCH 41/94] JS: address review comments --- ...qll => CustomAbstractValueDefinitions.qll} | 25 +++++++++++-------- .../internal/AbstractPropertiesImpl.qll | 2 +- .../dataflow/internal/AbstractValuesImpl.qll | 4 +-- .../dataflow/internal/FlowSteps.qll | 3 +-- .../CustomAbstractValueDefinitions.expected} | 2 +- .../CustomAbstractValueDefinitions.ql} | 2 +- ...stomAbstractValueDefinitionsFlow.expected} | 0 .../CustomAbstractValueDefinitionsFlow.ql} | 4 +-- .../tst.js | 0 9 files changed, 23 insertions(+), 19 deletions(-) rename javascript/ql/src/semmle/javascript/dataflow/{DefinedCustomAbstractValues.qll => CustomAbstractValueDefinitions.qll} (78%) rename javascript/ql/test/library-tests/{DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected => CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.expected} (82%) rename javascript/ql/test/library-tests/{DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql => CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.ql} (95%) rename javascript/ql/test/library-tests/{DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.expected => CustomAbstractValueDefinitions/CustomAbstractValueDefinitionsFlow.expected} (100%) rename javascript/ql/test/library-tests/{DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql => CustomAbstractValueDefinitions/CustomAbstractValueDefinitionsFlow.ql} (82%) rename javascript/ql/test/library-tests/{DefinedCustomAbstractValue => CustomAbstractValueDefinitions}/tst.js (100%) diff --git a/javascript/ql/src/semmle/javascript/dataflow/DefinedCustomAbstractValues.qll b/javascript/ql/src/semmle/javascript/dataflow/CustomAbstractValueDefinitions.qll similarity index 78% rename from javascript/ql/src/semmle/javascript/dataflow/DefinedCustomAbstractValues.qll rename to javascript/ql/src/semmle/javascript/dataflow/CustomAbstractValueDefinitions.qll index 5f94b9ccea4..0a069dbd87c 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/DefinedCustomAbstractValues.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/CustomAbstractValueDefinitions.qll @@ -1,7 +1,7 @@ /** * Provides classes for working with analysis-specific abstract values. * - * Implement a subclass of `CustomAbstractValueDefinition` When the builtin + * Implement a subclass of `CustomAbstractValueDefinition` when the builtin * abstract values of `AbstractValues.qll` are not expressive enough. * * For performance reasons, all subclasses of `CustomAbstractValueDefinition` @@ -17,12 +17,12 @@ private import InferredTypes * * Wraps a `CustomAbstractValueDefinition`. */ -class DefinedCustomAbstractValue extends AbstractValue, TDefinedCustomAbstractValue { +class CustomAbstractValueFromDefinition extends AbstractValue, TCustomAbstractValueFromDefinition { CustomAbstractValueDefinition def; - DefinedCustomAbstractValue() { - this = TDefinedCustomAbstractValue(def) + CustomAbstractValueFromDefinition() { + this = TCustomAbstractValueFromDefinition(def) } override InferredType getType() { @@ -57,10 +57,14 @@ class DefinedCustomAbstractValue extends AbstractValue, TDefinedCustomAbstractVa result = def.toString() } + /** + * Gets the definition that induces this value. + */ CustomAbstractValueDefinition getDefinition() { result = def } + /** Holds if this is a value whose properties the type inference tracks. */ predicate shouldTrackProperties() { def.shouldTrackProperties() } @@ -68,7 +72,7 @@ class DefinedCustomAbstractValue extends AbstractValue, TDefinedCustomAbstractVa } /** - * A node that induces an analysis-specific abstract value. + * A data-flow node that induces an analysis-specific abstract value. * * Enables modular extensions of `AbstractValue`. * @@ -128,9 +132,10 @@ abstract class CustomAbstractValueDefinition extends Locatable { * Gets the induced abstract value. */ AbstractValue getAbstractValue() { - result.(DefinedCustomAbstractValue).getDefinition() = this + result.(CustomAbstractValueFromDefinition).getDefinition() = this } + /** Holds if this is a value whose properties the type inference tracks. */ abstract predicate shouldTrackProperties(); } @@ -138,12 +143,12 @@ abstract class CustomAbstractValueDefinition extends Locatable { /** * Flow analysis for custom abstract values. */ -class DefinedCustomAbstractValueNode extends DataFlow::AnalyzedNode, DataFlow::ValueNode { +class CustomAbstractValueFromDefinitionNode extends DataFlow::AnalyzedNode, DataFlow::ValueNode { - DefinedCustomAbstractValue val; + CustomAbstractValueFromDefinition val; - DefinedCustomAbstractValueNode() { - val = TDefinedCustomAbstractValue(this.getAstNode()) + CustomAbstractValueFromDefinitionNode() { + val = TCustomAbstractValueFromDefinition(this.getAstNode()) } override AbstractValue getALocalValue() { diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll index 8af16f4b9d5..c82d0e42dbb 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractPropertiesImpl.qll @@ -78,5 +78,5 @@ predicate shouldTrackProperties(AbstractValue baseVal) { shouldAlwaysTrackProperties(baseVal) or baseVal instanceof AbstractObjectLiteral or baseVal instanceof AbstractInstance or - baseVal.(DefinedCustomAbstractValue).shouldTrackProperties() + baseVal.(CustomAbstractValueFromDefinition).shouldTrackProperties() } diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll index ae8c0b3b39a..36a22a95f09 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll @@ -6,7 +6,7 @@ import semmle.javascript.dataflow.AbstractValues private import semmle.javascript.dataflow.InferredTypes -import semmle.javascript.dataflow.DefinedCustomAbstractValues +import semmle.javascript.dataflow.CustomAbstractValueDefinitions /** An abstract value inferred by the flow analysis. */ cached newtype TAbstractValue = @@ -104,7 +104,7 @@ cached newtype TAbstractValue = TCustomAbstractValue(CustomAbstractValueTag tag) or /** A custom abstract value induced by `def`. */ - TDefinedCustomAbstractValue(CustomAbstractValueDefinition def) + TCustomAbstractValueFromDefinition(CustomAbstractValueDefinition def) /** * Gets a definite abstract value with the given type. diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll index 16ba5e9aa7d..f70f6ea20af 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -14,8 +14,7 @@ import semmle.javascript.dataflow.Configuration */ predicate shouldTrackProperties(AbstractValue obj) { obj instanceof AbstractExportsObject or - obj instanceof AbstractModuleObject or - obj.(DefinedCustomAbstractValue).shouldTrackProperties() + obj instanceof AbstractModuleObject } /** diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.expected similarity index 82% rename from javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected rename to javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.expected index 15298d15903..e7d73ca3b88 100644 --- a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.expected +++ b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.expected @@ -1,2 +1,2 @@ | tst.js:4:16:4:50 | { custo ... false } | tst.js:4:16:4:50 | { custo ... false } | false | false | -| tst.js:5:16:5:49 | { custo ... true } | tst.js:5:16:5:49 | { custo ... true } | true | true | +| tst.js:5:16:5:49 | { custo ... true } | tst.js:5:16:5:49 | { custo ... true } | false | true | diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.ql similarity index 95% rename from javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql rename to javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.ql index 689d04b3c19..810cd457d05 100644 --- a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValue.ql +++ b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitions.ql @@ -2,7 +2,7 @@ import javascript import semmle.javascript.dataflow.InferredTypes import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps import semmle.javascript.dataflow.internal.AbstractPropertiesImpl as AbstractPropertiesImpl -import semmle.javascript.dataflow.DefinedCustomAbstractValues +import semmle.javascript.dataflow.CustomAbstractValueDefinitions class MyCustomAbstractValueDefinition extends CustomAbstractValueDefinition { diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.expected b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitionsFlow.expected similarity index 100% rename from javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.expected rename to javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitionsFlow.expected diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitionsFlow.ql similarity index 82% rename from javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql rename to javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitionsFlow.ql index 859ca79d0af..0d8eb67043d 100644 --- a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/DefinedCustomAbstractValueFlow.ql +++ b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/CustomAbstractValueDefinitionsFlow.ql @@ -1,6 +1,6 @@ import javascript import semmle.javascript.dataflow.InferredTypes -import semmle.javascript.dataflow.DefinedCustomAbstractValues +import semmle.javascript.dataflow.CustomAbstractValueDefinitions class MyCustomAbstractValueDefinition extends CustomAbstractValueDefinition { @@ -34,7 +34,7 @@ class MyCustomAbstractValueDefinition extends CustomAbstractValueDefinition { } -from AnalyzedValueNode n, MyCustomAbstractValueDefinition def, DefinedCustomAbstractValue val +from AnalyzedValueNode n, MyCustomAbstractValueDefinition def, CustomAbstractValueFromDefinition val where def.getAbstractValue() = val and n.getAValue() = val select n, val \ No newline at end of file diff --git a/javascript/ql/test/library-tests/DefinedCustomAbstractValue/tst.js b/javascript/ql/test/library-tests/CustomAbstractValueDefinitions/tst.js similarity index 100% rename from javascript/ql/test/library-tests/DefinedCustomAbstractValue/tst.js rename to javascript/ql/test/library-tests/CustomAbstractValueDefinitions/tst.js From 54fea1a4cb3ce631ec2cecd1db8d890212d52646 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Tue, 20 Nov 2018 09:00:33 +0100 Subject: [PATCH 42/94] JS: support "xyz:nomunge" YUI compressor directives --- change-notes/1.19/analysis-javascript.md | 1 + javascript/ql/src/semmle/javascript/Stmt.qll | 6 ++++++ .../Expressions/UnknownDirective/UnknownDirective.expected | 2 ++ .../Expressions/UnknownDirective/UnknownDirective.js | 7 +++++++ 4 files changed, 16 insertions(+) diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index d190d16dc14..c52b5c82a70 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -51,6 +51,7 @@ | Server-side URL redirect | More results | This rule now recognizes redirection calls in more cases. | | Unbound event handler receiver | Fewer false-positive results | This rule now recognizes additional ways class methods can be bound. | | Uncontrolled data used in remote request | More results | This rule now recognizes additional kinds of requests. | +| Unknown directive | Fewer false positives results | This rule now recognizes YUI compressor directives. | | Unused import | Fewer false-positive results | This rule no longer flags imports used by the `transform-react-jsx` Babel plugin. | | Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that may be used by `eval` calls. | | Unused variable, import, function or class | Fewer results | This rule now flags import statements with multiple unused imports once. | diff --git a/javascript/ql/src/semmle/javascript/Stmt.qll b/javascript/ql/src/semmle/javascript/Stmt.qll index 486298a3896..e076011ee44 100644 --- a/javascript/ql/src/semmle/javascript/Stmt.qll +++ b/javascript/ql/src/semmle/javascript/Stmt.qll @@ -224,6 +224,12 @@ class NgInjectDirective extends KnownDirective { NgInjectDirective() { getDirectiveText().regexpMatch("ng(No)?Inject") } } +/** A YUI compressor directive. */ +class YuiDirective extends KnownDirective { + YuiDirective() { + getDirectiveText().regexpMatch("([a-z0-9_]+:nomunge, ?)*([a-z0-9_]+:nomunge)") + } +} /** A SystemJS `deps` directive. */ class SystemJSDepsDirective extends KnownDirective { diff --git a/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.expected b/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.expected index 26a54cf8612..4968baa31ee 100644 --- a/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.expected +++ b/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.expected @@ -13,3 +13,5 @@ | UnknownDirective.js:14:5:14:14 | "use bar"; | Unknown directive: 'use bar'. | | UnknownDirective.js:38:5:38:17 | "[0, 0, 0];"; | Unknown directive: '[0, 0, 0];'. | | UnknownDirective.js:39:5:39:65 | "[0, 0, ... , 0];"; | Unknown directive: '[0, 0, 0, 0, 0, 0, 0 ... (truncated)'. | +| UnknownDirective.js:45:5:45:15 | ":nomunge"; | Unknown directive: ':nomunge'. | +| UnknownDirective.js:46:5:46:30 | "foo(), ... munge"; | Unknown directive: 'foo(), bar, baz:nomu ... (truncated)'. | diff --git a/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.js b/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.js index 5f38a2eb1a0..fc0da8bde43 100644 --- a/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.js +++ b/javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.js @@ -38,3 +38,10 @@ function data() { "[0, 0, 0];"; // NOT OK "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];"; // NOT OK } + +function yui() { + "foo:nomunge"; // OK + "bar:nomunge, baz:nomunge,qux:nomunge"; // OK + ":nomunge"; // NOT OK + "foo(), bar, baz:nomunge"; // NOT OK +} From 9f7eef02ec27d9c1cec01a56b1b2cb6a042100fe Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Nov 2018 09:24:53 +0100 Subject: [PATCH 43/94] C#: Address review comments --- .../src/semmle/code/csharp/dataflow/SSA.qll | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll index 4c4da9cfe4c..863f46d8ca7 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll @@ -319,10 +319,10 @@ module Ssa { } /** - * Holds if source varible `v` is likely to be live at any node inside basic - * block `bb`. + * Holds if source variable `v` is likely to be live at any node inside basic + * block `bb`. This is an overestimate. */ - predicate likelyLive(BasicBlock bb, SourceVariable v) { + predicate possiblyLiveAtAllNodes(BasicBlock bb, SourceVariable v) { liveAtExit(bb, v, _) or ref(bb, _, v, Read(_)) @@ -1203,7 +1203,7 @@ module Ssa { * `i`. */ private predicate updateCandidate(BasicBlock bb, int i, TrackedFieldOrProp fp, Call call) { - likelyLive(bb, fp) and + possiblyLiveAtAllNodes(bb, fp) and callAt(bb, i, call) and relevantDefinition(_, fp.getAssignable(), _) and not ref(bb, i, fp, _) @@ -1296,7 +1296,7 @@ module Ssa { setsOwnFieldOrPropTransitive(getARuntimeTarget(call), tfp.getAssignable(), setter) } - private predicate updatesNamedFieldOrPropLikelyLive(BasicBlock bb, int i, TrackedFieldOrProp fp, Call call, Callable setter) { + private predicate updatesNamedFieldOrPropPossiblyLive(BasicBlock bb, int i, TrackedFieldOrProp fp, Call call, Callable setter) { updateCandidate(bb, i, fp, call) and ( updatesNamedFieldOrPropPart1(call, fp, setter) @@ -1306,7 +1306,7 @@ module Ssa { } private int firstRefAfterCall(BasicBlock bb, int i, TrackedFieldOrProp fp) { - updatesNamedFieldOrPropLikelyLive(bb, i, fp, _, _) and + updatesNamedFieldOrPropPossiblyLive(bb, i, fp, _, _) and result = min(int k | k > i and ref(bb, k, fp, _)) } @@ -1318,7 +1318,7 @@ module Ssa { predicate updatesNamedFieldOrProp(Call c, TrackedFieldOrProp fp, Callable setter) { forceCachingInSameStage() and exists(BasicBlock bb, int i | - updatesNamedFieldOrPropLikelyLive(bb, i, fp, c, setter) | + updatesNamedFieldOrPropPossiblyLive(bb, i, fp, c, setter) | not exists(firstRefAfterCall(bb, i, fp)) and liveAtExit(bb, fp, _) or @@ -1439,7 +1439,7 @@ module Ssa { * `i`. */ private predicate updateCandidate(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v, Call call) { - likelyLive(bb, v) and + possiblyLiveAtAllNodes(bb, v) and callAt(bb, i, call) and relevantDefinition(_, v.getAssignable(), _) } @@ -1522,7 +1522,7 @@ module Ssa { * Holds if `call` may change the value of captured variable `v`. The actual * update occurs in `def`. */ - private predicate updatesCapturedVariableLikelyLive(BasicBlock bb, int i, Call call, LocalScopeSourceVariable v, AssignableDefinition def) { + private predicate updatesCapturedVariablePossiblyLive(BasicBlock bb, int i, Call call, LocalScopeSourceVariable v, AssignableDefinition def) { updateCandidate(bb, i, v, call) and exists(Callable writer | relevantDefinition(writer, v.getAssignable(), def) | @@ -1531,7 +1531,7 @@ module Ssa { } private int firstRefAfter(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v) { - updatesCapturedVariableLikelyLive(bb, i, _, v, _) and + updatesCapturedVariablePossiblyLive(bb, i, _, v, _) and result = min(int k | k > i and ref(bb, k, v, _)) } @@ -1543,7 +1543,7 @@ module Ssa { predicate updatesCapturedVariable(Call call, LocalScopeSourceVariable v, AssignableDefinition def) { forceCachingInSameStage() and exists(BasicBlock bb, int i | - updatesCapturedVariableLikelyLive(bb, i, call, v, def) | + updatesCapturedVariablePossiblyLive(bb, i, call, v, def) | not exists(firstRefAfter(bb, i, v)) and liveAtExit(bb, v, _) or From d7c2f9d18566b5e0c6a36a11d7aaa1a45f9ecd38 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Tue, 20 Nov 2018 09:43:54 +0100 Subject: [PATCH 44/94] C++: Remove @precision from AV Rule 78 This rule, named "No virtual destructor", was supposed to be superseded by `cpp/virtual-destructor` in 0c796de83, but that commit didn't actually disable this rule, so both rules are now active in the LGTM suite. This commit disables the rule by removing `@precision`. We're still discussing the best way to disable rules that are precise and valid but not universally applicable. For now, removing `@precision` is consistent with how we're keeping most other JSF queries from appearing on LGTM. --- cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql index 04a69db8ddd..ae751e1ce10 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql @@ -3,7 +3,6 @@ * @description All base classes with a virtual function should define a virtual destructor. If an application attempts to delete a derived class object through a base class pointer, the result is undefined if the base class destructor is non-virtual. * @kind problem * @problem.severity warning - * @precision high * @id cpp/jsf/av-rule-78 * @tags reliability * readability From 342164ff714e98355b2dc1723d2eef9112d131bb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 15 Nov 2018 13:55:48 +0000 Subject: [PATCH 45/94] CPP: Clean up / normalize some test code. --- cpp/ql/test/library-tests/opts/main.cpp | 4 +-- .../ReturnCstrOfLocalStdString.expected | 6 ++--- .../ReturnCstrOfLocalStdString/test.cpp | 26 ++++++++++--------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/cpp/ql/test/library-tests/opts/main.cpp b/cpp/ql/test/library-tests/opts/main.cpp index 2f78971c3fc..881cd001ad3 100644 --- a/cpp/ql/test/library-tests/opts/main.cpp +++ b/cpp/ql/test/library-tests/opts/main.cpp @@ -1,8 +1,8 @@ char *Xstrdup(const char *string); -void abort(); +void abort(void); struct FILE; -char *fgets(char *str, int num, FILE *stream); +char *fgets(char *s, int n, FILE *stream); int ignore_return_value(); #define IGNORE_RETURN_VALUE() ignore_return_value() void myIgnoreReturnValue(); diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/ReturnCstrOfLocalStdString.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/ReturnCstrOfLocalStdString.expected index 32869c5353b..df2724bc3c6 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/ReturnCstrOfLocalStdString.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/ReturnCstrOfLocalStdString.expected @@ -1,3 +1,3 @@ -| test.cpp:22:3:22:26 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:21:24:21:37 | call to string | this local std::string | -| test.cpp:30:3:30:44 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:30:10:30:35 | call to string | this local std::string | -| test.cpp:43:3:43:42 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:42:22:42:35 | call to string | this local std::string | +| test.cpp:24:3:24:26 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:23:24:23:37 | call to basic_string | this local std::string | +| test.cpp:32:3:32:44 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:32:10:32:35 | call to basic_string | this local std::string | +| test.cpp:45:3:45:42 | return ... | Return value may contain a dangling pointer to $@. | test.cpp:44:22:44:35 | call to basic_string | this local std::string | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/test.cpp index b9858ab5594..c27cb77b1d8 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString/test.cpp @@ -1,20 +1,22 @@ -extern "C" { - char *strdup(const char *s); - void free (void* ptr); -} namespace std { - // We are not allowed to include in the test file, - // so this is an approximation of the std::string class. - class string { - char* str_; + template struct char_traits; + template class allocator { public: - string(const char* str) : str_(strdup(str)) {} - ~string() { free(str_); } - - const char* c_str() const noexcept { return str_; } + allocator() throw(); }; + + template, class Allocator = allocator > + class basic_string { + public: + explicit basic_string(const Allocator& a = Allocator()); + basic_string(const charT* s, const Allocator& a = Allocator()); + + const charT* c_str() const; + }; + + typedef basic_string string; } const char* bad000() { From 82fc8ae32aed7ad2d961ab0aa5606496effff69c Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Tue, 20 Nov 2018 10:08:44 +0100 Subject: [PATCH 46/94] JS: support indirection with extra args in js/missing-this-qualifier --- change-notes/1.19/analysis-javascript.md | 1 + javascript/ql/src/Declarations/MissingThisQualifier.ql | 8 ++++++++ .../Declarations/MissingThisQualifier/indirection.js | 5 +++++ 3 files changed, 14 insertions(+) create mode 100644 javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index d190d16dc14..84a7f1c928a 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -43,6 +43,7 @@ | Duplicate switch case | Lower severity | The severity of this rule has been revised to "warning". | | Information exposure through a stack trace | More results | This rule now also flags cases where the entire exception object (including the stack trace) may be exposed. | | Missing CSRF middleware | Fewer false-positive results | This rule now recognizes additional CSRF protection middlewares. | +| Missing 'this' qualifier | Fewer false-positive results | This rule now recognizes additional intentional calls to global functions. | | Missing variable declaration | Lower severity | The severity of this rule has been revised to "warning". | | Regular expression injection | Fewer false-positive results | This rule now identifies calls to `String.prototype.search` with more precision. | | Remote property injection | Fewer results | The precision of this rule has been revised to "medium". Results are no longer shown on LGTM by default. | diff --git a/javascript/ql/src/Declarations/MissingThisQualifier.ql b/javascript/ql/src/Declarations/MissingThisQualifier.ql index e6218a4a0d4..93f4fa665e4 100644 --- a/javascript/ql/src/Declarations/MissingThisQualifier.ql +++ b/javascript/ql/src/Declarations/MissingThisQualifier.ql @@ -50,5 +50,13 @@ where maybeMissingThis(call, intendedTarget, gv) decl.isNamespaceExport() and call.getContainer().getEnclosingContainer*() instanceof NamespaceDeclaration ) + or + // call to global function with additional arguments + exists (Function self | + intendedTarget.getBody() = self and + call.getEnclosingFunction() = self and + call.flow().(DataFlow::CallNode).getNumArgument() > self.getNumParameter() and + not self.usesArgumentsObject() + ) ) select call, "This call refers to a global function, and not the local method $@.", intendedTarget, intendedTarget.getName() diff --git a/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js b/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js new file mode 100644 index 00000000000..60488458ac4 --- /dev/null +++ b/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js @@ -0,0 +1,5 @@ +class X { + m() { + m("default"); // OK + } +} From c1690a69e538e0c979a33315df9a80d5dd6fa20a Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Tue, 20 Nov 2018 12:51:37 +0000 Subject: [PATCH 47/94] JavaScript: Make `TargetBlank` only highlight the first line of the link. Otherwise alerts for multi-line `` elements end up looking very red. I also took the opportunity to improve the tests slightly. --- javascript/ql/src/DOM/TargetBlank.ql | 3 ++- .../query-tests/DOM/TargetBlank/TargetBlank.expected | 3 +++ javascript/ql/test/query-tests/DOM/TargetBlank/tst.html | 9 ++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/DOM/TargetBlank.ql b/javascript/ql/src/DOM/TargetBlank.ql index a59954a6aba..cc48d548074 100644 --- a/javascript/ql/src/DOM/TargetBlank.ql +++ b/javascript/ql/src/DOM/TargetBlank.ql @@ -13,6 +13,7 @@ import javascript import semmle.javascript.frameworks.Templating +import semmle.javascript.RestrictedLocations /** * Holds if the href attribute contains a host that we cannot determine statically. @@ -53,4 +54,4 @@ where // `e` is a link that opens in a new browsing context (that is, it has `ta not exists (DOM::AttributeDefinition attr | attr = e.getAnAttribute() | not exists(attr.getName()) ) -select e, "External links without noopener/noreferrer are a potential security risk." +select (FirstLineOf)e, "External links without noopener/noreferrer are a potential security risk." diff --git a/javascript/ql/test/query-tests/DOM/TargetBlank/TargetBlank.expected b/javascript/ql/test/query-tests/DOM/TargetBlank/TargetBlank.expected index 44418490bda..6f0af3473f2 100644 --- a/javascript/ql/test/query-tests/DOM/TargetBlank/TargetBlank.expected +++ b/javascript/ql/test/query-tests/DOM/TargetBlank/TargetBlank.expected @@ -1,3 +1,6 @@ +| tst.html:23:1:23:61 | ... | External links without noopener/noreferrer are a potential security risk. | +| tst.html:24:1:24:48 | ... | External links without noopener/noreferrer are a potential security risk. | +| tst.html:25:1:25:36 | ... | External links without noopener/noreferrer are a potential security risk. | | tst.js:18:1:18:43 | | External links without noopener/noreferrer are a potential security risk. | | tst.js:19:1:19:58 | | External links without noopener/noreferrer are a potential security risk. | | tst.js:20:1:20:51 | | External links without noopener/noreferrer are a potential security risk. | diff --git a/javascript/ql/test/query-tests/DOM/TargetBlank/tst.html b/javascript/ql/test/query-tests/DOM/TargetBlank/tst.html index 1a16fb7d786..ded63fefde7 100644 --- a/javascript/ql/test/query-tests/DOM/TargetBlank/tst.html +++ b/javascript/ql/test/query-tests/DOM/TargetBlank/tst.html @@ -14,10 +14,17 @@ Example Example -

NOT OK, because of dynamic URL

+

OK, because of constant prefix

Example Example Example +

NOT OK, because of dynamic URL

+Example +Example + + Example + + From 25150265dc1eb9da1ceb732539a0d05fea40f328 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 12 Nov 2018 15:49:50 +0100 Subject: [PATCH 48/94] C#: Compute phi inputs in pre-SSA library Logic is copied directly from the ordinary SSA library. --- .../csharp/controlflow/ControlFlowGraph.qll | 116 ++++++++++++++++-- .../dataflow/ssa/PreSsaConsistency.expected | 3 + .../dataflow/ssa/PreSsaConsistency.ql | 50 ++++++-- 3 files changed, 149 insertions(+), 20 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll index aa7bf06f2a2..366c3958a30 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll @@ -2516,8 +2516,12 @@ module ControlFlow { result = strictcount(getAnElement()) } + predicate immediatelyDominates(PreBasicBlock bb) { + bbIDominates(this, bb) + } + predicate strictlyDominates(PreBasicBlock bb) { - bbIDominates+(this, bb) + this.immediatelyDominates+(bb) } predicate dominates(PreBasicBlock bb) { @@ -2584,8 +2588,6 @@ module ControlFlow { } } - private newtype SsaRefKind = SsaRead() or SsaDef() - class Definition extends TPreSsaDef { string toString() { exists(AssignableDefinition def | @@ -2626,12 +2628,25 @@ module ControlFlow { ) } + PreBasicBlock getBasicBlock() { + this = TExplicitPreSsaDef(result, _, _, _) or + this = TPhiPreSsaDef(result, _) + } + AssignableDefinition getDefinition() { this = TExplicitPreSsaDef(_, _, result, _) } + + Definition getAPhiInput() { + exists(PreBasicBlock bb, PreBasicBlock phiPred, SimpleLocalScopeVariable v | + this = TPhiPreSsaDef(bb, v) | + bb.getAPredecessor() = phiPred and + ssaDefReachesEndOfBlock(phiPred, result, v) + ) + } } - predicate assignableDefAt(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleLocalScopeVariable v) { + private predicate assignableDefAt(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleLocalScopeVariable v) { bb.getElement(i) = def.getExpr() and v = def.getTarget() and // In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x` @@ -2650,16 +2665,82 @@ module ControlFlow { ) } + private predicate readAt(PreBasicBlock bb, int i, LocalScopeVariableRead read, SimpleLocalScopeVariable v) { + read = bb.getElement(i) and + read.getTarget() = v + } + + pragma[noinline] + private predicate exitBlock(PreBasicBlock bb, Callable c) { + exists(succExit(bb.getLastElement(), _)) and + c = bb.getEnclosingCallable() + } + + private predicate outRefExitRead(PreBasicBlock bb, int i, SimpleLocalScopeVariable v) { + exitBlock(bb, v.getCallable()) and + i = bb.length() + 1 and + (v.isRef() or v.(Parameter).isOut()) + } + + private newtype RefKind = + Read() + or + Write(boolean certain) { certain = true or certain = false } + + private predicate ref(PreBasicBlock bb, int i, SimpleLocalScopeVariable v, RefKind k) { + (readAt(bb, i, _, v) or outRefExitRead(bb, i, v)) and + k = Read() + or + exists(AssignableDefinition def, boolean certain | + assignableDefAt(bb, i, def, v) | + if def.getTargetAccess().isRefArgument() then certain = false else certain = true and + k = Write(certain) + ) + } + + private int refRank(PreBasicBlock bb, int i, SimpleLocalScopeVariable v, RefKind k) { + i = rank[result](int j | ref(bb, j, v, _)) and + ref(bb, i, v, k) + } + + private int firstReadOrCertainWrite(PreBasicBlock bb, SimpleLocalScopeVariable v) { + result = min(int r, RefKind k | + r = refRank(bb, _, v, k) and + k != Write(false) + | + r + ) + } + + predicate liveAtEntry(PreBasicBlock bb, SimpleLocalScopeVariable v) { + refRank(bb, _, v, Read()) = firstReadOrCertainWrite(bb, v) + or + not exists(firstReadOrCertainWrite(bb, v)) and + liveAtExit(bb, v) + } + + private predicate liveAtExit(PreBasicBlock bb, SimpleLocalScopeVariable v) { + liveAtEntry(bb.getASuccessor(), v) + } + + predicate assignableDefAtLive(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleLocalScopeVariable v) { + assignableDefAt(bb, i, def, v) and + exists(int rnk | + rnk = refRank(bb, i, v, Write(_)) | + rnk + 1 = refRank(bb, _, v, Read()) + or + rnk = max(refRank(bb, _, v, _)) and + liveAtExit(bb, v) + ) + } + predicate defAt(PreBasicBlock bb, int i, Definition def, SimpleLocalScopeVariable v) { def = TExplicitPreSsaDef(bb, i, _, v) or def = TPhiPreSsaDef(bb, v) and i = -1 } - private predicate readAt(PreBasicBlock bb, int i, LocalScopeVariableRead read, SimpleLocalScopeVariable v) { - read = bb.getElement(i) and - read.getTarget() = v - } + private newtype SsaRefKind = SsaRead() or SsaDef() private predicate ssaRef(PreBasicBlock bb, int i, SimpleLocalScopeVariable v, SsaRefKind k) { readAt(bb, i, _, v) and @@ -2756,6 +2837,22 @@ module ControlFlow { readAt(bb2, i2, read2, v) ) } + + predicate ssaDefReachesEndOfBlock(PreBasicBlock bb, Definition def, SimpleLocalScopeVariable v) { + liveAtExit(bb, v) and + ( + exists(int last | + last = max(ssaRefRank(bb, _, v, _)) | + defReachesRank(bb, def, v, last) + ) + or + exists(PreBasicBlock idom | + idom.immediatelyDominates(bb) | + ssaDefReachesEndOfBlock(idom, def, v) and + not exists(ssaRefRank(bb, _, v, SsaDef())) + ) + ) + } } /** @@ -3847,10 +3944,11 @@ module ControlFlow { newtype TPreSsaDef = TExplicitPreSsaDef(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, LocalScopeVariable v) { Guards::Internal::CachedWithCFG::forceCachingInSameStage() and - PreSsa::assignableDefAt(bb, i, def, v) + PreSsa::assignableDefAtLive(bb, i, def, v) } or TPhiPreSsaDef(PreBasicBlocks::PreBasicBlock bb, LocalScopeVariable v) { + PreSsa::liveAtEntry(bb, v) and exists(PreBasicBlocks::PreBasicBlock def | def.inDominanceFrontier(bb) | PreSsa::defAt(def, _, _, v) diff --git a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.expected b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.expected index e69de29bb2d..4fa64b47674 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.expected @@ -0,0 +1,3 @@ +defReadInconsistency +readReadInconsistency +phiInconsistency diff --git a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql index caa9144fe15..23e74eb0c8f 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql +++ b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql @@ -1,11 +1,13 @@ import csharp import ControlFlow::Internal -predicate defReadInconsistency(AssignableRead ar, Expr e, boolean b) { +query +predicate defReadInconsistency(AssignableRead ar, Expr e, PreSsa::SimpleLocalScopeVariable v, boolean b) { exists(AssignableDefinition def | e = def.getExpr() | b = true and exists(PreSsa::Definition ssaDef | + ssaDef.getVariable() = v | PreSsa::firstReadSameVar(ssaDef, ar) and ssaDef.getDefinition() = def and not exists(Ssa::ExplicitDefinition edef | @@ -18,7 +20,7 @@ predicate defReadInconsistency(AssignableRead ar, Expr e, boolean b) { exists(Ssa::ExplicitDefinition edef | edef.getADefinition() = def and edef.getAFirstRead() = ar and - def.getTarget() instanceof PreSsa::SimpleLocalScopeVariable and + def.getTarget() = v and not exists(PreSsa::Definition ssaDef | PreSsa::firstReadSameVar(ssaDef, ar) and ssaDef.getDefinition() = def @@ -27,22 +29,48 @@ predicate defReadInconsistency(AssignableRead ar, Expr e, boolean b) { ) } -predicate readReadInconsistency(LocalScopeVariableRead read1, LocalScopeVariableRead read2, boolean b) { +query +predicate readReadInconsistency(LocalScopeVariableRead read1, LocalScopeVariableRead read2, PreSsa::SimpleLocalScopeVariable v, boolean b) { b = true and + v = read1.getTarget() and PreSsa::adjacentReadPairSameVar(read1, read2) and not Ssa::Internal::adjacentReadPairSameVar(read1, read2) or b = false and + v = read1.getTarget() and Ssa::Internal::adjacentReadPairSameVar(read1, read2) and read1.getTarget() instanceof PreSsa::SimpleLocalScopeVariable and not PreSsa::adjacentReadPairSameVar(read1, read2) } -from Element e1, Element e2, boolean b, string s -where - defReadInconsistency(e1, e2, b) and - s = "def-read inconsistency (" + b + ")" - or - readReadInconsistency(e1, e2, b) and - s = "read-read inconsistency (" + b + ")" -select e1, e2, s +query +predicate phiInconsistency(ControlFlowElement cfe, Expr e, PreSsa::SimpleLocalScopeVariable v, boolean b) { + exists(AssignableDefinition adef | + e = adef.getExpr() | + b = true and + exists(PreSsa::Definition def | + v = def.getVariable() | + adef = def.getAPhiInput+().getDefinition() and + cfe = def.getBasicBlock().getFirstElement() and + not exists(Ssa::PhiNode phi, ControlFlow::BasicBlock bb, Ssa::ExplicitDefinition edef | + edef = phi.getAnUltimateDefinition() | + edef.getADefinition() = adef and + phi.definesAt(bb, _) and + cfe = bb.getFirstNode().getElement() + ) + ) + or + b = false and + exists(Ssa::PhiNode phi, ControlFlow::BasicBlock bb, Ssa::ExplicitDefinition edef | + v = phi.getSourceVariable().getAssignable() | + edef = phi.getAnUltimateDefinition() and + edef.getADefinition() = adef and + phi.definesAt(bb, _) and + cfe = bb.getFirstNode().getElement() and + not exists(PreSsa::Definition def | + adef = def.getAPhiInput+().getDefinition() and + cfe = def.getBasicBlock().getFirstElement() + ) + ) + ) +} From 3e78c2671f44dd377d311caa8d15a1b613aa7e1d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 13 Nov 2018 21:16:36 +0100 Subject: [PATCH 49/94] C#: Generalize pre-SSA library to include local-scope-like fields/properties --- .../csharp/controlflow/ControlFlowGraph.qll | 323 +++++++++++------- .../src/semmle/code/csharp/dataflow/SSA.qll | 72 ++-- .../code/csharp/dataflow/internal/BaseSSA.qll | 3 +- .../dataflow/ssa/PreSsaConsistency.ql | 20 +- 4 files changed, 256 insertions(+), 162 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll index 366c3958a30..6e232bf79da 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll @@ -2569,7 +2569,8 @@ module ControlFlow { /** * Provides an SSA implementation based on "pre-basic-blocks", restricted - * to local scope variables. + * to local scope variables and fields/properties that behave like local + * scope variables. * * The logic is duplicated from the implementation in `SSA.qll`, and * being an internal class, all predicate documentation has been removed. @@ -2578,14 +2579,39 @@ module ControlFlow { private import PreBasicBlocks private import AssignableDefinitions - class SimpleLocalScopeVariable extends LocalScopeVariable { - SimpleLocalScopeVariable() { - not exists(AssignableDefinition def1, AssignableDefinition def2 | - def1.getTarget() = this and - def2.getTarget() = this and - def1.getEnclosingCallable() != def2.getEnclosingCallable() + /** + * A simple assignable. Either a local scope variable or a field/property + * that behaves like a local scope variable. + */ + class SimpleAssignable extends Assignable { + private Callable c; + + SimpleAssignable() { + ( + this instanceof LocalScopeVariable + or + this instanceof Field + or + this = any(TrivialProperty tp | not tp.isOverridableOrImplementable()) + ) and + forall(AssignableDefinition def | + def.getTarget() = this | + c = def.getEnclosingCallable() + or + def.getEnclosingCallable() instanceof Constructor + ) and + exists(AssignableAccess aa | + aa.getTarget() = this | + c = aa.getEnclosingCallable() + ) and + forall(QualifiableExpr qe | + qe.(AssignableAccess).getTarget() = this | + qe.targetIsThisInstance() ) } + + /** Gets a callable in which this simple assignable can be analyzed. */ + Callable getACallable() { result = c } } class Definition extends TPreSsaDef { @@ -2595,22 +2621,29 @@ module ControlFlow { result = def.toString() ) or - exists(SimpleLocalScopeVariable v | - this = TPhiPreSsaDef(_, v) | - result = "phi(" + v.toString() + ")" + exists(SimpleAssignable a | + this = TImplicitEntryPreSsaDef(_, _, a) | + result = "implicit(" + a + ")" + ) + or + exists(SimpleAssignable a | + this = TPhiPreSsaDef(_, a) | + result = "phi(" + a.toString() + ")" ) } - SimpleLocalScopeVariable getVariable() { + SimpleAssignable getAssignable() { this = TExplicitPreSsaDef(_, _, _, result) or + this = TImplicitEntryPreSsaDef(_, _, result) + or this = TPhiPreSsaDef(_, result) } - LocalScopeVariableRead getARead() { + AssignableRead getARead() { firstReadSameVar(this, result) or - exists(LocalScopeVariableRead read | + exists(AssignableRead read | firstReadSameVar(this, read) | adjacentReadPairSameVar+(read, result) ) @@ -2622,6 +2655,11 @@ module ControlFlow { result = def.getLocation() ) or + exists(Callable c | + this = TImplicitEntryPreSsaDef(c, _, _) | + result = c.getLocation() + ) + or exists(PreBasicBlock bb | this = TPhiPreSsaDef(bb, _) | result = bb.getLocation() @@ -2629,45 +2667,58 @@ module ControlFlow { } PreBasicBlock getBasicBlock() { - this = TExplicitPreSsaDef(result, _, _, _) or + this = TExplicitPreSsaDef(result, _, _, _) + or + this = TImplicitEntryPreSsaDef(_, result, _) + or this = TPhiPreSsaDef(result, _) } + Callable getCallable() { + result = this.getBasicBlock().getEnclosingCallable() + } + AssignableDefinition getDefinition() { this = TExplicitPreSsaDef(_, _, result, _) } Definition getAPhiInput() { - exists(PreBasicBlock bb, PreBasicBlock phiPred, SimpleLocalScopeVariable v | - this = TPhiPreSsaDef(bb, v) | + exists(PreBasicBlock bb, PreBasicBlock phiPred, SimpleAssignable a | + this = TPhiPreSsaDef(bb, a) | bb.getAPredecessor() = phiPred and - ssaDefReachesEndOfBlock(phiPred, result, v) + ssaDefReachesEndOfBlock(phiPred, result, a) ) } } - private predicate assignableDefAt(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleLocalScopeVariable v) { + predicate implicitEntryDef(Callable c, PreBasicBlock bb, SimpleAssignable a) { + not a instanceof LocalScopeVariable and + c = a.getACallable() and + bb = succEntry(c) + } + + private predicate assignableDefAt(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleAssignable a) { bb.getElement(i) = def.getExpr() and - v = def.getTarget() and + a = def.getTarget() and // In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x` not exists(TupleAssignmentDefinition first, TupleAssignmentDefinition second | first = def | second.getAssignment() = first.getAssignment() and second.getEvaluationOrder() > first.getEvaluationOrder() and - second.getTarget() = v + second.getTarget() = a ) or - def.(ImplicitParameterDefinition).getParameter() = v and + def.(ImplicitParameterDefinition).getParameter() = a and exists(Callable c | - v = c.getAParameter() | + a = c.getAParameter() | bb = succEntry(c) and i = -1 ) } - private predicate readAt(PreBasicBlock bb, int i, LocalScopeVariableRead read, SimpleLocalScopeVariable v) { + private predicate readAt(PreBasicBlock bb, int i, AssignableRead read, SimpleAssignable a) { read = bb.getElement(i) and - read.getTarget() = v + read.getTarget() = a } pragma[noinline] @@ -2676,7 +2727,7 @@ module ControlFlow { c = bb.getEnclosingCallable() } - private predicate outRefExitRead(PreBasicBlock bb, int i, SimpleLocalScopeVariable v) { + private predicate outRefExitRead(PreBasicBlock bb, int i, LocalScopeVariable v) { exitBlock(bb, v.getCallable()) and i = bb.length() + 1 and (v.isRef() or v.(Parameter).isOut()) @@ -2687,172 +2738,188 @@ module ControlFlow { or Write(boolean certain) { certain = true or certain = false } - private predicate ref(PreBasicBlock bb, int i, SimpleLocalScopeVariable v, RefKind k) { - (readAt(bb, i, _, v) or outRefExitRead(bb, i, v)) and + private predicate ref(PreBasicBlock bb, int i, SimpleAssignable a, RefKind k) { + (readAt(bb, i, _, a) or outRefExitRead(bb, i, a)) and k = Read() or exists(AssignableDefinition def, boolean certain | - assignableDefAt(bb, i, def, v) | + assignableDefAt(bb, i, def, a) | if def.getTargetAccess().isRefArgument() then certain = false else certain = true and k = Write(certain) ) } - private int refRank(PreBasicBlock bb, int i, SimpleLocalScopeVariable v, RefKind k) { - i = rank[result](int j | ref(bb, j, v, _)) and - ref(bb, i, v, k) + private int refRank(PreBasicBlock bb, int i, SimpleAssignable a, RefKind k) { + i = rank[result](int j | ref(bb, j, a, _)) and + ref(bb, i, a, k) } - private int firstReadOrCertainWrite(PreBasicBlock bb, SimpleLocalScopeVariable v) { + private int maxRefRank(PreBasicBlock bb, SimpleAssignable a) { + result = refRank(bb, _, a, _) and + not result + 1 = refRank(bb, _, a, _) + } + + private int firstReadOrCertainWrite(PreBasicBlock bb, SimpleAssignable a) { result = min(int r, RefKind k | - r = refRank(bb, _, v, k) and + r = refRank(bb, _, a, k) and k != Write(false) | r ) } - predicate liveAtEntry(PreBasicBlock bb, SimpleLocalScopeVariable v) { - refRank(bb, _, v, Read()) = firstReadOrCertainWrite(bb, v) + predicate liveAtEntry(PreBasicBlock bb, SimpleAssignable a) { + refRank(bb, _, a, Read()) = firstReadOrCertainWrite(bb, a) or - not exists(firstReadOrCertainWrite(bb, v)) and - liveAtExit(bb, v) + not exists(firstReadOrCertainWrite(bb, a)) and + liveAtExit(bb, a) } - private predicate liveAtExit(PreBasicBlock bb, SimpleLocalScopeVariable v) { - liveAtEntry(bb.getASuccessor(), v) + private predicate liveAtExit(PreBasicBlock bb, SimpleAssignable a) { + liveAtEntry(bb.getASuccessor(), a) } - predicate assignableDefAtLive(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleLocalScopeVariable v) { - assignableDefAt(bb, i, def, v) and + predicate assignableDefAtLive(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleAssignable a) { + assignableDefAt(bb, i, def, a) and exists(int rnk | - rnk = refRank(bb, i, v, Write(_)) | - rnk + 1 = refRank(bb, _, v, Read()) + rnk = refRank(bb, i, a, Write(_)) | + rnk + 1 = refRank(bb, _, a, Read()) or - rnk = max(refRank(bb, _, v, _)) and - liveAtExit(bb, v) + rnk = maxRefRank(bb, a) and + liveAtExit(bb, a) ) } - predicate defAt(PreBasicBlock bb, int i, Definition def, SimpleLocalScopeVariable v) { - def = TExplicitPreSsaDef(bb, i, _, v) + predicate defAt(PreBasicBlock bb, int i, Definition def, SimpleAssignable a) { + def = TExplicitPreSsaDef(bb, i, _, a) or - def = TPhiPreSsaDef(bb, v) and i = -1 + def = TImplicitEntryPreSsaDef(_, bb, a) and i = -1 + or + def = TPhiPreSsaDef(bb, a) and i = -1 } private newtype SsaRefKind = SsaRead() or SsaDef() - private predicate ssaRef(PreBasicBlock bb, int i, SimpleLocalScopeVariable v, SsaRefKind k) { - readAt(bb, i, _, v) and + private predicate ssaRef(PreBasicBlock bb, int i, SimpleAssignable a, SsaRefKind k) { + readAt(bb, i, _, a) and k = SsaRead() or - defAt(bb, i, _, v) and + defAt(bb, i, _, a) and k = SsaDef() } - private int ssaRefRank(PreBasicBlock bb, int i, SimpleLocalScopeVariable v, SsaRefKind k) { - i = rank[result](int j | ssaRef(bb, j, v, _)) and - ssaRef(bb, i, v, k) + private int ssaRefRank(PreBasicBlock bb, int i, SimpleAssignable a, SsaRefKind k) { + i = rank[result](int j | ssaRef(bb, j, a, _)) and + ssaRef(bb, i, a, k) } - private predicate defReachesRank(PreBasicBlock bb, Definition def, SimpleLocalScopeVariable v, int rnk) { + private predicate defReachesRank(PreBasicBlock bb, Definition def, SimpleAssignable a, int rnk) { exists(int i | - rnk = ssaRefRank(bb, i, v, SsaDef()) and - defAt(bb, i, def, v) + rnk = ssaRefRank(bb, i, a, SsaDef()) and + defAt(bb, i, def, a) ) or - defReachesRank(bb, def, v, rnk - 1) and - rnk = ssaRefRank(bb, _, v, SsaRead()) + defReachesRank(bb, def, a, rnk - 1) and + rnk = ssaRefRank(bb, _, a, SsaRead()) } - private predicate reachesEndOf(Definition def, SimpleLocalScopeVariable v, PreBasicBlock bb) { - exists(int rnk | - defReachesRank(bb, def, v, rnk) and - rnk = max(ssaRefRank(bb, _, v, _)) + private int maxSsaRefRank(PreBasicBlock bb, SimpleAssignable a) { + result = ssaRefRank(bb, _, a, _) and + not result + 1 = ssaRefRank(bb, _, a, _) + } + + private predicate reachesEndOf(Definition def, SimpleAssignable a, PreBasicBlock bb) { + exists(int last | + last = maxSsaRefRank(bb, a) | + defReachesRank(bb, def, a, last) ) or exists(PreBasicBlock mid | - reachesEndOf(def, v, mid) and - not exists(ssaRefRank(mid, _, v, SsaDef())) and + reachesEndOf(def, a, mid) and + not exists(ssaRefRank(mid, _, a, SsaDef())) and bb = mid.getASuccessor() ) } - private predicate varOccursInBlock(SimpleLocalScopeVariable v, PreBasicBlock bb) { - exists(ssaRefRank(bb, _, v, _)) + private predicate varOccursInBlock(SimpleAssignable a, PreBasicBlock bb) { + exists(ssaRefRank(bb, _, a, _)) } pragma [nomagic] - private predicate blockPrecedesVar(SimpleLocalScopeVariable v, PreBasicBlock bb) { - varOccursInBlock(v, bb.getASuccessor*()) + private predicate blockPrecedesVar(SimpleAssignable a, PreBasicBlock bb) { + varOccursInBlock(a, bb.getASuccessor*()) } - private predicate varBlockReaches(SimpleLocalScopeVariable v, PreBasicBlock bb1, PreBasicBlock bb2) { - varOccursInBlock(v, bb1) and + private predicate varBlockReaches(SimpleAssignable a, PreBasicBlock bb1, PreBasicBlock bb2) { + varOccursInBlock(a, bb1) and bb2 = bb1.getASuccessor() and - blockPrecedesVar(v, bb2) + blockPrecedesVar(a, bb2) or - varBlockReachesRec(v, bb1, bb2) and - blockPrecedesVar(v, bb2) + varBlockReachesRec(a, bb1, bb2) and + blockPrecedesVar(a, bb2) } pragma [nomagic] - private predicate varBlockReachesRec(SimpleLocalScopeVariable v, PreBasicBlock bb1, PreBasicBlock bb2) { + private predicate varBlockReachesRec(SimpleAssignable a, PreBasicBlock bb1, PreBasicBlock bb2) { exists(PreBasicBlock mid | - varBlockReaches(v, bb1, mid) | + varBlockReaches(a, bb1, mid) | bb2 = mid.getASuccessor() and - not varOccursInBlock(v, mid) + not varOccursInBlock(a, mid) ) } - private predicate varBlockStep(SimpleLocalScopeVariable v, PreBasicBlock bb1, PreBasicBlock bb2) { - varBlockReaches(v, bb1, bb2) and - varOccursInBlock(v, bb2) + private predicate varBlockStep(SimpleAssignable a, PreBasicBlock bb1, PreBasicBlock bb2) { + varBlockReaches(a, bb1, bb2) and + varOccursInBlock(a, bb2) } - private predicate adjacentVarRefs(SimpleLocalScopeVariable v, PreBasicBlock bb1, int i1, PreBasicBlock bb2, int i2) { + private predicate adjacentVarRefs(SimpleAssignable a, PreBasicBlock bb1, int i1, PreBasicBlock bb2, int i2) { exists(int rankix | bb1 = bb2 and - rankix = ssaRefRank(bb1, i1, v, _) and - rankix + 1 = ssaRefRank(bb2, i2, v, _) + rankix = ssaRefRank(bb1, i1, a, _) and + rankix + 1 = ssaRefRank(bb2, i2, a, _) ) or - ssaRefRank(bb1, i1, v, _) = max(ssaRefRank(bb1, _, v, _)) and - varBlockStep(v, bb1, bb2) and - ssaRefRank(bb2, i2, v, _) = 1 + ssaRefRank(bb1, i1, a, _) = maxSsaRefRank(bb1, a) and + varBlockStep(a, bb1, bb2) and + ssaRefRank(bb2, i2, a, _) = 1 } - predicate firstReadSameVar(Definition def, LocalScopeVariableRead read) { - exists(SimpleLocalScopeVariable v, PreBasicBlock b1, int i1, PreBasicBlock b2, int i2 | - adjacentVarRefs(v, b1, i1, b2, i2) and - defAt(b1, i1, def, v) and - readAt(b2, i2, read, v) + predicate firstReadSameVar(Definition def, AssignableRead read) { + exists(SimpleAssignable a, PreBasicBlock b1, int i1, PreBasicBlock b2, int i2 | + adjacentVarRefs(a, b1, i1, b2, i2) and + defAt(b1, i1, def, a) and + readAt(b2, i2, read, a) ) } - predicate adjacentReadPairSameVar(LocalScopeVariableRead read1, LocalScopeVariableRead read2) { - exists(SimpleLocalScopeVariable v, PreBasicBlock bb1, int i1, PreBasicBlock bb2, int i2 | - adjacentVarRefs(v, bb1, i1, bb2, i2) and - readAt(bb1, i1, read1, v) and - readAt(bb2, i2, read2, v) + predicate adjacentReadPairSameVar(AssignableRead read1, AssignableRead read2) { + exists(SimpleAssignable a, PreBasicBlock bb1, int i1, PreBasicBlock bb2, int i2 | + adjacentVarRefs(a, bb1, i1, bb2, i2) and + readAt(bb1, i1, read1, a) and + readAt(bb2, i2, read2, a) ) } - predicate ssaDefReachesEndOfBlock(PreBasicBlock bb, Definition def, SimpleLocalScopeVariable v) { - liveAtExit(bb, v) and - ( - exists(int last | - last = max(ssaRefRank(bb, _, v, _)) | - defReachesRank(bb, def, v, last) - ) - or - exists(PreBasicBlock idom | - idom.immediatelyDominates(bb) | - ssaDefReachesEndOfBlock(idom, def, v) and - not exists(ssaRefRank(bb, _, v, SsaDef())) - ) + pragma[noinline] + private predicate ssaDefReachesEndOfBlockRec(PreBasicBlock bb, Definition def, SimpleAssignable a) { + exists(PreBasicBlock idom | + ssaDefReachesEndOfBlock(idom, def, a) | + idom.immediatelyDominates(bb) ) } + + predicate ssaDefReachesEndOfBlock(PreBasicBlock bb, Definition def, SimpleAssignable a) { + exists(int last | + last = maxSsaRefRank(bb, a) | + defReachesRank(bb, def, a, last) and + liveAtExit(bb, a) + ) + or + ssaDefReachesEndOfBlockRec(bb, def, a) and + liveAtExit(bb, a) and + not ssaRef(bb, _, a, SsaDef()) + } } /** @@ -3453,11 +3520,11 @@ module ControlFlow { * and `cb` can be reached from `read` without passing through another * condition that reads the same SSA variable. */ - private predicate defConditionReachableFromRead(ConditionBlock cb, LocalScopeVariableRead read) { + private predicate defConditionReachableFromRead(ConditionBlock cb, AssignableRead read) { this.defCondition(cb) and read = cb.getLastElement() or - exists(LocalScopeVariableRead mid | + exists(AssignableRead mid | this.defConditionReachableFromRead(cb, mid) | adjacentReadPairSameVar(read, mid) and not this.defCondition(read) @@ -3470,7 +3537,7 @@ module ControlFlow { * another condition that reads the same SSA variable. */ private predicate firstDefCondition(ConditionBlock cb) { - exists(LocalScopeVariableRead read | + exists(AssignableRead read | this.defConditionReachableFromRead(cb, read) | firstReadSameVar(def, read) ) @@ -3478,7 +3545,7 @@ module ControlFlow { override predicate correlatesConditions(ConditionBlock cb1, ConditionBlock cb2, boolean inverted) { this.firstDefCondition(cb1) and - exists(LocalScopeVariableRead read1, LocalScopeVariableRead read2 | + exists(AssignableRead read1, AssignableRead read2 | read1 = cb1.getLastElement() and adjacentReadPairSameVar+(read1, read2) and read2 = cb2.getLastElement() and @@ -3487,11 +3554,11 @@ module ControlFlow { } override Callable getEnclosingCallable() { - result = def.getVariable().getCallable() + result = def.getCallable() } override string toString() { - result = def.getVariable().toString() + result = def.getAssignable().toString() } override Location getLocation() { @@ -3940,19 +4007,29 @@ module ControlFlow { private cached module Cached { private import semmle.code.csharp.controlflow.Guards as Guards + pragma[noinline] + private predicate phiNodeMaybeLive(PreBasicBlocks::PreBasicBlock bb, PreSsa::SimpleAssignable a) { + exists(PreBasicBlocks::PreBasicBlock def | + PreSsa::defAt(def, _, _, a) | + def.inDominanceFrontier(bb) + ) + } + cached newtype TPreSsaDef = - TExplicitPreSsaDef(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, LocalScopeVariable v) { + TExplicitPreSsaDef(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, PreSsa::SimpleAssignable a) { Guards::Internal::CachedWithCFG::forceCachingInSameStage() and - PreSsa::assignableDefAtLive(bb, i, def, v) + PreSsa::assignableDefAtLive(bb, i, def, a) } or - TPhiPreSsaDef(PreBasicBlocks::PreBasicBlock bb, LocalScopeVariable v) { - PreSsa::liveAtEntry(bb, v) and - exists(PreBasicBlocks::PreBasicBlock def | - def.inDominanceFrontier(bb) | - PreSsa::defAt(def, _, _, v) - ) + TImplicitEntryPreSsaDef(Callable c, PreBasicBlocks::PreBasicBlock bb, Assignable a) { + PreSsa::implicitEntryDef(c, bb, a) and + PreSsa::liveAtEntry(bb, a) + } + or + TPhiPreSsaDef(PreBasicBlocks::PreBasicBlock bb, PreSsa::SimpleAssignable a) { + phiNodeMaybeLive(bb, a) and + PreSsa::liveAtEntry(bb, a) } cached diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll index 863f46d8ca7..ae2f0654f45 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll @@ -283,6 +283,11 @@ module Ssa { ref(bb, i, v, k) } + private int maxRefRank(BasicBlock bb, SourceVariable v) { + result = refRank(bb, _, v, _) and + not result + 1 = refRank(bb, _, v, _) + } + /** * Gets the (1-based) rank of the first reference to `v` inside basic block `bb` * that is either a read or a certain write. @@ -335,7 +340,7 @@ module Ssa { predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk, ReadKind rk) { rnk = refRank(bb, i, v, _) and ( - rnk = max(refRank(bb, _, v, _)) and + rnk = maxRefRank(bb, v) and liveAtExit(bb, v, rk) or ref(bb, i, v, Read(rk)) @@ -641,6 +646,11 @@ module Ssa { ssaRef(bb, i, v, k) } + private int maxSsaRefRank(BasicBlock bb, SourceVariable v) { + result = ssaRefRank(bb, _, v, _) and + not result + 1 = ssaRefRank(bb, _, v, _) + } + /** * Holds if the non-trivial SSA definition `def` reaches rank index `rankix` * in its own basic block `bb`. @@ -734,7 +744,7 @@ module Ssa { rankix + 1 = ssaRefRank(bb2, i2, v, _) ) or - ssaRefRank(bb1, i1, v, _) = max(ssaRefRank(bb1, _, v, _)) and + ssaRefRank(bb1, i1, v, _) = maxSsaRefRank(bb1, v) and varBlockStep(v, bb1, bb2) and ssaRefRank(bb2, i2, v, _) = 1 } @@ -792,7 +802,7 @@ module Ssa { rnk + 1 = ssaRefRank(bb, _, v, SsaDef()) or // No next reference to `v` inside `bb` - rnk = max(ssaRefRank(bb, _, v, _)) and + rnk = maxSsaRefRank(bb, v) and ( // Read reaches end of enclosing callable not varBlockReaches(v, bb, _) @@ -806,6 +816,21 @@ module Ssa { ) } + pragma[noinline] + private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, TrackedDefinition def, TrackedVar v) { + exists(BasicBlock idom | + ssaDefReachesEndOfBlock(idom, def, v) | + /* The construction of SSA form ensures that each read of a variable is + * dominated by its definition. An SSA definition therefore reaches a + * control flow node if it is the _closest_ SSA definition that dominates + * the node. If two definitions dominate a node then one must dominate the + * other, so therefore the definition of _closest_ is given by the dominator + * tree. Thus, reaching definitions can be calculated in terms of dominance. + */ + idom = bb.getImmediateDominator() + ) + } + /** * Holds if the non-trivial SSA definition of `v` at `def` reaches the end of a * basic block `bb`, at which point it is still live, without crossing another @@ -813,26 +838,15 @@ module Ssa { */ cached predicate ssaDefReachesEndOfBlock(BasicBlock bb, TrackedDefinition def, TrackedVar v) { - liveAtExit(bb, v, _) and - ( - exists(int last | - last = max(ssaRefRank(bb, _, v, _)) | - ssaDefReachesRank(bb, def, last, v) - ) - or - exists(BasicBlock idom | - /* The construction of SSA form ensures that each read of a variable is - * dominated by its definition. An SSA definition therefore reaches a - * control flow node if it is the _closest_ SSA definition that dominates - * the node. If two definitions dominate a node then one must dominate the - * other, so therefore the definition of _closest_ is given by the dominator - * tree. Thus, reaching definitions can be calculated in terms of dominance. - */ - idom = bb.getImmediateDominator() and - ssaDefReachesEndOfBlock(idom, def, v) and - not exists(ssaRefRank(bb, _, v, SsaDef())) - ) + exists(int last | + last = maxSsaRefRank(bb, v) | + ssaDefReachesRank(bb, def, last, v) and + liveAtExit(bb, v, _) ) + or + ssaDefReachesEndOfBlockRec(bb, def, v) and + liveAtExit(bb, v, _) and + not ssaRef(bb, _, v, SsaDef()) } /** @@ -1896,14 +1910,18 @@ module Ssa { } or TPhiNode(TrackedVar v, ControlFlow::BasicBlocks::JoinBlock bb) { + phiNodeMaybeLive(bb, v) and liveAtEntry(bb, v, _) - and - exists(BasicBlock bb1, Definition def | - bb1.inDominanceFrontier(bb) and - definesAt(def, bb1, _, v) - ) } + pragma[noinline] + private predicate phiNodeMaybeLive(ControlFlow::BasicBlocks::JoinBlock bb, TrackedVar v) { + exists(Definition def, BasicBlock bb1 | + definesAt(def, bb1, _, v) | + bb1.inDominanceFrontier(bb) + ) + } + /** * Holds if the SSA definition `def` defines source variable `v` at index `i` * in basic block `bb`. Phi nodes and entry nodes (captured variables and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/BaseSSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/BaseSSA.qll index 9f005557d92..367358931b1 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/BaseSSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/BaseSSA.qll @@ -114,10 +114,9 @@ module BaseSsa { */ cached AssignableRead getARead(AssignableDefinition def, SimpleLocalScopeVariable v) { exists(BasicBlock bb, int i, int rnk | - result.getTarget() = v and result.getAControlFlowNode() = bb.getNode(i) and rnk = ssaRefRank(bb, i, v, SsaRead()) - | + | defReachesRank(bb, def, v, rnk) or reachesEndOf(def, v, bb.getAPredecessor()) and diff --git a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql index 23e74eb0c8f..dea9b67b059 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql +++ b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql @@ -2,12 +2,12 @@ import csharp import ControlFlow::Internal query -predicate defReadInconsistency(AssignableRead ar, Expr e, PreSsa::SimpleLocalScopeVariable v, boolean b) { +predicate defReadInconsistency(AssignableRead ar, Expr e, PreSsa::SimpleAssignable a, boolean b) { exists(AssignableDefinition def | e = def.getExpr() | b = true and exists(PreSsa::Definition ssaDef | - ssaDef.getVariable() = v | + ssaDef.getAssignable() = a | PreSsa::firstReadSameVar(ssaDef, ar) and ssaDef.getDefinition() = def and not exists(Ssa::ExplicitDefinition edef | @@ -20,7 +20,7 @@ predicate defReadInconsistency(AssignableRead ar, Expr e, PreSsa::SimpleLocalSco exists(Ssa::ExplicitDefinition edef | edef.getADefinition() = def and edef.getAFirstRead() = ar and - def.getTarget() = v and + def.getTarget() = a and not exists(PreSsa::Definition ssaDef | PreSsa::firstReadSameVar(ssaDef, ar) and ssaDef.getDefinition() = def @@ -30,26 +30,26 @@ predicate defReadInconsistency(AssignableRead ar, Expr e, PreSsa::SimpleLocalSco } query -predicate readReadInconsistency(LocalScopeVariableRead read1, LocalScopeVariableRead read2, PreSsa::SimpleLocalScopeVariable v, boolean b) { +predicate readReadInconsistency(LocalScopeVariableRead read1, LocalScopeVariableRead read2, PreSsa::SimpleAssignable a, boolean b) { b = true and - v = read1.getTarget() and + a = read1.getTarget() and PreSsa::adjacentReadPairSameVar(read1, read2) and not Ssa::Internal::adjacentReadPairSameVar(read1, read2) or b = false and - v = read1.getTarget() and + a = read1.getTarget() and Ssa::Internal::adjacentReadPairSameVar(read1, read2) and - read1.getTarget() instanceof PreSsa::SimpleLocalScopeVariable and + read1.getTarget() instanceof PreSsa::SimpleAssignable and not PreSsa::adjacentReadPairSameVar(read1, read2) } query -predicate phiInconsistency(ControlFlowElement cfe, Expr e, PreSsa::SimpleLocalScopeVariable v, boolean b) { +predicate phiInconsistency(ControlFlowElement cfe, Expr e, PreSsa::SimpleAssignable a, boolean b) { exists(AssignableDefinition adef | e = adef.getExpr() | b = true and exists(PreSsa::Definition def | - v = def.getVariable() | + a = def.getAssignable() | adef = def.getAPhiInput+().getDefinition() and cfe = def.getBasicBlock().getFirstElement() and not exists(Ssa::PhiNode phi, ControlFlow::BasicBlock bb, Ssa::ExplicitDefinition edef | @@ -62,7 +62,7 @@ predicate phiInconsistency(ControlFlowElement cfe, Expr e, PreSsa::SimpleLocalSc or b = false and exists(Ssa::PhiNode phi, ControlFlow::BasicBlock bb, Ssa::ExplicitDefinition edef | - v = phi.getSourceVariable().getAssignable() | + a = phi.getSourceVariable().getAssignable() | edef = phi.getAnUltimateDefinition() and edef.getADefinition() = adef and phi.definesAt(bb, _) and From e8f967a477181e8a665905f33c6db660628a200a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 Nov 2018 15:45:51 +0000 Subject: [PATCH 50/94] CPP: Add change notes for my recent changes. --- change-notes/1.19/analysis-cpp.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index f22f5dc638f..90cb71e6fc4 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -24,6 +24,10 @@ | Suspicious call to memset | Fewer false positive results | Types involving decltype are now correctly compared. | | Suspicious add with sizeof | Fewer false positive results | Arithmetic with void pointers (where allowed) is now excluded from this query. | | Wrong type of arguments to formatting function | Fewer false positive results | False positive results involving typedefs have been removed. Expected argument types are determined more accurately, especially for wide string and pointer types. Custom (non-standard) formatting functions are also identified more accurately. | +| Missing return statement | Fewer false positive results | Functions which make a non-returning function call are no longer expected to have a return statement after that call. | +| AV Rule 164 | Fewer false positive results | This query now accounts for explicit casts. | +| Negation of unsigned value | Fewer false positive results | This query now accounts for explicit casts. | +| Variable scope too large | Fewer false positive results | Variables with declarations in header files, or that are used at file scope, are now excluded from this query. | ## Changes to QL libraries From 7df7d8dd9e46fcb0be6f82aa706c412b2234ee85 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 Nov 2018 16:11:33 +0000 Subject: [PATCH 51/94] CPP: Add change notes for new query contributions. --- change-notes/1.19/analysis-cpp.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index 90cb71e6fc4..2c80e2464f7 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -10,6 +10,9 @@ | Setting a DACL to `NULL` in a `SECURITY_DESCRIPTOR` (`cpp/unsafe-dacl-security-descriptor`) | external/cwe/cwe-732 | This query finds code that creates world-writable objects on Windows by setting their DACL to `NULL`. Enabled by default. | | Cast from `char*` to `wchar_t*` | security, external/cwe/cwe-704 | Detects potentially dangerous casts from `char*` to `wchar_t*`. Enabled by default on LGTM. | | Dead code due to `goto` or `break` statement (`cpp/dead-code-goto`) | maintainability, external/cwe/cwe-561 | Detects dead code following a goto or break statement. Enabled by default on LGTM. | +| Inconsistent direction of for loop | correctness, external/cwe/cwe-835 | This query detects for loops where the increment and guard condition don't appear to correspond. Enabled by default on LGTM. | +| Incorrect Not Operator Usage | security, external/cwe/cwe-480 | This query finds uses of the logical not (!) operator that look like they should be bit-wise not (~). Available but not displayed by default on LGTM. | +| NULL application name with an unquoted path in call to CreateProcess | security, external/cwe/cwe-428 | This query finds unsafe uses of the CreateProcess function. Available but not displayed by default on LGTM. | ## Changes to existing queries From d8381ef4481a92bdd8c8747b673a2f78a30181e8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 Nov 2018 16:30:29 +0000 Subject: [PATCH 52/94] CPP: Add change notes for some more changes. --- change-notes/1.19/analysis-cpp.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index 2c80e2464f7..d8c2baa273e 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -31,6 +31,8 @@ | AV Rule 164 | Fewer false positive results | This query now accounts for explicit casts. | | Negation of unsigned value | Fewer false positive results | This query now accounts for explicit casts. | | Variable scope too large | Fewer false positive results | Variables with declarations in header files, or that are used at file scope, are now excluded from this query. | +| Comparison result is always the same | Fewer false positive results | Comparisons in template instantiations are now excluded from this query. | +| Unsigned comparison to zero | Fewer false positive results | Comparisons in template instantiations are now excluded from this query. | ## Changes to QL libraries From ae915812043ceec2e44cbf6bbc3f482ac35a47af Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 Nov 2018 16:52:36 +0000 Subject: [PATCH 53/94] CPP: Change note. --- change-notes/1.19/analysis-cpp.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index f22f5dc638f..c6e9051ccd8 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -17,6 +17,7 @@ |----------------------------|------------------------|------------------------------------------------------------------| | Empty branch of conditional | Fewer false positive results | The query now recognizes commented blocks more reliably. | | Expression has no effect | Fewer false positive results | Expressions in template instantiations are now excluded from this query. | +| Global could be static | Fewer false positive results | Variables with declarations in header files are now excluded from this query. | | Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. Also fixed an issue where false positives could occur if the destructor body was not in the snapshot. | | Missing return statement (`cpp/missing-return`) | Visible by default | The precision of this query has been increased from 'medium' to 'high', which makes it visible by default in LGTM. It was 'medium' in release 1.17 and 1.18 because it had false positives due to an extractor bug that was fixed in 1.18. | | Missing return statement | Fewer false positive results | The query is now produces correct results when a function returns a template-dependent type. | From 9922e365907f736fe7ba04314a7ba64a6e062322 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 Nov 2018 16:55:10 +0000 Subject: [PATCH 54/94] CPP: Add missing file. --- .../query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.h | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.h diff --git a/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.h b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.h new file mode 100644 index 00000000000..f446408efcf --- /dev/null +++ b/cpp/ql/test/query-tests/JPL_C/LOC-3/Rule 13/LimitedScopeFile/file1.h @@ -0,0 +1,3 @@ +// file1.h + +extern int globalInt3; From bb7da78c953d4a7ab6ab8084ebc08f914e2bb974 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 12 Nov 2018 18:05:28 +0000 Subject: [PATCH 55/94] CPP: Tag the JSF queries. --- cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql | 1 + cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql | 3 +++ cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql | 3 ++- cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql | 2 ++ cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql | 2 ++ cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql | 2 ++ cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql | 2 ++ cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql | 2 ++ cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql | 3 +++ cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql | 2 ++ cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql | 2 ++ cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql | 2 ++ cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql | 3 ++- cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql | 2 ++ cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql | 2 ++ cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql | 1 + cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql | 2 ++ cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql | 1 + cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql | 2 ++ cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql | 3 ++- cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql | 2 ++ cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql | 4 +++- cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql | 4 +++- cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql | 4 +++- cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql | 3 ++- cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql | 2 ++ cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql | 4 +++- cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql | 3 ++- cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql | 2 ++ cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql | 3 ++- cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql | 3 ++- cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql | 3 ++- cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql | 4 +++- cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql | 3 ++- cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql | 4 +++- .../src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql | 3 ++- .../src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql | 3 ++- .../src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql | 3 ++- cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql | 1 + cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql | 1 + cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql | 3 ++- cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql | 3 ++- cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql | 3 ++- cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql | 4 +++- cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql | 3 ++- cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql | 5 +++-- cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql | 1 + cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql | 4 +++- cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql | 4 +++- cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql | 4 +++- cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql | 3 ++- cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql | 4 +++- cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql | 3 ++- cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql | 3 ++- cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql | 2 ++ cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql | 4 +++- cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql | 4 +++- cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql | 4 +++- cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql | 1 + cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql | 1 + cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql | 3 ++- cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql | 2 ++ cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql | 3 ++- cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql | 2 ++ cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql | 2 ++ cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql | 3 ++- cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql | 3 ++- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql | 4 +++- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql | 2 ++ cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql | 3 ++- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql | 3 ++- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql | 3 ++- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql | 4 +++- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql | 3 ++- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql | 2 ++ cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql | 4 ++-- cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql | 2 ++ cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql | 2 ++ cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql | 1 + cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql | 1 + cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql | 1 + cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql | 4 +++- cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql | 3 ++- cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql | 3 ++- cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql | 2 ++ cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql | 3 ++- cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql | 4 +++- cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql | 2 ++ cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql | 2 ++ cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql | 4 +++- cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql | 1 + cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql | 2 ++ 135 files changed, 276 insertions(+), 76 deletions(-) diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql index 5d7c1324319..fab1c721b02 100644 --- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql +++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-1 * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql index 81441a548fc..791d87bb7cc 100644 --- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql +++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql @@ -4,6 +4,9 @@ * @kind problem * @id cpp/jsf/av-rule-2 * @problem.severity error + * @tags maintainability + * readability + * testability */ import cpp diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql index 41aea8836d7..c7a48b44627 100644 --- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql +++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql @@ -3,7 +3,8 @@ * @description All functions shall have a cyclomatic complexity number of 20 or less. * @kind problem * @id cpp/jsf/av-rule-3 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql index c7ff2e29cd5..7fd2403c386 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-11 * @problem.severity warning + * @tags maintainability + * readability */ import cpp import external.ExternalArtifact diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql index 704a605f7ad..2c750112214 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-12 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql index 1eeb9f0ef3e..595d4b6d8a9 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-13 * @problem.severity error + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql index f9da62380f6..8c88085eafe 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-14 * @problem.severity error + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql index 5ac20cfc5a6..ac40ee176d5 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-9 * @problem.severity warning + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql index 30a36d0ad96..675ba0e5c52 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-17 * @problem.severity error + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql index 8045b2bb604..62b570a6227 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-18 * @problem.severity error + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql index ea4885b13a3..079bd13c041 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-19 * @problem.severity error + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql index f5658511c13..f76574ef9bb 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql @@ -4,6 +4,9 @@ * @kind problem * @id cpp/jsf/av-rule-20 * @problem.severity error + * @tags correctness + * portability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql index 388a717eebb..c19a028876e 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-21 * @problem.severity error + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql index 4a8f075a7bd..c1d4e563fae 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-22 * @problem.severity error + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql index 62b3b4c6539..c0e4401a04e 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-23 * @problem.severity error + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql index 1cec97180f7..c50af2955a7 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql @@ -4,7 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-24 * @problem.severity warning - * @tags portability + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql index 659afa17cf4..1ef9928d328 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-25 * @problem.severity error + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql index 095b7ecb80a..33b77c389b3 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-26 * @problem.severity error + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql index 43b483caa48..7c552e450f3 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-27 * @problem.severity warning + * @tags maintainability + * portability */ import cpp import semmle.code.cpp.headers.MultipleInclusion diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql index 8b044fdfc0e..c7896fcbda6 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-28 * @problem.severity warning + * @tags maintainability */ import cpp import semmle.code.cpp.headers.MultipleInclusion diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql index c6229e118b6..1f632fd73c3 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-29 * @problem.severity error + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql index dff8e58367b..6f2809e0815 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-30 * @problem.severity error + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql index 74b5eb9697b..7632ac5e780 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-31 * @problem.severity warning + * @tags maintainability */ import cpp import semmle.code.cpp.headers.MultipleInclusion diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql index 9dd2e5bfc22..77b150be817 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql @@ -7,6 +7,7 @@ * @id cpp/include-non-header * @tags maintainability * modularity + * readability */ import cpp import semmle.code.cpp.AutogeneratedFile diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql index bdf802a85f7..d4eeab687eb 100644 --- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql +++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-33 * @problem.severity error + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql index 4a38b3807b6..f546daf81ab 100644 --- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql +++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-39 * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql b/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql index fbc24554547..bd282b9212a 100644 --- a/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql +++ b/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-40 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql index e3f6ce995c1..9ebcc1159fe 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql @@ -3,7 +3,9 @@ * @description Source lines will be kept to a length of 120 characters or less. * @kind problem * @id cpp/jsf/av-rule-41 - * @problem.severity warning + * @problem.severity warrecommendationning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql index 170ed0a4458..fb7627a0452 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql @@ -3,7 +3,9 @@ * @description Each expression-statement will be on a separate line. * @kind problem * @id cpp/jsf/av-rule-42 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql index c2094226871..75e078049a7 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-43 * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql index 7b842e4edd7..8a9bffde46f 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql @@ -3,7 +3,9 @@ * @description All indentations will be at least two spaces and be consistent within the same source file. * @kind problem * @id cpp/jsf/av-rule-44 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql index 79bdad085b8..db0fbeacb80 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql @@ -3,7 +3,9 @@ * @description All words in an identifier will be separated by the underscore character. * @kind problem * @id cpp/jsf/av-rule-45 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql index 4511cbfe1f0..156f60889a3 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql @@ -3,7 +3,9 @@ * @description User-specified identifiers (internal and external) will not rely on significance of more than 64 characters. * @kind problem * @id cpp/jsf/av-rule-46 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql index 49255f8347f..032bafcf396 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql @@ -3,7 +3,8 @@ * @description Identifiers will not begin with the underscore character. * @kind problem * @id cpp/jsf/av-rule-47 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql index 890245aafcd..e64343c273e 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-48 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql index 68301d12c27..e530b6ffd1c 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql @@ -3,7 +3,9 @@ * @description All acronyms in an identifier will be composed of uppercase letters. * @kind problem * @id cpp/jsf/av-rule-49 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql index 5ead6fe0236..ed8acf12332 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql @@ -3,7 +3,9 @@ * @description The first word of the name of a class, structure, namespace, enumeration, or type created with typedef will begin with an uppercase letter. All other letters will be lowercase. * @kind problem * @id cpp/jsf/av-rule-50 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql index 346e9c3ee4c..ff97a8480b1 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql @@ -3,7 +3,9 @@ * @description All letters contained in function and variable names will be lowercase. * @kind problem * @id cpp/jsf/av-rule-51 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql index 93218392e92..08f7185e4a2 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql @@ -3,7 +3,9 @@ * @description Identifiers for constant and enumerator values shall be lowercase. * @kind problem * @id cpp/jsf/av-rule-52 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql index 77953c40c6d..fb2f47e5d14 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql @@ -3,7 +3,9 @@ * @description The following character sequences shall not appear in header file names: ', \, /*, //, or ". * @kind problem * @id cpp/jsf/av-rule-53-1 - * @problem.severity error + * @problem.severity warning + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql index 862d9028de3..942543331a6 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql @@ -3,7 +3,9 @@ * @description Header files will always have a file name extension of .h. * @kind problem * @id cpp/jsf/av-rule-53 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql index cb40d30d51d..6c504484558 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql @@ -3,7 +3,9 @@ * @description Implementation files will always have a file name extension of .cpp. * @kind problem * @id cpp/jsf/av-rule-54 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql index 2c205cc009f..120afa5f758 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql @@ -3,7 +3,9 @@ * @description The public, protected, and private sections of a class will be declared in that order. * @kind problem * @id cpp/jsf/av-rule-57 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql index 08a6e2c81b3..48970a4f867 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql @@ -3,7 +3,9 @@ * @description When declaring and defining functions with more than two parameters, the leading parenthesis and the first argument will be written on the same line as the function name. Each additional argument will be written on a separate line (with the closing parenthesis directly after the last argument). * @kind problem * @id cpp/jsf/av-rule-58 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql index ca598d20b2e..c78f1f24ebb 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql @@ -3,7 +3,9 @@ * @description The statements forming the body of an if, else if, else, while, do-while or for statement shall always be enclosed in braces, even if the braces form an empty block. * @kind problem * @id cpp/jsf/av-rule-59 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql index 206eb7c5d99..57544aa161e 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql @@ -3,7 +3,9 @@ * @description Braces which enclose a block will be placed in the same column, on separate lines directly before and after the block. * @kind problem * @id cpp/jsf/av-rule-60 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql index e31e844a3a5..e45209e0c33 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql @@ -3,7 +3,9 @@ * @description Braces which enclose a block will have nothing else on the line except comments (if necessary). * @kind problem * @id cpp/jsf/av-rule-61 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql index 2f65ce9ec83..03ebd2e2ef8 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql @@ -3,7 +3,9 @@ * @description Spaces will not be used around '.' or '->', nor between unary operators and operands. * @kind problem * @id cpp/jsf/av-rule-63 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql index 1ef9a49bb23..7758023b8e3 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql @@ -3,7 +3,8 @@ * @description Unneeded implicitly generated member functions shall be explicitly disallowed. * @kind problem * @id cpp/jsf/av-rule-68 - * @problem.severity error + * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql index 1daec9c9cec..4e3b2edd792 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-69 * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql index af544ae4610..ea3fd973ffb 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql @@ -5,7 +5,8 @@ * for logical or efficiency reasons. * @kind problem * @id cpp/jsf/av-rule-70 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql index 8a1cc05eb72..122bfa69049 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-71 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql index 2cce8b26646..44f83745353 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql @@ -3,8 +3,9 @@ * @description Unnecessary default constructors shall not be defined. * @kind problem * @id cpp/jsf/av-rule-73 - * @problem.severity error + * @problem.severity recommendation * @precision low + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql index 7828fc02849..a18be35c1e4 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql @@ -6,6 +6,7 @@ * @kind problem * @id cpp/jsf/av-rule-74 * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql index ba78dec6486..377df558fe0 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql @@ -3,7 +3,9 @@ * @description Members of the initialization list shall be listed in the order in which they are declared in the class. * @kind problem * @id cpp/jsf/av-rule-75 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql index 9ab2a892b65..bd8a777b513 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql @@ -3,7 +3,8 @@ * @description A copy constructor and an assignment operator shall be declared for classes that contain pointers to data items or nontrivial destructors. If the copy constructor and assignment operators are not required, they should be explicitly disallowed. * @kind problem * @id cpp/jsf/av-rule-76 - * @problem.severity error + * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql index a6bba73ebd4..768bde73a34 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-81 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql index 690dd9479d2..f8aa362d1f3 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql @@ -4,7 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-85 * @problem.severity warning - * @tags reliability + * @tags maintainability + * reliability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql index a96697f1e5c..13ab88db879 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql @@ -3,7 +3,8 @@ * @description A stateful virtual base shall be explicitly declared in each derived class that accesses it. Explicitly declaring a stateful virtual base at each level in a hierarchy (where that base is used), documents that fact that no assumptions can be made with respect to the exclusive use of the data contained within the virtual base. * @kind problem * @id cpp/jsf/av-rule-88-1 - * @problem.severity error + * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql index 0bc3b17177b..69d5233c4f9 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql @@ -5,7 +5,8 @@ * @problem.severity recommendation * @precision high * @id cpp/undisciplined-multiple-inheritance - * @tags readability + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql index 1bf0465486a..0f1c2540cea 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql @@ -3,7 +3,8 @@ * @description An inherited nonvirtual function shall not be redefined in a derived class. Such definitions would hide the function in the base class. * @kind problem * @id cpp/jsf/av-rule-94 - * @problem.severity error + * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql index d577b649df8..5a10f410625 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-96 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql index 455add085d5..abff8370513 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-97-1 * @problem.severity error + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql b/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql index 920853145fc..7d7687d0d68 100644 --- a/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql +++ b/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql @@ -3,7 +3,9 @@ * @description Namespaces will not be nested more than two levels deep * @kind problem * @id cpp/jsf/av-rule-99 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql b/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql index 2c4037770ba..422b7020c9c 100644 --- a/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql +++ b/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-104 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql index 1ece9be6fe8..19316a81edb 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql @@ -3,7 +3,8 @@ * @description Functions with variable number of arguments shall not be used. * @kind problem * @id cpp/jsf/av-rule-108 - * @problem.severity error + * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql index 16e24b9697b..dd481542d6f 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-110 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql index edc3f8c646d..b4441527d0d 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql @@ -4,7 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-111 * @problem.severity error - * @tags reliability + * @tags correctness + * reliability */ import semmle.code.cpp.pointsto.PointsTo diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql index 938e8b3a81e..a9aba53e203 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql @@ -3,7 +3,8 @@ * @description Functions will have a single exit point. * @kind problem * @id cpp/jsf/av-rule-113 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql index af81266e1d8..a4ba5820cb8 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-115 * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql index e45afd24880..bae02940f6b 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql @@ -3,7 +3,8 @@ * @description Functions shall not call themselves, either directly or indirectly (i.e. recursion shall not be allowed). * @kind problem * @id cpp/jsf/av-rule-119 - * @problem.severity error + * @problem.severity recommendation + * @tags resources */ import cpp diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql index 975489f30f2..b40c73899ca 100644 --- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql +++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql @@ -3,7 +3,9 @@ * @description Only valid C++ style comments shall be used. * @kind problem * @id cpp/jsf/av-rule-126 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * documentation */ import cpp diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql index e8dfa01e54d..30bd4c8ed3b 100644 --- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql +++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql @@ -3,7 +3,8 @@ * @description Code that is not used (commented out) shall be deleted. * @kind problem * @id cpp/jsf/av-rule-127 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql index 6de8e990e3e..54d71e0cf19 100644 --- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql +++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql @@ -3,7 +3,9 @@ * @description Every source file will be documented with an introductory comment that provides information on the file name, its contents, and any program-required information (eg. legal statements, copyright information, etc) * @kind problem * @id cpp/jsf/av-rule-133 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability + * documentation */ import cpp diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql index 0a6744aed2c..c720257228c 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql @@ -3,7 +3,8 @@ * @description Identifiers shall not simultaneously have both internal and external linkage in the same translation unit. * @kind problem * @id cpp/jsf/av-rule-138 - * @problem.severity error + * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql index 1d8a8849ac1..2eb21d117bc 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql @@ -1,9 +1,10 @@ /** * @name AV Rule 139 - * @description External objects will not be declared in more than one file + * @description External objects will not be declared in more than one file. * @kind problem * @id cpp/jsf/av-rule-139 * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql index 7a0e6f58661..cc54a8f113e 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql @@ -4,7 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-140 * @problem.severity warning - * @tags portability + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql index 570a3566d4a..6600caeb2a1 100644 --- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql +++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-142 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql index 595b414ee9b..272b78b0c5a 100644 --- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql +++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-143 * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql index d09fd2de3dc..fc727da9491 100644 --- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql +++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql @@ -3,7 +3,8 @@ * @description Octal constants (other than zero) shall not be used. * @kind problem * @id cpp/jsf/av-rule-149 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql index 542d241721a..8ddad3dfcbe 100644 --- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql +++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql @@ -3,7 +3,8 @@ * @description Hexadecimal constants will be represented using all uppercase letters. * @kind problem * @id cpp/jsf/av-rule-150 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql index e4dad7e2e00..7edf379ada2 100644 --- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql +++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql @@ -3,7 +3,8 @@ * @description Numeric values in code will not be used; symbolic values will be used instead. * @kind problem * @id cpp/jsf/av-rule-151 - * @problem.severity warning + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql b/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql index d57a9eb79b0..f662d04b5ea 100644 --- a/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql +++ b/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql @@ -3,7 +3,9 @@ * @description Multiple variable declarations shall not be allowed on the same line. * @kind problem * @id cpp/jsf/av-rule-152 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql index 7f0298c3558..06c90e12c47 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql @@ -3,7 +3,8 @@ * @description Unions shall not be used. * @kind problem * @id cpp/jsf/av-rule-153 - * @problem.severity error + * @problem.severity recommendation + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql index 247a38130b5..d07c0533251 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql @@ -6,8 +6,9 @@ * @problem.severity warning * @precision low * @id cpp/signed-bit-field - * @tags reliability - * readability + * @tags correctness + * portability + * reliability * language-features * external/cwe/cwe-190 */ diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql index ba48fe3539a..b2415434305 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-155 * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql index 2dcabc93098..d1b3127d85c 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql @@ -4,7 +4,9 @@ * and shall only be accessed via their names. * @kind problem * @id cpp/jsf/av-rule-156 - * @problem.severity error + * @problem.severity warning + * @precision low + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql index 18cbc5118a1..a4fec0bae4e 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql @@ -4,7 +4,9 @@ * contain side effects. * @kind problem * @id cpp/jsf/av-rule-157 - * @problem.severity error + * @problem.severity warning + * @tags correctness + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql index 6063f45073d..b2c61ce72a4 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql @@ -4,7 +4,9 @@ * if the operands contain binary operators. * @kind problem * @id cpp/jsf/av-rule-158 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql index ae3350aeece..12989b012b0 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql @@ -3,7 +3,8 @@ * @description Operators ||, &&, and unary & shall not be overloaded * @kind problem * @id cpp/jsf/av-rule-159 - * @problem.severity error + * @problem.severity warning + * @tags correctness */ // See More Effective C++ item 7 // Note: Meyers allows unary & to be overloaded but not comma diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql index e34673b9070..45057d79049 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql @@ -3,7 +3,9 @@ * @description An assignment expression shall be used only as the expression in an expression statement. * @kind problem * @id cpp/jsf/av-rule-160 - * @problem.severity error + * @problem.severity warning + * @tags correctness + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql index e9f1fa4f08f..79b66cb180a 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql @@ -3,7 +3,8 @@ * @description Signed and unsigned values shall not be mixed in arithmetic or comparison operations. Mixing signed and unsigned values is error prone as it subjects operations to numerous arithmetic conversion and integral promotion rules. * @kind problem * @id cpp/jsf/av-rule-162 - * @problem.severity error + * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql index d8a5a8930a9..9deedac050d 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql @@ -3,7 +3,8 @@ * @description Unsigned arithmetic shall not be used. * @kind problem * @id cpp/jsf/av-rule-163 - * @problem.severity error + * @problem.severity recommendation + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql index 714c7d6c4de..c8ae3f140b9 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-164 * @problem.severity error + * @precision low + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql index e657be1844e..8b4aecc16ce 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql @@ -4,7 +4,9 @@ * @kind problem * @id cpp/jsf/av-rule-165 * @problem.severity warning - * @tags reliability + * @precision low + * @tags correctness + * reliability */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql index 6a47217fd1a..d5cf369a1d3 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql @@ -3,7 +3,9 @@ * @description The comma operator shall not be used. * @kind problem * @id cpp/jsf/av-rule-168 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql index 1cd0a5a5a68..e850f2299b2 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql @@ -3,7 +3,9 @@ * @description More than two levels of pointer indirection shall not be used. * @kind problem * @id cpp/jsf/av-rule-170 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql index a5a282bd280..90a493941d7 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-171 * @problem.severity error + * @tags correctness */ import cpp import semmle.code.cpp.pointsto.PointsTo diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql index 9bbc4f56388..23c0d8488e1 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql @@ -6,6 +6,7 @@ * @kind problem * @id cpp/jsf/av-rule-173 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql index b9b19ca1236..916c7fe9e3c 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql @@ -3,7 +3,8 @@ * @description A pointer shall not be compared to NULL or be assigned NULL; use plain 0 instead. * @kind problem * @id cpp/jsf/av-rule-175 - * @problem.severity error + * @problem.severity recommendation + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql index 3b3369dff21..1dd8cb4032a 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-176 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql index 62bb5ac7207..49bc12294b3 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-178 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql index 007f6c9c80a..79c326e28ae 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-179 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql index 7f3ecd38c99..e5752cd31d5 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql @@ -4,7 +4,8 @@ * shall not be used. * @kind problem * @id cpp/jsf/av-rule-180 - * @problem.severity error + * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql index cd32f6f4208..854ef0b9ad1 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-181 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql index 0e5a345c198..29810473da8 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-182 * @problem.severity error + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql index b72c3803f06..c17979295ab 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql @@ -5,7 +5,8 @@ * requirement or is necessary for a hardware interface. * @kind problem * @id cpp/jsf/av-rule-184 - * @problem.severity error + * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql index 5a276d498c7..96a729b24dd 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql @@ -4,7 +4,8 @@ * instead of the traditional C-style cast. * @kind problem * @id cpp/jsf/av-rule-185 - * @problem.severity error + * @problem.severity recommendation + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql index 2ee5c35140a..f25145800d1 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql @@ -3,7 +3,9 @@ * @description There shall be no unreachable code. * @kind problem * @id cpp/jsf/av-rule-186 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * useless-code */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql index 6033c421a4f..76757ea98de 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-187 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql index f01c15a9a0e..143fca84ced 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-188 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql index fbf0a1b0b11..606bbebc701 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql @@ -3,8 +3,9 @@ * @description The goto statement shall not be used. * @kind problem * @id cpp/jsf/av-rule-189 - * @problem.severity error + * @problem.severity warning * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql index 8e794081c2e..e34056e25dd 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql @@ -3,7 +3,8 @@ * @description The continue statement shall not be used. * @kind problem * @id cpp/jsf/av-rule-190 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql index 866dbcd2a22..615a5d1bb7f 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql @@ -3,7 +3,8 @@ * @description The break statement shall not be used. * @kind problem * @id cpp/jsf/av-rule-191 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql index 8553d0a005a..a418dc58ab0 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-192 * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql index 6e589bb0fab..72cd0a7f646 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql @@ -4,7 +4,9 @@ * shall be terminated with a break statement. * @kind problem * @id cpp/jsf/av-rule-193 - * @problem.severity error + * @problem.severity warning + * @tags correctness + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql index 4aa98eb85e6..871a4799279 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql @@ -3,7 +3,8 @@ * @description All switch statements that do not intend to test for every enumeration value shall contain a final default clause. * @kind problem * @id cpp/jsf/av-rule-194 - * @problem.severity error + * @problem.severity warning + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql index 8a8fa4b58e5..b3fb2ab035c 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-195 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql index 37fc05b5833..d1993af58ca 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql @@ -5,8 +5,8 @@ * @problem.severity recommendation * @precision high * @id cpp/loop-variable-float - * @tags reliability - * readability + * @tags correctness + * reliability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql index 9b973d40264..6d8c0d8e288 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql @@ -5,6 +5,8 @@ * @kind problem * @id cpp/jsf/av-rule-198 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql index 258a6c1e2bf..e6c6c9a4ab9 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql @@ -5,6 +5,8 @@ * @kind problem * @id cpp/jsf/av-rule-199 * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql index cbabf485265..cddb2573aaa 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-200 * @problem.severity warning + * @tags maintainability */ import cpp diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql index 352993f2c17..f97000ed9c2 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-202 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql index d1c53d781ed..9ed07f073ad 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql @@ -4,6 +4,7 @@ * @kind problem * @id cpp/jsf/av-rule-204-1 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql index d2bf1728a76..f76505c021e 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql @@ -6,7 +6,9 @@ * condition, or as a part of a chained operation. * @kind problem * @id cpp/jsf/av-rule-204 - * @problem.severity error + * @problem.severity warning + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql index a269959daa2..2d74a1aaa9e 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql @@ -3,7 +3,8 @@ * @description The volatile keyword shall not be used unless directly interfacing with hardware. * @kind problem * @id cpp/jsf/av-rule-205 - * @problem.severity error + * @problem.severity warning + * @tags efficiency */ import cpp diff --git a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql index 30254488556..ad73ea336e4 100644 --- a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql +++ b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql @@ -4,7 +4,8 @@ * occur after initialization. * @kind problem * @id cpp/jsf/av-rule-206 - * @problem.severity error + * @problem.severity recommendation + * @tags resources */ import cpp diff --git a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql index 6628234ff0c..51d5ec8a38b 100644 --- a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql +++ b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-207 * @problem.severity warning + * @tags maintainability + * modularity */ import cpp diff --git a/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql b/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql index 172f8db58a8..11fbe9de13c 100644 --- a/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql +++ b/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql @@ -3,7 +3,8 @@ * @description C++ exceptions shall not be used. * @kind problem * @id cpp/jsf/av-rule-208 - * @problem.severity error + * @problem.severity recommendation + * @tags language-features */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql index 991026f4fa6..f2ea9349340 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql @@ -5,7 +5,9 @@ * each compiler, and these type names used in the code. * @kind problem * @id cpp/jsf/av-rule-209 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql index c8fb016284d..96ff35d1a2a 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql @@ -6,6 +6,8 @@ * @id cpp/jsf/av-rule-210 * @problem.severity error * @precision low + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql index 5a05826fa19..32092820bce 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql @@ -5,6 +5,8 @@ * @kind problem * @id cpp/jsf/av-rule-212 * @problem.severity error + * @tags correctness + * portability */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql index 7cdcc1e9e24..8b6d139eb05 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql @@ -4,7 +4,9 @@ * below arithmetic operators, in expressions. * @kind problem * @id cpp/jsf/av-rule-213 - * @problem.severity error + * @problem.severity recommendation + * @tags maintainability + * readability */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql index 9b873f8e716..41cb239ee74 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql @@ -5,6 +5,7 @@ * @kind problem * @id cpp/jsf/av-rule-214 * @problem.severity error + * @tags correctness */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql index 201ea073fd9..48e8398c208 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql @@ -4,6 +4,8 @@ * @kind problem * @id cpp/jsf/av-rule-215 * @problem.severity warning + * @tags correctness + * language-features */ import cpp From 8aeaf0bc8e212e823fb7fd245be158f08ac32121 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 14 Nov 2018 15:54:28 +0000 Subject: [PATCH 56/94] CPP: Add an external/jsf tag as well. --- cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql | 1 + cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql | 1 + cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql | 1 + cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql | 1 + cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql | 1 + cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql | 1 + cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql | 1 + cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql | 1 + cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql | 1 + cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql | 1 + cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql | 1 + cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql | 1 + cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql | 1 + cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql | 1 + cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql | 1 + cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql | 1 + cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql | 1 + cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql | 1 + cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql | 1 + cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql | 1 + cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql | 1 + cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql | 1 + cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql | 1 + cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql | 1 + cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql | 1 + cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql | 1 + cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql | 1 + cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql | 1 + cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql | 1 + cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql | 1 + cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql | 1 + cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql | 1 + cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql | 1 + cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql | 1 + cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql | 1 + cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql | 1 + cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql | 1 + cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql | 1 + cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql | 1 + cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql | 1 + cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql | 1 + cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql | 1 + cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql | 1 + cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql | 1 + cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql | 1 + cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql | 1 + cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql | 1 + cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql | 1 + cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql | 1 + cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql | 1 + cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql | 1 + cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql | 1 + cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql | 1 + cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql | 1 + cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql | 1 + cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql | 1 + cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql | 1 + cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql | 1 + cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql | 1 + cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql | 1 + cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql | 1 + 154 files changed, 154 insertions(+) diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql index fab1c721b02..e4f6524ae5f 100644 --- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql +++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-1 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql index 791d87bb7cc..cf1b952e17c 100644 --- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql +++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql @@ -7,6 +7,7 @@ * @tags maintainability * readability * testability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql index c7a48b44627..60f8cf8616f 100644 --- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql +++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-3 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql index 7fd2403c386..ac46a454101 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp import external.ExternalArtifact diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql index 2c750112214..b3460c5bc5f 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql index 595d4b6d8a9..6d03cd712aa 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags maintainability * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql index 8c88085eafe..792383baf77 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql index ac40ee176d5..9df1b72a736 100644 --- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql +++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql index 675ba0e5c52..520cb67a622 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-17 * @problem.severity error * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql index 62b570a6227..a9eeb2e6639 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-18 * @problem.severity error * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql index 079bd13c041..414ba2e969f 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-19 * @problem.severity error * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql index f76574ef9bb..fed2482a56c 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql @@ -7,6 +7,7 @@ * @tags correctness * portability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql index c19a028876e..8d3ed394737 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql index c1d4e563fae..8a1cb164e93 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags maintainability * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql index c0e4401a04e..1c0c84c7cdd 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql index c50af2955a7..42e456e3dd6 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql index 1ef9928d328..09df5fa8b56 100644 --- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql +++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql index 33b77c389b3..9561f452cd3 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-26 * @problem.severity error * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql index 7c552e450f3..1aed7ddab59 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * portability + * external/jsf */ import cpp import semmle.code.cpp.headers.MultipleInclusion diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql index c7896fcbda6..9d22ab3c340 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-28 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp import semmle.code.cpp.headers.MultipleInclusion diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql index 1f632fd73c3..f3dc2a2e87f 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-29 * @problem.severity error * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql index 6f2809e0815..ceedac6112f 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-30 * @problem.severity error * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql index 7632ac5e780..9c8f389cf3f 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-31 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp import semmle.code.cpp.headers.MultipleInclusion diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql index 77b150be817..59fef7909e0 100644 --- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql +++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql @@ -8,6 +8,7 @@ * @tags maintainability * modularity * readability + * external/jsf */ import cpp import semmle.code.cpp.AutogeneratedFile diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql index d4eeab687eb..2b416c4ce21 100644 --- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql +++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags maintainability * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql index 1f1ddef6a9c..b3b9dc19a95 100644 --- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql +++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql @@ -10,6 +10,7 @@ * @tags efficiency * maintainability * modularity + * external/jsf */ import cpp import semmle.code.cpp.headers.MultipleInclusion diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql index f546daf81ab..0bf35a35f17 100644 --- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql +++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-39 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql b/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql index bd282b9212a..9ca933383df 100644 --- a/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql +++ b/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-40 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql index 9ebcc1159fe..35799e26b04 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql @@ -6,6 +6,7 @@ * @problem.severity warrecommendationning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql index fb7627a0452..e7058321347 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql index 75e078049a7..ef9d5fbd748 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql index 8a9bffde46f..540434cb718 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql index db0fbeacb80..b022760d806 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql index 156f60889a3..841b32df310 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql index 032bafcf396..fb36adf66a9 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-47 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql index e64343c273e..1a900733330 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql index e530b6ffd1c..e422ee217fe 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql index ed8acf12332..ca45954eeb6 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql index ff97a8480b1..e6fe9828e88 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql index 08f7185e4a2..3c1d3631843 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp import Naming diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql index fb2f47e5d14..d70e7ff48bc 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql index 942543331a6..b5f2d223951 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql index 6c504484558..d7f10a88e57 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql index 120afa5f758..fe629ce5a4c 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql index 48970a4f867..80b6ec08004 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql index c78f1f24ebb..6baf82e3b32 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql index 57544aa161e..c1b2729aec2 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql index e45209e0c33..feee51df3de 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql index 03ebd2e2ef8..4fa3ac5b8f0 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql index 7758023b8e3..bfe52e65a65 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-68 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql index 4e3b2edd792..3f9b23311aa 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-69 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql index ea3fd973ffb..1e08577217d 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql @@ -7,6 +7,7 @@ * @id cpp/jsf/av-rule-70 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql index 354c165a5e9..01a6195c88e 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql @@ -8,6 +8,7 @@ * @tags reliability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql index 122bfa69049..2b0159e6452 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-71 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql index 44f83745353..4d7025d38a5 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @precision low * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql index a18be35c1e4..d0ec52033c1 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql @@ -7,6 +7,7 @@ * @id cpp/jsf/av-rule-74 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql index 377df558fe0..c16f09dbb93 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql index bd8a777b513..b065b75aed3 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-76 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql index c268d3c4f7f..0b847e795c6 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql @@ -8,6 +8,7 @@ * @tags reliability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql index 04a69db8ddd..fa2edce92d4 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql @@ -8,6 +8,7 @@ * @tags reliability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql index 6ad499a8337..1b2f4080992 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql @@ -8,6 +8,7 @@ * @tags efficiency * readability * external/cwe/cwe-404 + * external/jsf */ import cpp import Critical.NewDelete diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql index 768bde73a34..c16da4309a5 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-81 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql index 47d95e14eca..4624cd29931 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql @@ -8,6 +8,7 @@ * @tags reliability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql index f8aa362d1f3..fcab5ac5cd8 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * reliability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql index 13ab88db879..90efc3cba0f 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-88-1 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql index 69d5233c4f9..bbd39779744 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql @@ -7,6 +7,7 @@ * @id cpp/undisciplined-multiple-inheritance * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql index 7e39363e838..53d6b95b011 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql @@ -7,6 +7,7 @@ * @id cpp/inconsistent-virtual-inheritance * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql index 0f1c2540cea..68b6c7fd506 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-94 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql index a43c7b56a3b..f32fe58f0be 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql @@ -7,6 +7,7 @@ * @id cpp/redefined-default-parameter * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql index 5a10f410625..839625f4d2c 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-96 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql index abff8370513..02d0f169245 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql index 256b1174ccb..781e3c922d3 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql @@ -8,6 +8,7 @@ * @tags reliability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql b/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql index 7d7687d0d68..4d4713026f1 100644 --- a/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql +++ b/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql b/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql index 422b7020c9c..a88a8f165e9 100644 --- a/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql +++ b/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-104 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql index 22341330150..a92a3d268f8 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql @@ -7,6 +7,7 @@ * @id cpp/function-in-block * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql index 19316a81edb..b463e51afa7 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-108 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql index dd481542d6f..9afa55ee4ca 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql index b4441527d0d..6e6d8004a1c 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags correctness * reliability + * external/jsf */ import semmle.code.cpp.pointsto.PointsTo diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql index a9aba53e203..ca934aa84e1 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-113 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql index 600d4a6abf0..dc44cef9bca 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql @@ -8,6 +8,7 @@ * @tags reliability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql index a4ba5820cb8..2cec08f027b 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-115 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql index bae02940f6b..3e365d28ddf 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-119 * @problem.severity recommendation * @tags resources + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql index b40c73899ca..bc0a6a4be1d 100644 --- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql +++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * documentation + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql index 30bd4c8ed3b..663efcc5bcd 100644 --- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql +++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-127 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql index 54d71e0cf19..94026501130 100644 --- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql +++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * documentation + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql index d5fb20d4883..b7561398468 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-135 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp import Best_Practices.Hiding.Shadowing diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql index c720257228c..b1863aad849 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-138 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql index 2eb21d117bc..83de729ba60 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-139 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql index cc54a8f113e..0088664dcd8 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql index 6600caeb2a1..4b8cd81eb63 100644 --- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql +++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-142 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql index 272b78b0c5a..9bac57b913a 100644 --- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql +++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-143 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql index 858fbf9e123..0388e533650 100644 --- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql +++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql @@ -8,6 +8,7 @@ * @tags reliability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql b/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql index 072076080b1..c60c924460b 100644 --- a/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql +++ b/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-147 * @problem.severity error * @tags reliability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql b/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql index e76a52ce3cd..11a2e09ba96 100644 --- a/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql +++ b/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql @@ -8,6 +8,7 @@ * @tags maintainability * readability * language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql index fc727da9491..1485bb67573 100644 --- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql +++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-149 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql index 8ddad3dfcbe..eaa41fc002f 100644 --- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql +++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-150 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql index 8411c8ebf3f..b541121139b 100644 --- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql +++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-151-1 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql index 7edf379ada2..5cd0052b455 100644 --- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql +++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-151 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql b/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql index f662d04b5ea..c83d96102a5 100644 --- a/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql +++ b/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql index 06c90e12c47..237ce784cd5 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-153 * @problem.severity recommendation * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql index d07c0533251..1fe2b836f2d 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql @@ -10,6 +10,7 @@ * portability * reliability * language-features + * external/jsf * external/cwe/cwe-190 */ import cpp diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql index b2415434305..784cc19d109 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-155 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql index d1b3127d85c..223ba5877d4 100644 --- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql +++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql @@ -7,6 +7,7 @@ * @problem.severity warning * @precision low * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql index a4fec0bae4e..7f99a96fb78 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql @@ -7,6 +7,7 @@ * @problem.severity warning * @tags correctness * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql index b2c61ce72a4..aea14943088 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql @@ -7,6 +7,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql index 12989b012b0..eeccef02f38 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-159 * @problem.severity warning * @tags correctness + * external/jsf */ // See More Effective C++ item 7 // Note: Meyers allows unary & to be overloaded but not comma diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql index 45057d79049..f339291976c 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags correctness * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql index 79b66cb180a..757eb78292e 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-162 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql index 9deedac050d..51f970c912e 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-163 * @problem.severity recommendation * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql index c8ae3f140b9..d10ddfc61d4 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql @@ -6,6 +6,7 @@ * @problem.severity error * @precision low * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql index 8b4aecc16ce..4edae501c8a 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql @@ -7,6 +7,7 @@ * @precision low * @tags correctness * reliability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql index 019e52e0e9f..9eea44cf016 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql @@ -7,6 +7,7 @@ * @id cpp/sizeof-side-effect * @tags reliability * correctness + * external/jsf */ import cpp import jsf.lib.section_4_21_Operators.AV_Rule_166 diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql index d5cf369a1d3..d8b0edf0bf8 100644 --- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql +++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql index e850f2299b2..3dbc992773c 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql index 90a493941d7..2ff8d5464c5 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-171 * @problem.severity error * @tags correctness + * external/jsf */ import cpp import semmle.code.cpp.pointsto.PointsTo diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql index 23c0d8488e1..5f615755478 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql @@ -7,6 +7,7 @@ * @id cpp/jsf/av-rule-173 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql index 916c7fe9e3c..3662d050c3d 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-175 * @problem.severity recommendation * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql index 1dd8cb4032a..1ddce11dc2b 100644 --- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql +++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql index 49bc12294b3..d8738ccc158 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-178 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql index 79c326e28ae..ea16c751592 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-179 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql index e5752cd31d5..a190874796e 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-180 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql index 854ef0b9ad1..bad480ef016 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql index 29810473da8..cf2844519dd 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql @@ -6,6 +6,7 @@ * @problem.severity error * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql index c17979295ab..828d655cd3d 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql @@ -7,6 +7,7 @@ * @id cpp/jsf/av-rule-184 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql index 96a729b24dd..ad7aef37eb9 100644 --- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql +++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-185 * @problem.severity recommendation * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql index f25145800d1..9f56a1ab564 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql @@ -6,6 +6,7 @@ * @problem.severity recommendation * @tags maintainability * useless-code + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql index 76757ea98de..f0435485ce7 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-187 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql index 143fca84ced..1c13ac90ef4 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql index 606bbebc701..79c68166ae3 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql index e34056e25dd..19a60dbc8f5 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-190 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql index 615a5d1bb7f..4201256e09c 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-191 * @problem.severity recommendation * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql index a418dc58ab0..b20f82241cc 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-192 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql index 72cd0a7f646..32754f6d20b 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql @@ -7,6 +7,7 @@ * @problem.severity warning * @tags correctness * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql index 871a4799279..82713fa58ea 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-194 * @problem.severity warning * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql index b3fb2ab035c..318a5879a4d 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql index b0f2627e655..33eaacee040 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql @@ -7,6 +7,7 @@ * @id cpp/trivial-switch * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql index d1993af58ca..9230255a9a0 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql @@ -7,6 +7,7 @@ * @id cpp/loop-variable-float * @tags correctness * reliability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql index 6d8c0d8e288..5b1058b42d7 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql @@ -7,6 +7,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql index e6c6c9a4ab9..2cb5e918c44 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql @@ -7,6 +7,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql index cddb2573aaa..159074279ea 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-200 * @problem.severity warning * @tags maintainability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql index 060734ab0ec..fa9510681d5 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql @@ -7,6 +7,7 @@ * @id cpp/loop-variable-changed * @tags reliability * readability + * external/jsf */ import cpp import Likely_Bugs.NestedLoopSameVar diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql index f97000ed9c2..ea19a9c4eb2 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-202 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql index 9ed07f073ad..132084c0488 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-204-1 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql index f76505c021e..676e4789244 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql @@ -9,6 +9,7 @@ * @problem.severity warning * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql index 2d74a1aaa9e..e468e38a980 100644 --- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql +++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-205 * @problem.severity warning * @tags efficiency + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql index ad73ea336e4..da5c599615a 100644 --- a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql +++ b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-206 * @problem.severity recommendation * @tags resources + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql index 51d5ec8a38b..c9d4015cb40 100644 --- a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql +++ b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags maintainability * modularity + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql b/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql index 11fbe9de13c..26c2d25b784 100644 --- a/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql +++ b/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql @@ -5,6 +5,7 @@ * @id cpp/jsf/av-rule-208 * @problem.severity recommendation * @tags language-features + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql index f2ea9349340..964eec6bbe4 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql @@ -8,6 +8,7 @@ * @problem.severity recommendation * @tags maintainability * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql index 96ff35d1a2a..113c039baec 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql @@ -8,6 +8,7 @@ * @precision low * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql index 32092820bce..5ab7e3598a1 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql @@ -7,6 +7,7 @@ * @problem.severity error * @tags correctness * portability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql index 8b6d139eb05..45672d33397 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql @@ -7,6 +7,7 @@ * @problem.severity recommendation * @tags maintainability * readability + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql index 41cb239ee74..fb267186095 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql @@ -6,6 +6,7 @@ * @id cpp/jsf/av-rule-214 * @problem.severity error * @tags correctness + * external/jsf */ import cpp diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql index 48e8398c208..642feb697a7 100644 --- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql +++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql @@ -6,6 +6,7 @@ * @problem.severity warning * @tags correctness * language-features + * external/jsf */ import cpp From 3c7ed9b7ab46048c516afd66fdd207948231ae89 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 20 Nov 2018 17:02:04 +0000 Subject: [PATCH 57/94] CPP: Fix typo. --- cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql index 35799e26b04..7167bb59cd5 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql @@ -3,7 +3,7 @@ * @description Source lines will be kept to a length of 120 characters or less. * @kind problem * @id cpp/jsf/av-rule-41 - * @problem.severity warrecommendationning + * @problem.severity recommendation * @tags maintainability * readability * external/jsf From 841218540e17ba43751751e8da1d1b2e2cf537d8 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 19 Nov 2018 13:18:27 +0100 Subject: [PATCH 58/94] C#: Add CFG test This test exhibits two issues with Boolean CFG splitting: incorrect handling of negated variables and incorrect splitting for variables defined inside a loop. --- .../controlflow/graph/BasicBlock.expected | 7 + .../graph/BasicBlockDominance.expected | 34 ++++ .../controlflow/graph/BooleanNode.expected | 50 ++++++ .../controlflow/graph/ConditionBlock.expected | 11 ++ .../graph/ConditionalFlow.expected | 12 ++ .../controlflow/graph/Conditions.cs | 13 ++ .../controlflow/graph/Dominance.expected | 153 ++++++++++++++++++ .../controlflow/graph/ElementGraph.expected | 40 +++++ .../controlflow/graph/EntryElement.expected | 38 +++++ .../controlflow/graph/EntryPoint.expected | 1 + .../controlflow/graph/ExitElement.expected | 45 ++++++ .../controlflow/graph/NodeGraph.expected | 81 ++++++++++ 12 files changed, 485 insertions(+) diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected index 3f98400488d..b9930628969 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected @@ -164,6 +164,13 @@ | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | Conditions.cs:109:17:109:23 | ... = ... | 9 | | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | Conditions.cs:108:18:108:18 | [b (line 102): true] access to parameter b | 3 | | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:102:12:102:13 | exit M8 | 3 | +| Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:116:24:116:38 | ... < ... | 14 | +| Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | 1 | +| Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | 13 | +| Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | 13 | +| Conditions.cs:117:9:123:9 | {...} | Conditions.cs:119:18:119:21 | access to local variable last | 13 | +| Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | 16 | +| Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | 8 | | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | exit M1 | 7 | | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | exit M2 | 7 | | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | exit M3 | 6 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected index 04c69bbb6c6..c8b07dab74b 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected @@ -360,6 +360,21 @@ | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:16:110:16 | access to local variable x | +| post | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | enter M9 | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | enter M9 | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | {...} | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| post | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| post | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| post | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} | +| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | | post | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | | post | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | | post | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 | @@ -1705,6 +1720,25 @@ | pre | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | | pre | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | | pre | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:16:110:16 | access to local variable x | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | enter M9 | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | exit M9 | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | {...} | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| pre | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | +| pre | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| pre | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | | pre | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | | pre | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | | pre | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected b/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected index 84ce6e8c301..cffb5425287 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected @@ -98,3 +98,53 @@ | inc (line 3): true | Conditions.cs:7:9:8:16 | [inc (line 3): true] if (...) ... | | inc (line 3): true | Conditions.cs:7:13:7:16 | [inc (line 3): true] !... | | inc (line 3): true | Conditions.cs:7:14:7:16 | [inc (line 3): true] access to parameter inc | +| last (line 118): false | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | +| last (line 118): false | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | +| last (line 118): false | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | +| last (line 118): false | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | +| last (line 118): false | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | +| last (line 118): false | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | +| last (line 118): false | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| last (line 118): false | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | +| last (line 118): false | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | +| last (line 118): false | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | +| last (line 118): false | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | +| last (line 118): false | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | +| last (line 118): false | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | +| last (line 118): false | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | +| last (line 118): false | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | +| last (line 118): false | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | +| last (line 118): false | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | +| last (line 118): false | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | +| last (line 118): false | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | +| last (line 118): false | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| last (line 118): false | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | +| last (line 118): true | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | +| last (line 118): true | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | +| last (line 118): true | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | +| last (line 118): true | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | +| last (line 118): true | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | +| last (line 118): true | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | +| last (line 118): true | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| last (line 118): true | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | +| last (line 118): true | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | +| last (line 118): true | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | +| last (line 118): true | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | +| last (line 118): true | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | +| last (line 118): true | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | +| last (line 118): true | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | +| last (line 118): true | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | +| last (line 118): true | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | +| last (line 118): true | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | +| last (line 118): true | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | +| last (line 118): true | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | +| last (line 118): true | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | +| last (line 118): true | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | +| last (line 118): true | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| last (line 118): true | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | +| last (line 118): true | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| last (line 118): true | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | +| last (line 118): true | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | +| last (line 118): true | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | +| last (line 118): true | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | +| last (line 118): true | Conditions.cs:122:21:122:24 | [last (line 118): true] null | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected index 6c29210d9a9..b638840a8b8 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected @@ -155,6 +155,17 @@ | Conditions.cs:105:13:105:13 | access to parameter b | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | true | | Conditions.cs:107:13:107:24 | [b (line 102): false] ... > ... | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | true | | Conditions.cs:107:13:107:24 | [b (line 102): true] ... > ... | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | true | +| Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | +| Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | true | | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | false | | ExitMethods.cs:55:13:55:13 | access to parameter b | ExitMethods.cs:56:19:56:33 | object creation of type Exception | true | | ExitMethods.cs:61:13:61:13 | access to parameter b | ExitMethods.cs:62:19:62:33 | object creation of type Exception | true | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected b/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected index 3e5ddc8b28a..1b864ed7760 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected @@ -187,10 +187,22 @@ | 108 | 18 | Conditions.cs:108:18:108:18 | [b (line 102): false] access to parameter b | false | 109 | 17 | Conditions.cs:109:17:109:24 | ...; | | 108 | 18 | Conditions.cs:108:18:108:18 | [b (line 102): true] access to parameter b | true | 110 | 16 | Conditions.cs:110:16:110:16 | access to local variable x | | 110 | 20 | cflow.cs:110:20:110:23 | true | true | 111 | 13 | cflow.cs:111:13:113:13 | {...} | +| 116 | 24 | Conditions.cs:116:24:116:38 | ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 | +| 116 | 24 | Conditions.cs:116:24:116:38 | ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | {...} | +| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 | +| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 | +| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | false | 118 | 13 | Switch.cs:118:13:118:33 | case ...: | | 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | true | 117 | 43 | Switch.cs:117:43:117:43 | 1 | | 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | false | 120 | 17 | Switch.cs:120:17:120:17 | 1 | | 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | true | 118 | 42 | Switch.cs:118:42:118:42 | 2 | +| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | false | 116 | 41 | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | +| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | true | 122 | 17 | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | | 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | false | 127 | 53 | cflow.cs:127:53:127:57 | this access | | 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | true | 127 | 48 | cflow.cs:127:48:127:49 | "" | | 162 | 48 | cflow.cs:162:48:162:51 | [exception: Exception] true | true | 163 | 9 | cflow.cs:163:9:165:9 | {...} | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Conditions.cs b/csharp/ql/test/library-tests/controlflow/graph/Conditions.cs index 80a205f732d..d4c5d45a579 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Conditions.cs +++ b/csharp/ql/test/library-tests/controlflow/graph/Conditions.cs @@ -109,4 +109,17 @@ class Conditions x += ""; return x; } + + void M9(string[] args) + { + string s = null; + for(var i = 0; i < args.Length; i++) + { + var last = i == args.Length - 1; + if (!last) + s = ""; + if (last) + s = null; + } + } } diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected index e9b2d47aff5..688fd5c3be2 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected @@ -621,6 +621,82 @@ | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:107:13:107:24 | [b (line 102): true] ... > ... | | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:108:18:108:18 | [b (line 102): true] access to parameter b | | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:109:17:109:23 | ... = ... | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:24:116:38 | ... < ... | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | +| post | Conditions.cs:114:5:124:5 | {...} | Conditions.cs:113:10:113:11 | enter M9 | +| post | Conditions.cs:115:9:115:24 | ... ...; | Conditions.cs:114:5:124:5 | {...} | +| post | Conditions.cs:115:16:115:16 | access to local variable s | Conditions.cs:115:9:115:24 | ... ...; | +| post | Conditions.cs:115:16:115:23 | String s = ... | Conditions.cs:115:20:115:23 | null | +| post | Conditions.cs:115:20:115:23 | null | Conditions.cs:115:16:115:16 | access to local variable s | +| post | Conditions.cs:116:9:123:9 | for (...;...;...) ... | Conditions.cs:115:16:115:23 | String s = ... | +| post | Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:9:123:9 | for (...;...;...) ... | +| post | Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:21:116:21 | 0 | +| post | Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:17:116:17 | access to local variable i | +| post | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | +| post | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:17:116:21 | Int32 i = ... | +| post | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:116:28:116:38 | access to property Length | +| post | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | +| post | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | +| post | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | +| post | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | +| post | Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:24:116:24 | access to local variable i | +| post | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | +| post | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | +| post | Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:28:116:31 | access to parameter args | +| post | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | +| post | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | +| post | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | +| post | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | +| post | Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:117:9:123:9 | {...} | +| post | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| post | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| post | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | +| post | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | +| post | Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:13:118:44 | ... ...; | +| post | Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:118:24:118:43 | ... == ... | +| post | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | +| post | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | +| post | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | +| post | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | +| post | Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:17:118:20 | access to local variable last | +| post | Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:29:118:43 | ... - ... | +| post | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | +| post | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | +| post | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | +| post | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | +| post | Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:24:118:24 | access to local variable i | +| post | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | +| post | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | +| post | Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:29:118:32 | access to parameter args | +| post | Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:43:118:43 | 1 | +| post | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | +| post | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | +| post | Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:29:118:39 | access to property Length | +| post | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | +| post | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | +| post | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | +| post | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | +| post | Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:118:17:118:43 | Boolean last = ... | +| post | Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:13:120:23 | if (...) ... | +| post | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | +| post | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | +| post | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | +| post | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | +| post | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:119:17:119:21 | !... | +| post | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| post | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | +| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | +| post | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | +| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | +| post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | +| post | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| post | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| post | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | +| post | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | Conditions.cs:122:21:122:24 | [last (line 118): true] null | +| post | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | +| post | Conditions.cs:122:21:122:24 | [last (line 118): true] null | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | | post | ExitMethods.cs:7:10:7:11 | exit M1 | ExitMethods.cs:10:9:10:15 | return ...; | | post | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:7:10:7:11 | enter M1 | | post | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:9:20:9:23 | true | @@ -2748,6 +2824,83 @@ | pre | Conditions.cs:109:22:109:23 | "" | Conditions.cs:109:17:109:23 | ... + ... | | pre | Conditions.cs:110:9:110:17 | return ...; | Conditions.cs:102:12:102:13 | exit M8 | | pre | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:9:110:17 | return ...; | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:114:5:124:5 | {...} | +| pre | Conditions.cs:114:5:124:5 | {...} | Conditions.cs:115:9:115:24 | ... ...; | +| pre | Conditions.cs:115:9:115:24 | ... ...; | Conditions.cs:115:16:115:16 | access to local variable s | +| pre | Conditions.cs:115:16:115:16 | access to local variable s | Conditions.cs:115:20:115:23 | null | +| pre | Conditions.cs:115:16:115:23 | String s = ... | Conditions.cs:116:9:123:9 | for (...;...;...) ... | +| pre | Conditions.cs:115:20:115:23 | null | Conditions.cs:115:16:115:23 | String s = ... | +| pre | Conditions.cs:116:9:123:9 | for (...;...;...) ... | Conditions.cs:116:17:116:17 | access to local variable i | +| pre | Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:21:116:21 | 0 | +| pre | Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:24:116:24 | access to local variable i | +| pre | Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:17:116:21 | Int32 i = ... | +| pre | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | +| pre | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | +| pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:28:116:31 | access to parameter args | +| pre | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:113:10:113:11 | exit M9 | +| pre | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | +| pre | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| pre | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | +| pre | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | +| pre | Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:28:116:38 | access to property Length | +| pre | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | +| pre | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | +| pre | Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:24:116:38 | ... < ... | +| pre | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | +| pre | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | +| pre | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | +| pre | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | +| pre | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | +| pre | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:118:13:118:44 | ... ...; | +| pre | Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:118:17:118:20 | access to local variable last | +| pre | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | +| pre | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | +| pre | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | +| pre | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | +| pre | Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:24:118:24 | access to local variable i | +| pre | Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:119:13:120:23 | if (...) ... | +| pre | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | +| pre | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | +| pre | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | +| pre | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | +| pre | Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:29:118:32 | access to parameter args | +| pre | Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:17:118:43 | Boolean last = ... | +| pre | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | +| pre | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | +| pre | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | +| pre | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | +| pre | Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:29:118:39 | access to property Length | +| pre | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | +| pre | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | +| pre | Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:43:118:43 | 1 | +| pre | Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:24:118:43 | ... == ... | +| pre | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | +| pre | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | +| pre | Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:29:118:43 | ... - ... | +| pre | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | +| pre | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | +| pre | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | +| pre | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | +| pre | Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:119:17:119:21 | !... | +| pre | Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | +| pre | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | +| pre | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | +| pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | +| pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| pre | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | +| pre | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | +| pre | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | +| pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | +| pre | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | +| pre | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | +| pre | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | +| pre | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | Conditions.cs:122:21:122:24 | [last (line 118): true] null | +| pre | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | +| pre | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | +| pre | Conditions.cs:122:21:122:24 | [last (line 118): true] null | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | | pre | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:8:5:11:5 | {...} | | pre | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:9:9:9:25 | ...; | | pre | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:15 | return ...; | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ElementGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/ElementGraph.expected index 8867c45ad34..a4158402723 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ElementGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ElementGraph.expected @@ -474,6 +474,46 @@ | Conditions.cs:109:17:109:24 | ...; | Conditions.cs:109:17:109:17 | access to local variable x | semmle.label | successor | | Conditions.cs:109:22:109:23 | "" | Conditions.cs:109:17:109:23 | ... + ... | semmle.label | successor | | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:9:110:17 | return ...; | semmle.label | successor | +| Conditions.cs:114:5:124:5 | {...} | Conditions.cs:115:9:115:24 | ... ...; | semmle.label | successor | +| Conditions.cs:115:9:115:24 | ... ...; | Conditions.cs:115:16:115:16 | access to local variable s | semmle.label | successor | +| Conditions.cs:115:16:115:16 | access to local variable s | Conditions.cs:115:20:115:23 | null | semmle.label | successor | +| Conditions.cs:115:16:115:23 | String s = ... | Conditions.cs:116:9:123:9 | for (...;...;...) ... | semmle.label | successor | +| Conditions.cs:115:20:115:23 | null | Conditions.cs:115:16:115:23 | String s = ... | semmle.label | successor | +| Conditions.cs:116:9:123:9 | for (...;...;...) ... | Conditions.cs:116:17:116:17 | access to local variable i | semmle.label | successor | +| Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:21:116:21 | 0 | semmle.label | successor | +| Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:24:116:24 | access to local variable i | semmle.label | successor | +| Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:17:116:21 | Int32 i = ... | semmle.label | successor | +| Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:28:116:31 | access to parameter args | semmle.label | successor | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | semmle.label | true | +| Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:28:116:38 | access to property Length | semmle.label | successor | +| Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:24:116:38 | ... < ... | semmle.label | successor | +| Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:43 | ...++ | semmle.label | successor | +| Conditions.cs:116:41:116:43 | ...++ | Conditions.cs:116:24:116:24 | access to local variable i | semmle.label | successor | +| Conditions.cs:117:9:123:9 | {...} | Conditions.cs:118:13:118:44 | ... ...; | semmle.label | successor | +| Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:118:17:118:20 | access to local variable last | semmle.label | successor | +| Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:24:118:24 | access to local variable i | semmle.label | successor | +| Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:119:13:120:23 | if (...) ... | semmle.label | successor | +| Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:29:118:32 | access to parameter args | semmle.label | successor | +| Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:17:118:43 | Boolean last = ... | semmle.label | successor | +| Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:29:118:39 | access to property Length | semmle.label | successor | +| Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:43:118:43 | 1 | semmle.label | successor | +| Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:24:118:43 | ... == ... | semmle.label | successor | +| Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:29:118:43 | ... - ... | semmle.label | successor | +| Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:119:17:119:21 | !... | semmle.label | successor | +| Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | semmle.label | successor | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | ...; | semmle.label | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | if (...) ... | semmle.label | true | +| Conditions.cs:120:17:120:17 | access to local variable s | Conditions.cs:120:21:120:22 | "" | semmle.label | successor | +| Conditions.cs:120:17:120:22 | ... = ... | Conditions.cs:121:13:122:25 | if (...) ... | semmle.label | successor | +| Conditions.cs:120:17:120:23 | ...; | Conditions.cs:120:17:120:17 | access to local variable s | semmle.label | successor | +| Conditions.cs:120:21:120:22 | "" | Conditions.cs:120:17:120:22 | ... = ... | semmle.label | successor | +| Conditions.cs:121:13:122:25 | if (...) ... | Conditions.cs:121:17:121:20 | access to local variable last | semmle.label | successor | +| Conditions.cs:121:17:121:20 | access to local variable last | Conditions.cs:116:41:116:41 | access to local variable i | semmle.label | false | +| Conditions.cs:121:17:121:20 | access to local variable last | Conditions.cs:122:17:122:25 | ...; | semmle.label | true | +| Conditions.cs:122:17:122:17 | access to local variable s | Conditions.cs:122:21:122:24 | null | semmle.label | successor | +| Conditions.cs:122:17:122:24 | ... = ... | Conditions.cs:116:41:116:41 | access to local variable i | semmle.label | successor | +| Conditions.cs:122:17:122:25 | ...; | Conditions.cs:122:17:122:17 | access to local variable s | semmle.label | successor | +| Conditions.cs:122:21:122:24 | null | Conditions.cs:122:17:122:24 | ... = ... | semmle.label | successor | | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:9:9:9:25 | ...; | semmle.label | successor | | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:15 | return ...; | semmle.label | successor | | ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:9:20:9:23 | true | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected b/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected index bcd5f55c292..2df036510c4 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected @@ -478,6 +478,44 @@ | Conditions.cs:109:22:109:23 | "" | Conditions.cs:109:22:109:23 | "" | | Conditions.cs:110:9:110:17 | return ...; | Conditions.cs:110:16:110:16 | access to local variable x | | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:16:110:16 | access to local variable x | +| Conditions.cs:114:5:124:5 | {...} | Conditions.cs:114:5:124:5 | {...} | +| Conditions.cs:115:9:115:24 | ... ...; | Conditions.cs:115:9:115:24 | ... ...; | +| Conditions.cs:115:16:115:16 | access to local variable s | Conditions.cs:115:16:115:16 | access to local variable s | +| Conditions.cs:115:16:115:23 | String s = ... | Conditions.cs:115:16:115:16 | access to local variable s | +| Conditions.cs:115:20:115:23 | null | Conditions.cs:115:20:115:23 | null | +| Conditions.cs:116:9:123:9 | for (...;...;...) ... | Conditions.cs:116:9:123:9 | for (...;...;...) ... | +| Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:17:116:17 | access to local variable i | +| Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:17:116:17 | access to local variable i | +| Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:21:116:21 | 0 | +| Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:24:116:24 | access to local variable i | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:116:24:116:24 | access to local variable i | +| Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:28:116:31 | access to parameter args | +| Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:28:116:31 | access to parameter args | +| Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:41 | access to local variable i | +| Conditions.cs:116:41:116:43 | ...++ | Conditions.cs:116:41:116:41 | access to local variable i | +| Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} | +| Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:118:13:118:44 | ... ...; | +| Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:17:118:20 | access to local variable last | +| Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:118:17:118:20 | access to local variable last | +| Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:24:118:24 | access to local variable i | +| Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:24:118:24 | access to local variable i | +| Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:29:118:32 | access to parameter args | +| Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:29:118:32 | access to parameter args | +| Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:29:118:32 | access to parameter args | +| Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:43:118:43 | 1 | +| Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:119:13:120:23 | if (...) ... | +| Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:17:119:21 | !... | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:119:18:119:21 | access to local variable last | +| Conditions.cs:120:17:120:17 | access to local variable s | Conditions.cs:120:17:120:17 | access to local variable s | +| Conditions.cs:120:17:120:22 | ... = ... | Conditions.cs:120:17:120:17 | access to local variable s | +| Conditions.cs:120:17:120:23 | ...; | Conditions.cs:120:17:120:23 | ...; | +| Conditions.cs:120:21:120:22 | "" | Conditions.cs:120:21:120:22 | "" | +| Conditions.cs:121:13:122:25 | if (...) ... | Conditions.cs:121:13:122:25 | if (...) ... | +| Conditions.cs:121:17:121:20 | access to local variable last | Conditions.cs:121:17:121:20 | access to local variable last | +| Conditions.cs:122:17:122:17 | access to local variable s | Conditions.cs:122:17:122:17 | access to local variable s | +| Conditions.cs:122:17:122:24 | ... = ... | Conditions.cs:122:17:122:17 | access to local variable s | +| Conditions.cs:122:17:122:25 | ...; | Conditions.cs:122:17:122:25 | ...; | +| Conditions.cs:122:21:122:24 | null | Conditions.cs:122:21:122:24 | null | | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:8:5:11:5 | {...} | | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:9:20:9:23 | true | | ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:9:9:9:25 | ...; | diff --git a/csharp/ql/test/library-tests/controlflow/graph/EntryPoint.expected b/csharp/ql/test/library-tests/controlflow/graph/EntryPoint.expected index f218267882b..000b67ba018 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/EntryPoint.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/EntryPoint.expected @@ -32,6 +32,7 @@ | Conditions.cs:70:9:70:10 | M6 | Conditions.cs:71:5:84:5 | {...} | | Conditions.cs:86:9:86:10 | M7 | Conditions.cs:87:5:100:5 | {...} | | Conditions.cs:102:12:102:13 | M8 | Conditions.cs:103:5:111:5 | {...} | +| Conditions.cs:113:10:113:11 | M9 | Conditions.cs:114:5:124:5 | {...} | | ExitMethods.cs:7:10:7:11 | M1 | ExitMethods.cs:8:5:11:5 | {...} | | ExitMethods.cs:13:10:13:11 | M2 | ExitMethods.cs:14:5:17:5 | {...} | | ExitMethods.cs:19:10:19:11 | M3 | ExitMethods.cs:20:5:23:5 | {...} | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected b/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected index e96a67d12e6..21e38d8163d 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected @@ -672,6 +672,51 @@ | Conditions.cs:109:22:109:23 | "" | Conditions.cs:109:22:109:23 | "" | normal | | Conditions.cs:110:9:110:17 | return ...; | Conditions.cs:110:9:110:17 | return ...; | return | | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:16:110:16 | access to local variable x | normal | +| Conditions.cs:114:5:124:5 | {...} | Conditions.cs:116:24:116:38 | ... < ... | false/false | +| Conditions.cs:115:9:115:24 | ... ...; | Conditions.cs:115:16:115:23 | String s = ... | normal | +| Conditions.cs:115:16:115:16 | access to local variable s | Conditions.cs:115:16:115:16 | access to local variable s | normal | +| Conditions.cs:115:16:115:23 | String s = ... | Conditions.cs:115:16:115:23 | String s = ... | normal | +| Conditions.cs:115:20:115:23 | null | Conditions.cs:115:20:115:23 | null | normal | +| Conditions.cs:116:9:123:9 | for (...;...;...) ... | Conditions.cs:116:24:116:38 | ... < ... | false/false | +| Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:17:116:17 | access to local variable i | normal | +| Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:17:116:21 | Int32 i = ... | normal | +| Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:21:116:21 | 0 | normal | +| Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:24:116:24 | access to local variable i | normal | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:116:24:116:38 | ... < ... | false/false | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:116:24:116:38 | ... < ... | true/true | +| Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:28:116:31 | access to parameter args | normal | +| Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:28:116:38 | access to property Length | normal | +| Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:41 | access to local variable i | normal | +| Conditions.cs:116:41:116:43 | ...++ | Conditions.cs:116:41:116:43 | ...++ | normal | +| Conditions.cs:117:9:123:9 | {...} | Conditions.cs:121:17:121:20 | access to local variable last | false/false | +| Conditions.cs:117:9:123:9 | {...} | Conditions.cs:122:17:122:24 | ... = ... | normal | +| Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:118:17:118:43 | Boolean last = ... | normal | +| Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:17:118:20 | access to local variable last | normal | +| Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:118:17:118:43 | Boolean last = ... | normal | +| Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:24:118:24 | access to local variable i | normal | +| Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:24:118:43 | ... == ... | normal | +| Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:29:118:32 | access to parameter args | normal | +| Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:29:118:39 | access to property Length | normal | +| Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:29:118:43 | ... - ... | normal | +| Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:43:118:43 | 1 | normal | +| Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:119:18:119:21 | access to local variable last | false/true | +| Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:120:17:120:22 | ... = ... | normal | +| Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | false/true | +| Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | true/false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:119:18:119:21 | access to local variable last | false/false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:119:18:119:21 | access to local variable last | true/true | +| Conditions.cs:120:17:120:17 | access to local variable s | Conditions.cs:120:17:120:17 | access to local variable s | normal | +| Conditions.cs:120:17:120:22 | ... = ... | Conditions.cs:120:17:120:22 | ... = ... | normal | +| Conditions.cs:120:17:120:23 | ...; | Conditions.cs:120:17:120:22 | ... = ... | normal | +| Conditions.cs:120:21:120:22 | "" | Conditions.cs:120:21:120:22 | "" | normal | +| Conditions.cs:121:13:122:25 | if (...) ... | Conditions.cs:121:17:121:20 | access to local variable last | false/false | +| Conditions.cs:121:13:122:25 | if (...) ... | Conditions.cs:122:17:122:24 | ... = ... | normal | +| Conditions.cs:121:17:121:20 | access to local variable last | Conditions.cs:121:17:121:20 | access to local variable last | false/false | +| Conditions.cs:121:17:121:20 | access to local variable last | Conditions.cs:121:17:121:20 | access to local variable last | true/true | +| Conditions.cs:122:17:122:17 | access to local variable s | Conditions.cs:122:17:122:17 | access to local variable s | normal | +| Conditions.cs:122:17:122:24 | ... = ... | Conditions.cs:122:17:122:24 | ... = ... | normal | +| Conditions.cs:122:17:122:25 | ...; | Conditions.cs:122:17:122:24 | ... = ... | normal | +| Conditions.cs:122:21:122:24 | null | Conditions.cs:122:21:122:24 | null | normal | | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:10:9:10:15 | return ...; | return | | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | normal | | ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | normal | diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index 66c8d0bb675..3a9fe38084a 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -728,6 +728,87 @@ | Conditions.cs:109:22:109:23 | "" | Conditions.cs:109:17:109:23 | ... + ... | semmle.label | successor | | Conditions.cs:110:9:110:17 | return ...; | Conditions.cs:102:12:102:13 | exit M8 | semmle.label | return | | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:9:110:17 | return ...; | semmle.label | successor | +| Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:114:5:124:5 | {...} | semmle.label | successor | +| Conditions.cs:114:5:124:5 | {...} | Conditions.cs:115:9:115:24 | ... ...; | semmle.label | successor | +| Conditions.cs:115:9:115:24 | ... ...; | Conditions.cs:115:16:115:16 | access to local variable s | semmle.label | successor | +| Conditions.cs:115:16:115:16 | access to local variable s | Conditions.cs:115:20:115:23 | null | semmle.label | successor | +| Conditions.cs:115:16:115:23 | String s = ... | Conditions.cs:116:9:123:9 | for (...;...;...) ... | semmle.label | successor | +| Conditions.cs:115:20:115:23 | null | Conditions.cs:115:16:115:23 | String s = ... | semmle.label | successor | +| Conditions.cs:116:9:123:9 | for (...;...;...) ... | Conditions.cs:116:17:116:17 | access to local variable i | semmle.label | successor | +| Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:21:116:21 | 0 | semmle.label | successor | +| Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:24:116:24 | access to local variable i | semmle.label | successor | +| Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:17:116:21 | Int32 i = ... | semmle.label | successor | +| Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | semmle.label | successor | +| Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | semmle.label | successor | +| Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:28:116:31 | access to parameter args | semmle.label | successor | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:113:10:113:11 | exit M9 | semmle.label | false | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | semmle.label | true | +| Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:113:10:113:11 | exit M9 | semmle.label | false | +| Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | semmle.label | true | +| Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:113:10:113:11 | exit M9 | semmle.label | false | +| Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | semmle.label | true | +| Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | semmle.label | successor | +| Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | semmle.label | successor | +| Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:28:116:38 | access to property Length | semmle.label | successor | +| Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | semmle.label | successor | +| Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | semmle.label | successor | +| Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:24:116:38 | ... < ... | semmle.label | successor | +| Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | semmle.label | successor | +| Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | semmle.label | successor | +| Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | semmle.label | successor | +| Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | semmle.label | successor | +| Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | semmle.label | successor | +| Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | semmle.label | successor | +| Conditions.cs:117:9:123:9 | {...} | Conditions.cs:118:13:118:44 | ... ...; | semmle.label | successor | +| Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:118:17:118:20 | access to local variable last | semmle.label | successor | +| Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | semmle.label | successor | +| Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | semmle.label | successor | +| Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | semmle.label | successor | +| Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | semmle.label | successor | +| Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:24:118:24 | access to local variable i | semmle.label | successor | +| Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:119:13:120:23 | if (...) ... | semmle.label | successor | +| Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | semmle.label | successor | +| Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | semmle.label | successor | +| Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | semmle.label | successor | +| Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | semmle.label | successor | +| Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:29:118:32 | access to parameter args | semmle.label | successor | +| Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:17:118:43 | Boolean last = ... | semmle.label | successor | +| Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | semmle.label | successor | +| Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | semmle.label | successor | +| Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | semmle.label | successor | +| Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | semmle.label | successor | +| Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:29:118:39 | access to property Length | semmle.label | successor | +| Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | semmle.label | successor | +| Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | semmle.label | successor | +| Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:43:118:43 | 1 | semmle.label | successor | +| Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:24:118:43 | ... == ... | semmle.label | successor | +| Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | semmle.label | successor | +| Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | semmle.label | successor | +| Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:29:118:43 | ... - ... | semmle.label | successor | +| Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | semmle.label | successor | +| Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | semmle.label | successor | +| Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | semmle.label | successor | +| Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | semmle.label | successor | +| Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:119:17:119:21 | !... | semmle.label | successor | +| Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | semmle.label | successor | +| Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | semmle.label | successor | +| Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | semmle.label | successor | +| Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | semmle.label | true | +| Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | semmle.label | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | semmle.label | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | semmle.label | true | +| Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | semmle.label | successor | +| Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | semmle.label | successor | +| Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | semmle.label | successor | +| Conditions.cs:120:21:120:22 | [last (line 118): true] "" | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | semmle.label | successor | +| Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | semmle.label | successor | +| Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | semmle.label | successor | +| Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | semmle.label | false | +| Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | semmle.label | true | +| Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | Conditions.cs:122:21:122:24 | [last (line 118): true] null | semmle.label | successor | +| Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | semmle.label | successor | +| Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | semmle.label | successor | +| Conditions.cs:122:21:122:24 | [last (line 118): true] null | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | semmle.label | successor | | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:8:5:11:5 | {...} | semmle.label | successor | | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:9:9:9:25 | ...; | semmle.label | successor | | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:15 | return ...; | semmle.label | successor | From 89d5daa137bd6cb52bd9e0d9a4460596a4a8718f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 19 Nov 2018 11:39:35 +0100 Subject: [PATCH 59/94] C#: Fix Boolean splitting negation bug --- .../csharp/controlflow/ControlFlowGraph.qll | 2 +- .../controlflow/graph/BasicBlock.expected | 4 +-- .../graph/BasicBlockDominance.expected | 28 +++++++++---------- .../controlflow/graph/BooleanNode.expected | 8 +++--- .../controlflow/graph/ConditionBlock.expected | 12 ++++---- .../graph/ConditionalFlow.expected | 8 +++--- .../controlflow/graph/Dominance.expected | 24 ++++++++-------- .../controlflow/graph/NodeGraph.expected | 16 +++++------ 8 files changed, 51 insertions(+), 51 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll index 6e232bf79da..45cefe8db17 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll @@ -3636,7 +3636,7 @@ module ControlFlow { override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) { succ = succ(pred, c) and this.getSubKind().startsSplit(pred) and - c = any(BooleanCompletion bc | bc.getOuterValue() = this.getBranch()) + c = any(BooleanCompletion bc | bc.getInnerValue() = this.getBranch()) } private ConditionBlock getACorrelatedCondition(boolean inverted) { diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected index b9930628969..2074fcb50a3 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected @@ -169,8 +169,8 @@ | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | 13 | | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | 13 | | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:119:18:119:21 | access to local variable last | 13 | -| Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | 16 | -| Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | 8 | +| Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | 12 | +| Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | 12 | | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | exit M1 | 7 | | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | exit M2 | 7 | | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | exit M3 | 6 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected index c8b07dab74b..ce8bb03486d 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected @@ -366,15 +366,15 @@ | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | {...} | -| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | post | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | | post | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | post | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} | -| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | -| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| post | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| post | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | post | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | | post | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | | post | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 | @@ -1725,20 +1725,20 @@ | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | {...} | -| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | pre | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | | pre | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | | pre | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | | pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} | -| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | -| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | -| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| pre | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | +| pre | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| pre | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | pre | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | | pre | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | | pre | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected b/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected index cffb5425287..b75da7032d1 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected @@ -117,6 +117,10 @@ | last (line 118): false | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | | last (line 118): false | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | | last (line 118): false | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | +| last (line 118): false | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | +| last (line 118): false | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | +| last (line 118): false | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| last (line 118): false | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | | last (line 118): false | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | | last (line 118): false | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | | last (line 118): true | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | @@ -138,10 +142,6 @@ | last (line 118): true | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | | last (line 118): true | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | | last (line 118): true | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | -| last (line 118): true | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | -| last (line 118): true | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | -| last (line 118): true | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| last (line 118): true | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | | last (line 118): true | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | last (line 118): true | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | | last (line 118): true | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected index b638840a8b8..d6a11784198 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected @@ -158,14 +158,14 @@ | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | true | -| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | true | -| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | true | | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | false | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | false | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | true | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | true | | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | false | | ExitMethods.cs:55:13:55:13 | access to parameter b | ExitMethods.cs:56:19:56:33 | object creation of type Exception | true | | ExitMethods.cs:61:13:61:13 | access to parameter b | ExitMethods.cs:62:19:62:33 | object creation of type Exception | true | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected b/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected index 1b864ed7760..b8c8c98dba2 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected @@ -197,10 +197,10 @@ | 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | true | 117 | 43 | Switch.cs:117:43:117:43 | 1 | | 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | false | 120 | 17 | Switch.cs:120:17:120:17 | 1 | | 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | true | 118 | 42 | Switch.cs:118:42:118:42 | 2 | -| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | -| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | false | 116 | 41 | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | | 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | true | 122 | 17 | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | | 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | false | 127 | 53 | cflow.cs:127:53:127:57 | this access | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected index 688fd5c3be2..65d4c617b0b 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected @@ -685,12 +685,12 @@ | post | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | | post | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | | post | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:119:17:119:21 | !... | -| post | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| post | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | -| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | -| post | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | -| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | -| post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | +| post | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| post | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | +| post | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | +| post | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | +| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | +| post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | | post | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | | post | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | post | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | @@ -2887,12 +2887,12 @@ | pre | Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | | pre | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | | pre | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | -| pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | -| pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | -| pre | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | -| pre | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | -| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | -| pre | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | +| pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| pre | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | +| pre | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | +| pre | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | +| pre | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | | pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | | pre | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | | pre | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index 3a9fe38084a..a0883986ab0 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -793,14 +793,14 @@ | Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | semmle.label | successor | | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | semmle.label | successor | | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | semmle.label | successor | -| Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | semmle.label | true | -| Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | semmle.label | false | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | semmle.label | false | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | semmle.label | true | -| Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): true] "" | semmle.label | successor | -| Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | semmle.label | successor | -| Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s | semmle.label | successor | -| Conditions.cs:120:21:120:22 | [last (line 118): true] "" | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... | semmle.label | successor | +| Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | semmle.label | false | +| Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | semmle.label | true | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | semmle.label | false | +| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | semmle.label | true | +| Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | semmle.label | successor | +| Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | semmle.label | successor | +| Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | semmle.label | successor | +| Conditions.cs:120:21:120:22 | [last (line 118): false] "" | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | semmle.label | successor | | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | semmle.label | successor | | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | semmle.label | successor | | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | semmle.label | false | From 8233e34ba2359424f99d8d00c2b485c29af4c321 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 19 Nov 2018 11:55:41 +0100 Subject: [PATCH 60/94] C#: Fix Boolean splitting for variables defined in a loop --- .../csharp/controlflow/ControlFlowGraph.qll | 34 ++++--- .../controlflow/graph/BasicBlock.expected | 10 +- .../graph/BasicBlockDominance.expected | 36 ++++--- .../controlflow/graph/BooleanNode.expected | 42 -------- .../controlflow/graph/ConditionBlock.expected | 8 +- .../graph/ConditionalFlow.expected | 10 +- .../controlflow/graph/Dominance.expected | 99 +++---------------- .../controlflow/graph/NodeGraph.expected | 54 ++-------- 8 files changed, 71 insertions(+), 222 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll index 45cefe8db17..14d12af5219 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll @@ -3476,6 +3476,12 @@ module ControlFlow { this.correlatesConditions(any(ConditionBlock cb | cb.getLastElement() = cfe), _, _) } + /** + * Holds if basic block `bb` can reach a condition correlated with a + * split of this kind. + */ + abstract predicate canReachCorrelatedCondition(PreBasicBlock bb); + /** Gets the callable that this Boolean split kind belongs to. */ abstract Callable getEnclosingCallable(); @@ -3553,6 +3559,17 @@ module ControlFlow { ) } + override predicate canReachCorrelatedCondition(PreBasicBlock bb) { + this.correlatesConditions(_, bb, _) and + not def.getBasicBlock() = bb + or + exists(PreBasicBlock mid | + this.canReachCorrelatedCondition(mid) | + bb = mid.getAPredecessor() and + not def.getBasicBlock() = bb + ) + } + override Callable getEnclosingCallable() { result = def.getCallable() } @@ -3662,26 +3679,13 @@ module ControlFlow { ) } - /** - * Holds if basic block `bb` can reach a condition correlated with the value - * recorded in this split. - */ - private predicate canReachCorrelatedCondition(PreBasicBlock bb) { - bb = this.getACorrelatedCondition(_) - or - exists(PreBasicBlock mid | - this.canReachCorrelatedCondition(mid) | - bb = mid.getAPredecessor() - ) - } - override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) { exists(PreBasicBlock bb | this.appliesToBlock(bb, c) | pred = bb.getLastElement() and succ = succ(pred, c) and // Exit this split if we can no longer reach a correlated condition - not this.canReachCorrelatedCondition(succ) + not this.getSubKind().canReachCorrelatedCondition(succ) ) } @@ -3702,7 +3706,7 @@ module ControlFlow { pred = bb.getLastElement() implies // We must still be able to reach a correlated condition to stay in this split - this.canReachCorrelatedCondition(succ) and + this.getSubKind().canReachCorrelatedCondition(succ) and c = c0 ) ) diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected index 2074fcb50a3..74e4497068d 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected @@ -164,13 +164,13 @@ | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | Conditions.cs:109:17:109:23 | ... = ... | 9 | | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | Conditions.cs:108:18:108:18 | [b (line 102): true] access to parameter b | 3 | | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:102:12:102:13 | exit M8 | 3 | -| Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:116:24:116:38 | ... < ... | 14 | +| Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:116:17:116:21 | Int32 i = ... | 10 | | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | 1 | -| Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | 13 | -| Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | 13 | +| Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:24:116:38 | ... < ... | 4 | +| Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:43 | ...++ | 2 | | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:119:18:119:21 | access to local variable last | 13 | -| Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | 12 | -| Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | 12 | +| Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | 6 | +| Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:122:17:122:24 | ... = ... | 6 | | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | exit M1 | 7 | | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | exit M2 | 7 | | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | exit M3 | 6 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected index ce8bb03486d..da73ec8b0bc 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected @@ -363,17 +363,23 @@ | post | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | enter M9 | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | enter M9 | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | -| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:24:116:24 | access to local variable i | +| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:41:116:41 | access to local variable i | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | {...} | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | -| post | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| post | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:113:10:113:11 | enter M9 | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:24:116:24 | access to local variable i | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:41:116:41 | access to local variable i | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:117:9:123:9 | {...} | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| post | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:41 | access to local variable i | +| post | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:117:9:123:9 | {...} | +| post | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| post | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | post | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} | -| post | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | | post | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | -| post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | post | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | | post | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | @@ -1722,22 +1728,24 @@ | pre | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:16:110:16 | access to local variable x | | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | enter M9 | | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | exit M9 | -| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:116:24:116:24 | access to local variable i | +| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:116:41:116:41 | access to local variable i | | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | {...} | | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | | pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | pre | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | -| pre | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| pre | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | -| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | +| pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:113:10:113:11 | exit M9 | +| pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:24:116:24 | access to local variable i | +| pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:41:116:41 | access to local variable i | +| pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:117:9:123:9 | {...} | +| pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | +| pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | +| pre | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:41 | access to local variable i | +| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:116:41:116:41 | access to local variable i | | pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} | | pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | | pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | -| pre | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | | pre | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | -| pre | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | pre | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | pre | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | | pre | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected b/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected index b75da7032d1..f8c6e8b0872 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected @@ -98,53 +98,11 @@ | inc (line 3): true | Conditions.cs:7:9:8:16 | [inc (line 3): true] if (...) ... | | inc (line 3): true | Conditions.cs:7:13:7:16 | [inc (line 3): true] !... | | inc (line 3): true | Conditions.cs:7:14:7:16 | [inc (line 3): true] access to parameter inc | -| last (line 118): false | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | -| last (line 118): false | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | -| last (line 118): false | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | -| last (line 118): false | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | -| last (line 118): false | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | -| last (line 118): false | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | -| last (line 118): false | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| last (line 118): false | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | -| last (line 118): false | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | -| last (line 118): false | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | -| last (line 118): false | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | -| last (line 118): false | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | -| last (line 118): false | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | -| last (line 118): false | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | -| last (line 118): false | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | -| last (line 118): false | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | -| last (line 118): false | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | -| last (line 118): false | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | -| last (line 118): false | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | | last (line 118): false | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | | last (line 118): false | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | | last (line 118): false | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | | last (line 118): false | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | | last (line 118): false | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | | last (line 118): false | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | -| last (line 118): true | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | -| last (line 118): true | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | -| last (line 118): true | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | -| last (line 118): true | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | -| last (line 118): true | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | -| last (line 118): true | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | -| last (line 118): true | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | -| last (line 118): true | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | -| last (line 118): true | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | -| last (line 118): true | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | -| last (line 118): true | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | -| last (line 118): true | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | -| last (line 118): true | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | -| last (line 118): true | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | -| last (line 118): true | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | -| last (line 118): true | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | -| last (line 118): true | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | -| last (line 118): true | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | -| last (line 118): true | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | | last (line 118): true | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | last (line 118): true | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | -| last (line 118): true | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | -| last (line 118): true | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | -| last (line 118): true | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | -| last (line 118): true | Conditions.cs:122:21:122:24 | [last (line 118): true] null | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected index d6a11784198..ad2b1fc3c4d 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected @@ -155,15 +155,11 @@ | Conditions.cs:105:13:105:13 | access to parameter b | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | true | | Conditions.cs:107:13:107:24 | [b (line 102): false] ... > ... | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | true | | Conditions.cs:107:13:107:24 | [b (line 102): true] ... > ... | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | true | -| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | -| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:113:10:113:11 | exit M9 | false | +| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:116:41:116:41 | access to local variable i | true | | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | true | | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | true | | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | true | -| Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true | -| Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | false | -| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true | | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | false | | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | true | | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | false | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected b/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected index b8c8c98dba2..101b935f13a 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected @@ -189,20 +189,14 @@ | 110 | 20 | cflow.cs:110:20:110:23 | true | true | 111 | 13 | cflow.cs:111:13:113:13 | {...} | | 116 | 24 | Conditions.cs:116:24:116:38 | ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 | | 116 | 24 | Conditions.cs:116:24:116:38 | ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | {...} | -| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 | -| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 | -| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | | 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | false | 118 | 13 | Switch.cs:118:13:118:33 | case ...: | | 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | true | 117 | 43 | Switch.cs:117:43:117:43 | 1 | | 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | false | 120 | 17 | Switch.cs:120:17:120:17 | 1 | | 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | true | 118 | 42 | Switch.cs:118:42:118:42 | 2 | -| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | -| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | | 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | -| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | false | 116 | 41 | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | -| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | true | 122 | 17 | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | +| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | false | 116 | 41 | Conditions.cs:116:41:116:41 | access to local variable i | +| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | true | 122 | 17 | Conditions.cs:122:17:122:25 | ...; | | 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | false | 127 | 53 | cflow.cs:127:53:127:57 | this access | | 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | true | 127 | 48 | cflow.cs:127:48:127:49 | "" | | 162 | 48 | cflow.cs:162:48:162:51 | [exception: Exception] true | true | 163 | 9 | cflow.cs:163:9:165:9 | {...} | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected index 65d4c617b0b..d141f51bd5c 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected @@ -622,8 +622,6 @@ | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:108:18:108:18 | [b (line 102): true] access to parameter b | | post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:109:17:109:23 | ... = ... | | post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:24:116:38 | ... < ... | -| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | -| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | | post | Conditions.cs:114:5:124:5 | {...} | Conditions.cs:113:10:113:11 | enter M9 | | post | Conditions.cs:115:9:115:24 | ... ...; | Conditions.cs:114:5:124:5 | {...} | | post | Conditions.cs:115:16:115:16 | access to local variable s | Conditions.cs:115:9:115:24 | ... ...; | @@ -633,70 +631,36 @@ | post | Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:9:123:9 | for (...;...;...) ... | | post | Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:21:116:21 | 0 | | post | Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:17:116:17 | access to local variable i | -| post | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | -| post | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | | post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:17:116:21 | Int32 i = ... | +| post | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:41:116:43 | ...++ | | post | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:116:28:116:38 | access to property Length | -| post | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | -| post | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | -| post | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | -| post | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | | post | Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:24:116:24 | access to local variable i | -| post | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | -| post | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | | post | Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:28:116:31 | access to parameter args | -| post | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | -| post | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | -| post | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | -| post | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | +| post | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | +| post | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:122:17:122:24 | ... = ... | +| post | Conditions.cs:116:41:116:43 | ...++ | Conditions.cs:116:41:116:41 | access to local variable i | | post | Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:117:9:123:9 | {...} | -| post | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| post | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | -| post | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | -| post | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | | post | Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:13:118:44 | ... ...; | | post | Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:118:24:118:43 | ... == ... | -| post | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | -| post | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | -| post | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | -| post | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | | post | Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:17:118:20 | access to local variable last | | post | Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:29:118:43 | ... - ... | -| post | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | -| post | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | -| post | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | -| post | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | | post | Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:24:118:24 | access to local variable i | -| post | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | -| post | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | | post | Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:29:118:32 | access to parameter args | | post | Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:43:118:43 | 1 | -| post | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | -| post | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | | post | Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:29:118:39 | access to property Length | -| post | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | -| post | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | -| post | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | -| post | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | | post | Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:118:17:118:43 | Boolean last = ... | | post | Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:13:120:23 | if (...) ... | -| post | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | -| post | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | -| post | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | -| post | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | | post | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:119:17:119:21 | !... | | post | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | | post | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | -| post | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | | post | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | | post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | -| post | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | | post | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | | post | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | -| post | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | -| post | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | Conditions.cs:122:21:122:24 | [last (line 118): true] null | -| post | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | -| post | Conditions.cs:122:21:122:24 | [last (line 118): true] null | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | +| post | Conditions.cs:122:17:122:17 | access to local variable s | Conditions.cs:122:17:122:25 | ...; | +| post | Conditions.cs:122:17:122:24 | ... = ... | Conditions.cs:122:21:122:24 | null | +| post | Conditions.cs:122:17:122:25 | ...; | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | +| post | Conditions.cs:122:21:122:24 | null | Conditions.cs:122:17:122:17 | access to local variable s | | post | ExitMethods.cs:7:10:7:11 | exit M1 | ExitMethods.cs:10:9:10:15 | return ...; | | post | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:7:10:7:11 | enter M1 | | post | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:9:20:9:23 | true | @@ -2834,59 +2798,24 @@ | pre | Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:21:116:21 | 0 | | pre | Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:24:116:24 | access to local variable i | | pre | Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:17:116:21 | Int32 i = ... | -| pre | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | -| pre | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | | pre | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:28:116:31 | access to parameter args | | pre | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:113:10:113:11 | exit M9 | | pre | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | -| pre | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | -| pre | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | -| pre | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | -| pre | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | | pre | Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:28:116:38 | access to property Length | -| pre | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | -| pre | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | | pre | Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:24:116:38 | ... < ... | -| pre | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | -| pre | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | -| pre | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | -| pre | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | -| pre | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | -| pre | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | +| pre | Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:43 | ...++ | | pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:118:13:118:44 | ... ...; | | pre | Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:118:17:118:20 | access to local variable last | -| pre | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | -| pre | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | -| pre | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | -| pre | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | | pre | Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:24:118:24 | access to local variable i | | pre | Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:119:13:120:23 | if (...) ... | -| pre | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | -| pre | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | -| pre | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | -| pre | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | | pre | Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:29:118:32 | access to parameter args | | pre | Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:17:118:43 | Boolean last = ... | -| pre | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | -| pre | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | -| pre | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | -| pre | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | | pre | Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:29:118:39 | access to property Length | -| pre | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | -| pre | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | | pre | Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:43:118:43 | 1 | | pre | Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:24:118:43 | ... == ... | -| pre | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | -| pre | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | | pre | Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:29:118:43 | ... - ... | -| pre | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | -| pre | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | -| pre | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | -| pre | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | | pre | Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:119:17:119:21 | !... | | pre | Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | -| pre | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | -| pre | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | | pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | | pre | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | | pre | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | @@ -2895,12 +2824,10 @@ | pre | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | | pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | | pre | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | -| pre | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | -| pre | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | -| pre | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | Conditions.cs:122:21:122:24 | [last (line 118): true] null | -| pre | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | -| pre | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | -| pre | Conditions.cs:122:21:122:24 | [last (line 118): true] null | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | +| pre | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:122:17:122:25 | ...; | +| pre | Conditions.cs:122:17:122:17 | access to local variable s | Conditions.cs:122:21:122:24 | null | +| pre | Conditions.cs:122:17:122:25 | ...; | Conditions.cs:122:17:122:17 | access to local variable s | +| pre | Conditions.cs:122:21:122:24 | null | Conditions.cs:122:17:122:24 | ... = ... | | pre | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:8:5:11:5 | {...} | | pre | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:9:9:9:25 | ...; | | pre | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:15 | return ...; | diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index a0883986ab0..8655ab27d46 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -738,63 +738,25 @@ | Conditions.cs:116:17:116:17 | access to local variable i | Conditions.cs:116:21:116:21 | 0 | semmle.label | successor | | Conditions.cs:116:17:116:21 | Int32 i = ... | Conditions.cs:116:24:116:24 | access to local variable i | semmle.label | successor | | Conditions.cs:116:21:116:21 | 0 | Conditions.cs:116:17:116:21 | Int32 i = ... | semmle.label | successor | -| Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | semmle.label | successor | -| Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | semmle.label | successor | | Conditions.cs:116:24:116:24 | access to local variable i | Conditions.cs:116:28:116:31 | access to parameter args | semmle.label | successor | | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:113:10:113:11 | exit M9 | semmle.label | false | | Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | semmle.label | true | -| Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:113:10:113:11 | exit M9 | semmle.label | false | -| Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | semmle.label | true | -| Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:113:10:113:11 | exit M9 | semmle.label | false | -| Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | semmle.label | true | -| Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | semmle.label | successor | -| Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | semmle.label | successor | | Conditions.cs:116:28:116:31 | access to parameter args | Conditions.cs:116:28:116:38 | access to property Length | semmle.label | successor | -| Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | semmle.label | successor | -| Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | semmle.label | successor | | Conditions.cs:116:28:116:38 | access to property Length | Conditions.cs:116:24:116:38 | ... < ... | semmle.label | successor | -| Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | semmle.label | successor | -| Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | semmle.label | successor | -| Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i | semmle.label | successor | -| Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i | semmle.label | successor | -| Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | semmle.label | successor | -| Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | semmle.label | successor | +| Conditions.cs:116:41:116:41 | access to local variable i | Conditions.cs:116:41:116:43 | ...++ | semmle.label | successor | +| Conditions.cs:116:41:116:43 | ...++ | Conditions.cs:116:24:116:24 | access to local variable i | semmle.label | successor | | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:118:13:118:44 | ... ...; | semmle.label | successor | | Conditions.cs:118:13:118:44 | ... ...; | Conditions.cs:118:17:118:20 | access to local variable last | semmle.label | successor | -| Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | semmle.label | successor | -| Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | semmle.label | successor | -| Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | semmle.label | successor | -| Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | semmle.label | successor | | Conditions.cs:118:17:118:20 | access to local variable last | Conditions.cs:118:24:118:24 | access to local variable i | semmle.label | successor | | Conditions.cs:118:17:118:43 | Boolean last = ... | Conditions.cs:119:13:120:23 | if (...) ... | semmle.label | successor | -| Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | semmle.label | successor | -| Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | semmle.label | successor | -| Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | semmle.label | successor | -| Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | semmle.label | successor | | Conditions.cs:118:24:118:24 | access to local variable i | Conditions.cs:118:29:118:32 | access to parameter args | semmle.label | successor | | Conditions.cs:118:24:118:43 | ... == ... | Conditions.cs:118:17:118:43 | Boolean last = ... | semmle.label | successor | -| Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... | semmle.label | successor | -| Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... | semmle.label | successor | -| Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | semmle.label | successor | -| Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | semmle.label | successor | | Conditions.cs:118:29:118:32 | access to parameter args | Conditions.cs:118:29:118:39 | access to property Length | semmle.label | successor | -| Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | semmle.label | successor | -| Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | semmle.label | successor | | Conditions.cs:118:29:118:39 | access to property Length | Conditions.cs:118:43:118:43 | 1 | semmle.label | successor | | Conditions.cs:118:29:118:43 | ... - ... | Conditions.cs:118:24:118:43 | ... == ... | semmle.label | successor | -| Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... | semmle.label | successor | -| Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... | semmle.label | successor | | Conditions.cs:118:43:118:43 | 1 | Conditions.cs:118:29:118:43 | ... - ... | semmle.label | successor | -| Conditions.cs:118:43:118:43 | [last (line 118): false] 1 | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... | semmle.label | successor | -| Conditions.cs:118:43:118:43 | [last (line 118): true] 1 | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... | semmle.label | successor | -| Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): false] !... | semmle.label | successor | -| Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... | Conditions.cs:119:17:119:21 | [last (line 118): true] !... | semmle.label | successor | | Conditions.cs:119:13:120:23 | if (...) ... | Conditions.cs:119:17:119:21 | !... | semmle.label | successor | | Conditions.cs:119:17:119:21 | !... | Conditions.cs:119:18:119:21 | access to local variable last | semmle.label | successor | -| Conditions.cs:119:17:119:21 | [last (line 118): false] !... | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | semmle.label | successor | -| Conditions.cs:119:17:119:21 | [last (line 118): true] !... | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | semmle.label | successor | -| Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | semmle.label | false | -| Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | semmle.label | true | | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): false] ...; | semmle.label | false | | Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | semmle.label | true | | Conditions.cs:120:17:120:17 | [last (line 118): false] access to local variable s | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | semmle.label | successor | @@ -803,12 +765,12 @@ | Conditions.cs:120:21:120:22 | [last (line 118): false] "" | Conditions.cs:120:17:120:22 | [last (line 118): false] ... = ... | semmle.label | successor | | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | semmle.label | successor | | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | semmle.label | successor | -| Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i | semmle.label | false | -| Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | semmle.label | true | -| Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | Conditions.cs:122:21:122:24 | [last (line 118): true] null | semmle.label | successor | -| Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i | semmle.label | successor | -| Conditions.cs:122:17:122:25 | [last (line 118): true] ...; | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s | semmle.label | successor | -| Conditions.cs:122:21:122:24 | [last (line 118): true] null | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... | semmle.label | successor | +| Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | Conditions.cs:116:41:116:41 | access to local variable i | semmle.label | false | +| Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | Conditions.cs:122:17:122:25 | ...; | semmle.label | true | +| Conditions.cs:122:17:122:17 | access to local variable s | Conditions.cs:122:21:122:24 | null | semmle.label | successor | +| Conditions.cs:122:17:122:24 | ... = ... | Conditions.cs:116:41:116:41 | access to local variable i | semmle.label | successor | +| Conditions.cs:122:17:122:25 | ...; | Conditions.cs:122:17:122:17 | access to local variable s | semmle.label | successor | +| Conditions.cs:122:21:122:24 | null | Conditions.cs:122:17:122:24 | ... = ... | semmle.label | successor | | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:8:5:11:5 | {...} | semmle.label | successor | | ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:9:9:9:25 | ...; | semmle.label | successor | | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:15 | return ...; | semmle.label | successor | From 07f9fe6ee439913ab3d277f0b8fa50b5f90f1498 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Tue, 20 Nov 2018 16:12:44 -0800 Subject: [PATCH 61/94] C++: Add Uninitialized instruction for list-initialized variables This commit inserts an `Uninitialized` instruction to "initialize" a local variable when that variable is initialized with an initializer list. This ensures that there is always a definition of the whole variable before any read or write to part of that variable. This change appears in a different form in @rdmarsh2's Chi node PR, but I needed to refactor the initialization code anyway to handle ConditionDeclExpr. --- .../internal/TranslatedDeclarationEntry.qll | 185 ++++----- .../ir/ir/aliased_ssa_ir.expected | 370 +++++++++--------- .../test/library-tests/ir/ir/raw_ir.expected | 368 ++++++++--------- .../ir/ir/unaliased_ssa_ir.expected | 370 +++++++++--------- 4 files changed, 651 insertions(+), 642 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll index cbddf84c890..53ab0725200 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll @@ -10,8 +10,7 @@ private import TranslatedInitialization * Gets the `TranslatedDeclarationEntry` that represents the declaration * `entry`. */ -TranslatedDeclarationEntry getTranslatedDeclarationEntry( - DeclarationEntry entry) { +TranslatedDeclarationEntry getTranslatedDeclarationEntry(DeclarationEntry entry) { result.getAST() = entry } @@ -21,8 +20,7 @@ TranslatedDeclarationEntry getTranslatedDeclarationEntry( * it can also be the declaration of a static local variable, an extern * variable, or an extern function. */ -abstract class TranslatedDeclarationEntry extends TranslatedElement, - TTranslatedDeclarationEntry { +abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslatedDeclarationEntry { DeclarationEntry entry; TranslatedDeclarationEntry() { @@ -50,14 +48,13 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, * for declarations other than local variables. Since these have no semantic * effect, they are translated as `NoOp`. */ -class TranslatedNonVariableDeclaration extends - TranslatedDeclarationEntry { - TranslatedNonVariableDeclaration() { +class TranslatedNonVariableDeclarationEntry extends TranslatedDeclarationEntry { + TranslatedNonVariableDeclarationEntry() { not entry.getDeclaration() instanceof LocalVariable } override predicate hasInstruction(Opcode opcode, InstructionTag tag, - Type resultType, boolean isGLValue) { + Type resultType, boolean isGLValue) { opcode instanceof Opcode::NoOp and tag = OnlyInstructionTag() and resultType instanceof VoidType and @@ -88,98 +85,11 @@ class TranslatedNonVariableDeclaration extends * Represents the IR translation of the declaration of a local variable, * including its initialization, if any. */ -abstract class TranslatedVariableDeclaration extends - TranslatedDeclarationEntry { - LocalVariable var; - - TranslatedVariableDeclaration() { - entry.getDeclaration() = var - } -} - -/** - * Represents the IR translation of a local variable with no initializer. The - * generated IR stores into the variable using an `Uninitialized` instruction, - * rather than a `Store`. - */ -class TranslatedUninitializedVariable extends - TranslatedVariableDeclaration { - TranslatedUninitializedVariable() { - not exists(Initializer init | - init.getDeclaration() = var - ) - } - - override TranslatedElement getChild(int id) { - none() - } - - override Instruction getFirstInstruction() { - result = getInstruction(InitializerVariableAddressTag()) - } - - override predicate hasInstruction(Opcode opcode, InstructionTag tag, - Type resultType, boolean isGLValue) { - ( - tag = InitializerVariableAddressTag() and - opcode instanceof Opcode::VariableAddress and - resultType = var.getType().getUnspecifiedType() and - isGLValue = true - ) or - ( - tag = InitializerStoreTag() and - opcode instanceof Opcode::Uninitialized and - resultType = var.getType().getUnspecifiedType() and - isGLValue = false - ) - } - - override Instruction getInstructionSuccessor(InstructionTag tag, - EdgeKind kind) { - kind instanceof GotoEdge and - ( - ( - tag = InitializerVariableAddressTag() and - result = getInstruction(InitializerStoreTag()) - ) or - ( - tag = InitializerStoreTag() and - result = getParent().getChildSuccessor(this) - ) - ) - } - - override Instruction getChildSuccessor(TranslatedElement child) { - none() - } - - override Instruction getInstructionOperand(InstructionTag tag, - OperandTag operandTag) { - tag = InitializerStoreTag() and - ( - ( - operandTag instanceof AddressOperandTag and - result = getInstruction(InitializerVariableAddressTag()) - ) - ) - } - - override IRVariable getInstructionVariable(InstructionTag tag) { - tag = InitializerVariableAddressTag() and - result = getIRUserVariable(var.getFunction(), var) - } -} - -/** - * Represents the IR translation of a local variable with an initializer. - */ -class TranslatedInitializedVariable extends - TranslatedVariableDeclaration, InitializationContext { - Initializer init; - - TranslatedInitializedVariable() { - init.getDeclaration() = var - } +abstract class TranslatedVariableDeclaration extends TranslatedElement, InitializationContext { + /** + * Gets the local variable being declared. + */ + abstract LocalVariable getVariable(); override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() @@ -190,18 +100,41 @@ class TranslatedInitializedVariable extends } override predicate hasInstruction(Opcode opcode, InstructionTag tag, - Type resultType, boolean isGLValue) { - tag = InitializerVariableAddressTag() and - opcode instanceof Opcode::VariableAddress and - resultType = var.getType().getUnspecifiedType() and - isGLValue = true + Type resultType, boolean isGLValue) { + ( + tag = InitializerVariableAddressTag() and + opcode instanceof Opcode::VariableAddress and + resultType = getVariable().getType().getUnspecifiedType() and + isGLValue = true + ) or + ( + hasUninitializedInstruction() and + tag = InitializerStoreTag() and + opcode instanceof Opcode::Uninitialized and + resultType = getVariable().getType().getUnspecifiedType() and + isGLValue = false + ) } override Instruction getInstructionSuccessor(InstructionTag tag, - EdgeKind kind) { - tag = InitializerVariableAddressTag() and - result = getInitialization().getFirstInstruction() and - kind instanceof GotoEdge + EdgeKind kind) { + ( + tag = InitializerVariableAddressTag() and + kind instanceof GotoEdge and + if hasUninitializedInstruction() then + result = getInstruction(InitializerStoreTag()) + else + result = getInitialization().getFirstInstruction() + ) or + ( + hasUninitializedInstruction() and + kind instanceof GotoEdge and + tag = InitializerStoreTag() and + ( + result = getInitialization().getFirstInstruction() or + not exists(getInitialization()) and result = getParent().getChildSuccessor(this) + ) + ) } override Instruction getChildSuccessor(TranslatedElement child) { @@ -210,7 +143,14 @@ class TranslatedInitializedVariable extends override IRVariable getInstructionVariable(InstructionTag tag) { tag = InitializerVariableAddressTag() and - result = getIRUserVariable(var.getFunction(), var) + result = getIRUserVariable(getFunction(), getVariable()) + } + + override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) { + hasUninitializedInstruction() and + tag = InitializerStoreTag() and + operandTag instanceof AddressOperandTag and + result = getInstruction(InitializerVariableAddressTag()) } override Instruction getTargetAddress() { @@ -218,10 +158,31 @@ class TranslatedInitializedVariable extends } override Type getTargetType() { - result = var.getType().getUnspecifiedType() + result = getVariable().getType().getUnspecifiedType() } private TranslatedInitialization getInitialization() { - result = getTranslatedInitialization(init.getExpr().getFullyConverted()) + result = getTranslatedInitialization(getVariable().getInitializer().getExpr().getFullyConverted()) + } + + private predicate hasUninitializedInstruction() { + not exists(getInitialization()) or + getInitialization() instanceof TranslatedListInitialization + } +} + +/** + * Represents the IR translation of a local variable declaration within a declaration statement. + */ +class TranslatedVariableDeclarationEntry extends TranslatedVariableDeclaration, + TranslatedDeclarationEntry { + LocalVariable var; + + TranslatedVariableDeclarationEntry() { + var = entry.getDeclaration() + } + + override LocalVariable getVariable() { + result = var } } diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected index 5fbbec2afb7..36c6cff9761 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected @@ -2152,40 +2152,43 @@ ir.cpp: # 503| r0_4(glval) = VariableAddress[f] : # 503| m0_5(float) = InitializeParameter[f] : r0_4 # 504| r0_6(glval) = VariableAddress[pt1] : -# 504| r0_7(glval) = FieldAddress[x] : r0_6 -# 504| r0_8(glval) = VariableAddress[x] : -# 504| r0_9(int) = Load : r0_8, m0_3 -# 504| m0_10(int) = Store : r0_7, r0_9 -# 504| r0_11(glval) = FieldAddress[y] : r0_6 -# 504| r0_12(glval) = VariableAddress[f] : -# 504| r0_13(float) = Load : r0_12, m0_5 -# 504| r0_14(int) = Convert : r0_13 -# 504| mu0_15(int) = Store : r0_11, r0_14 -# 505| r0_16(glval) = VariableAddress[pt2] : -# 505| r0_17(glval) = FieldAddress[x] : r0_16 -# 505| r0_18(glval) = VariableAddress[x] : -# 505| r0_19(int) = Load : r0_18, m0_3 -# 505| m0_20(int) = Store : r0_17, r0_19 -# 505| r0_21(glval) = FieldAddress[y] : r0_16 -# 505| r0_22(int) = Constant[0] : -# 505| mu0_23(int) = Store : r0_21, r0_22 -# 506| r0_24(glval) = VariableAddress[pt3] : -# 506| r0_25(glval) = FieldAddress[x] : r0_24 -# 506| r0_26(int) = Constant[0] : -# 506| m0_27(int) = Store : r0_25, r0_26 -# 506| r0_28(glval) = FieldAddress[y] : r0_24 +# 504| m0_7(Point) = Uninitialized : r0_6 +# 504| r0_8(glval) = FieldAddress[x] : r0_6 +# 504| r0_9(glval) = VariableAddress[x] : +# 504| r0_10(int) = Load : r0_9, m0_3 +# 504| m0_11(int) = Store : r0_8, r0_10 +# 504| r0_12(glval) = FieldAddress[y] : r0_6 +# 504| r0_13(glval) = VariableAddress[f] : +# 504| r0_14(float) = Load : r0_13, m0_5 +# 504| r0_15(int) = Convert : r0_14 +# 504| mu0_16(int) = Store : r0_12, r0_15 +# 505| r0_17(glval) = VariableAddress[pt2] : +# 505| m0_18(Point) = Uninitialized : r0_17 +# 505| r0_19(glval) = FieldAddress[x] : r0_17 +# 505| r0_20(glval) = VariableAddress[x] : +# 505| r0_21(int) = Load : r0_20, m0_3 +# 505| m0_22(int) = Store : r0_19, r0_21 +# 505| r0_23(glval) = FieldAddress[y] : r0_17 +# 505| r0_24(int) = Constant[0] : +# 505| mu0_25(int) = Store : r0_23, r0_24 +# 506| r0_26(glval) = VariableAddress[pt3] : +# 506| m0_27(Point) = Uninitialized : r0_26 +# 506| r0_28(glval) = FieldAddress[x] : r0_26 # 506| r0_29(int) = Constant[0] : -# 506| mu0_30(int) = Store : r0_28, r0_29 -# 508| r0_31(glval) = VariableAddress[x1] : -# 508| r0_32(int) = Constant[1] : -# 508| m0_33(int) = Store : r0_31, r0_32 -# 509| r0_34(glval) = VariableAddress[x2] : -# 509| r0_35(int) = Constant[0] : -# 509| m0_36(int) = Store : r0_34, r0_35 -# 510| v0_37(void) = NoOp : -# 503| v0_38(void) = ReturnVoid : -# 503| v0_39(void) = UnmodeledUse : mu* -# 503| v0_40(void) = ExitFunction : +# 506| m0_30(int) = Store : r0_28, r0_29 +# 506| r0_31(glval) = FieldAddress[y] : r0_26 +# 506| r0_32(int) = Constant[0] : +# 506| mu0_33(int) = Store : r0_31, r0_32 +# 508| r0_34(glval) = VariableAddress[x1] : +# 508| r0_35(int) = Constant[1] : +# 508| m0_36(int) = Store : r0_34, r0_35 +# 509| r0_37(glval) = VariableAddress[x2] : +# 509| r0_38(int) = Constant[0] : +# 509| m0_39(int) = Store : r0_37, r0_38 +# 510| v0_40(void) = NoOp : +# 503| v0_41(void) = ReturnVoid : +# 503| v0_42(void) = UnmodeledUse : mu* +# 503| v0_43(void) = ExitFunction : # 512| NestedInitList(int, float) -> void # 512| Block 0 @@ -2196,68 +2199,72 @@ ir.cpp: # 512| r0_4(glval) = VariableAddress[f] : # 512| m0_5(float) = InitializeParameter[f] : r0_4 # 513| r0_6(glval) = VariableAddress[r1] : -# 513| r0_7(glval) = FieldAddress[topLeft] : r0_6 -# 513| r0_8(Point) = Constant[0] : -# 513| m0_9(Point) = Store : r0_7, r0_8 -# 513| r0_10(glval) = FieldAddress[bottomRight] : r0_6 -# 513| r0_11(Point) = Constant[0] : -# 513| mu0_12(Point) = Store : r0_10, r0_11 -# 514| r0_13(glval) = VariableAddress[r2] : -# 514| r0_14(glval) = FieldAddress[topLeft] : r0_13 -# 514| r0_15(glval) = FieldAddress[x] : r0_14 -# 514| r0_16(glval) = VariableAddress[x] : -# 514| r0_17(int) = Load : r0_16, m0_3 -# 514| m0_18(int) = Store : r0_15, r0_17 -# 514| r0_19(glval) = FieldAddress[y] : r0_14 -# 514| r0_20(glval) = VariableAddress[f] : -# 514| r0_21(float) = Load : r0_20, m0_5 -# 514| r0_22(int) = Convert : r0_21 -# 514| mu0_23(int) = Store : r0_19, r0_22 -# 514| r0_24(glval) = FieldAddress[bottomRight] : r0_13 -# 514| r0_25(Point) = Constant[0] : -# 514| mu0_26(Point) = Store : r0_24, r0_25 -# 515| r0_27(glval) = VariableAddress[r3] : -# 515| r0_28(glval) = FieldAddress[topLeft] : r0_27 -# 515| r0_29(glval) = FieldAddress[x] : r0_28 -# 515| r0_30(glval) = VariableAddress[x] : -# 515| r0_31(int) = Load : r0_30, m0_3 -# 515| m0_32(int) = Store : r0_29, r0_31 -# 515| r0_33(glval) = FieldAddress[y] : r0_28 -# 515| r0_34(glval) = VariableAddress[f] : -# 515| r0_35(float) = Load : r0_34, m0_5 -# 515| r0_36(int) = Convert : r0_35 -# 515| mu0_37(int) = Store : r0_33, r0_36 -# 515| r0_38(glval) = FieldAddress[bottomRight] : r0_27 -# 515| r0_39(glval) = FieldAddress[x] : r0_38 -# 515| r0_40(glval) = VariableAddress[x] : -# 515| r0_41(int) = Load : r0_40, m0_3 -# 515| mu0_42(int) = Store : r0_39, r0_41 -# 515| r0_43(glval) = FieldAddress[y] : r0_38 -# 515| r0_44(glval) = VariableAddress[f] : -# 515| r0_45(float) = Load : r0_44, m0_5 -# 515| r0_46(int) = Convert : r0_45 -# 515| mu0_47(int) = Store : r0_43, r0_46 -# 516| r0_48(glval) = VariableAddress[r4] : -# 516| r0_49(glval) = FieldAddress[topLeft] : r0_48 -# 516| r0_50(glval) = FieldAddress[x] : r0_49 -# 516| r0_51(glval) = VariableAddress[x] : -# 516| r0_52(int) = Load : r0_51, m0_3 -# 516| m0_53(int) = Store : r0_50, r0_52 -# 516| r0_54(glval) = FieldAddress[y] : r0_49 -# 516| r0_55(int) = Constant[0] : -# 516| mu0_56(int) = Store : r0_54, r0_55 -# 516| r0_57(glval) = FieldAddress[bottomRight] : r0_48 -# 516| r0_58(glval) = FieldAddress[x] : r0_57 -# 516| r0_59(glval) = VariableAddress[x] : -# 516| r0_60(int) = Load : r0_59, m0_3 -# 516| mu0_61(int) = Store : r0_58, r0_60 -# 516| r0_62(glval) = FieldAddress[y] : r0_57 -# 516| r0_63(int) = Constant[0] : -# 516| mu0_64(int) = Store : r0_62, r0_63 -# 517| v0_65(void) = NoOp : -# 512| v0_66(void) = ReturnVoid : -# 512| v0_67(void) = UnmodeledUse : mu* -# 512| v0_68(void) = ExitFunction : +# 513| m0_7(Rect) = Uninitialized : r0_6 +# 513| r0_8(glval) = FieldAddress[topLeft] : r0_6 +# 513| r0_9(Point) = Constant[0] : +# 513| m0_10(Point) = Store : r0_8, r0_9 +# 513| r0_11(glval) = FieldAddress[bottomRight] : r0_6 +# 513| r0_12(Point) = Constant[0] : +# 513| mu0_13(Point) = Store : r0_11, r0_12 +# 514| r0_14(glval) = VariableAddress[r2] : +# 514| m0_15(Rect) = Uninitialized : r0_14 +# 514| r0_16(glval) = FieldAddress[topLeft] : r0_14 +# 514| r0_17(glval) = FieldAddress[x] : r0_16 +# 514| r0_18(glval) = VariableAddress[x] : +# 514| r0_19(int) = Load : r0_18, m0_3 +# 514| m0_20(int) = Store : r0_17, r0_19 +# 514| r0_21(glval) = FieldAddress[y] : r0_16 +# 514| r0_22(glval) = VariableAddress[f] : +# 514| r0_23(float) = Load : r0_22, m0_5 +# 514| r0_24(int) = Convert : r0_23 +# 514| mu0_25(int) = Store : r0_21, r0_24 +# 514| r0_26(glval) = FieldAddress[bottomRight] : r0_14 +# 514| r0_27(Point) = Constant[0] : +# 514| mu0_28(Point) = Store : r0_26, r0_27 +# 515| r0_29(glval) = VariableAddress[r3] : +# 515| m0_30(Rect) = Uninitialized : r0_29 +# 515| r0_31(glval) = FieldAddress[topLeft] : r0_29 +# 515| r0_32(glval) = FieldAddress[x] : r0_31 +# 515| r0_33(glval) = VariableAddress[x] : +# 515| r0_34(int) = Load : r0_33, m0_3 +# 515| m0_35(int) = Store : r0_32, r0_34 +# 515| r0_36(glval) = FieldAddress[y] : r0_31 +# 515| r0_37(glval) = VariableAddress[f] : +# 515| r0_38(float) = Load : r0_37, m0_5 +# 515| r0_39(int) = Convert : r0_38 +# 515| mu0_40(int) = Store : r0_36, r0_39 +# 515| r0_41(glval) = FieldAddress[bottomRight] : r0_29 +# 515| r0_42(glval) = FieldAddress[x] : r0_41 +# 515| r0_43(glval) = VariableAddress[x] : +# 515| r0_44(int) = Load : r0_43, m0_3 +# 515| mu0_45(int) = Store : r0_42, r0_44 +# 515| r0_46(glval) = FieldAddress[y] : r0_41 +# 515| r0_47(glval) = VariableAddress[f] : +# 515| r0_48(float) = Load : r0_47, m0_5 +# 515| r0_49(int) = Convert : r0_48 +# 515| mu0_50(int) = Store : r0_46, r0_49 +# 516| r0_51(glval) = VariableAddress[r4] : +# 516| m0_52(Rect) = Uninitialized : r0_51 +# 516| r0_53(glval) = FieldAddress[topLeft] : r0_51 +# 516| r0_54(glval) = FieldAddress[x] : r0_53 +# 516| r0_55(glval) = VariableAddress[x] : +# 516| r0_56(int) = Load : r0_55, m0_3 +# 516| m0_57(int) = Store : r0_54, r0_56 +# 516| r0_58(glval) = FieldAddress[y] : r0_53 +# 516| r0_59(int) = Constant[0] : +# 516| mu0_60(int) = Store : r0_58, r0_59 +# 516| r0_61(glval) = FieldAddress[bottomRight] : r0_51 +# 516| r0_62(glval) = FieldAddress[x] : r0_61 +# 516| r0_63(glval) = VariableAddress[x] : +# 516| r0_64(int) = Load : r0_63, m0_3 +# 516| mu0_65(int) = Store : r0_62, r0_64 +# 516| r0_66(glval) = FieldAddress[y] : r0_61 +# 516| r0_67(int) = Constant[0] : +# 516| mu0_68(int) = Store : r0_66, r0_67 +# 517| v0_69(void) = NoOp : +# 512| v0_70(void) = ReturnVoid : +# 512| v0_71(void) = UnmodeledUse : mu* +# 512| v0_72(void) = ExitFunction : # 519| ArrayInit(int, float) -> void # 519| Block 0 @@ -2268,40 +2275,43 @@ ir.cpp: # 519| r0_4(glval) = VariableAddress[f] : # 519| m0_5(float) = InitializeParameter[f] : r0_4 # 520| r0_6(glval) = VariableAddress[a1] : -# 520| r0_7(int) = Constant[0] : -# 520| r0_8(glval) = PointerAdd : r0_6, r0_7 -# 520| r0_9(unknown[12]) = Constant[0] : -# 520| mu0_10(unknown[12]) = Store : r0_8, r0_9 -# 521| r0_11(glval) = VariableAddress[a2] : -# 521| r0_12(int) = Constant[0] : -# 521| r0_13(glval) = PointerAdd : r0_11, r0_12 -# 521| r0_14(glval) = VariableAddress[x] : -# 521| r0_15(int) = Load : r0_14, m0_3 -# 521| mu0_16(int) = Store : r0_13, r0_15 -# 521| r0_17(int) = Constant[1] : -# 521| r0_18(glval) = PointerAdd : r0_11, r0_17 -# 521| r0_19(glval) = VariableAddress[f] : -# 521| r0_20(float) = Load : r0_19, m0_5 -# 521| r0_21(int) = Convert : r0_20 -# 521| mu0_22(int) = Store : r0_18, r0_21 -# 521| r0_23(int) = Constant[2] : -# 521| r0_24(glval) = PointerAdd : r0_11, r0_23 -# 521| r0_25(int) = Constant[0] : -# 521| mu0_26(int) = Store : r0_24, r0_25 -# 522| r0_27(glval) = VariableAddress[a3] : -# 522| r0_28(int) = Constant[0] : -# 522| r0_29(glval) = PointerAdd : r0_27, r0_28 -# 522| r0_30(glval) = VariableAddress[x] : -# 522| r0_31(int) = Load : r0_30, m0_3 -# 522| mu0_32(int) = Store : r0_29, r0_31 -# 522| r0_33(int) = Constant[1] : -# 522| r0_34(glval) = PointerAdd : r0_27, r0_33 -# 522| r0_35(unknown[8]) = Constant[0] : -# 522| mu0_36(unknown[8]) = Store : r0_34, r0_35 -# 523| v0_37(void) = NoOp : -# 519| v0_38(void) = ReturnVoid : -# 519| v0_39(void) = UnmodeledUse : mu* -# 519| v0_40(void) = ExitFunction : +# 520| mu0_7(int[3]) = Uninitialized : r0_6 +# 520| r0_8(int) = Constant[0] : +# 520| r0_9(glval) = PointerAdd : r0_6, r0_8 +# 520| r0_10(unknown[12]) = Constant[0] : +# 520| mu0_11(unknown[12]) = Store : r0_9, r0_10 +# 521| r0_12(glval) = VariableAddress[a2] : +# 521| mu0_13(int[3]) = Uninitialized : r0_12 +# 521| r0_14(int) = Constant[0] : +# 521| r0_15(glval) = PointerAdd : r0_12, r0_14 +# 521| r0_16(glval) = VariableAddress[x] : +# 521| r0_17(int) = Load : r0_16, m0_3 +# 521| mu0_18(int) = Store : r0_15, r0_17 +# 521| r0_19(int) = Constant[1] : +# 521| r0_20(glval) = PointerAdd : r0_12, r0_19 +# 521| r0_21(glval) = VariableAddress[f] : +# 521| r0_22(float) = Load : r0_21, m0_5 +# 521| r0_23(int) = Convert : r0_22 +# 521| mu0_24(int) = Store : r0_20, r0_23 +# 521| r0_25(int) = Constant[2] : +# 521| r0_26(glval) = PointerAdd : r0_12, r0_25 +# 521| r0_27(int) = Constant[0] : +# 521| mu0_28(int) = Store : r0_26, r0_27 +# 522| r0_29(glval) = VariableAddress[a3] : +# 522| mu0_30(int[3]) = Uninitialized : r0_29 +# 522| r0_31(int) = Constant[0] : +# 522| r0_32(glval) = PointerAdd : r0_29, r0_31 +# 522| r0_33(glval) = VariableAddress[x] : +# 522| r0_34(int) = Load : r0_33, m0_3 +# 522| mu0_35(int) = Store : r0_32, r0_34 +# 522| r0_36(int) = Constant[1] : +# 522| r0_37(glval) = PointerAdd : r0_29, r0_36 +# 522| r0_38(unknown[8]) = Constant[0] : +# 522| mu0_39(unknown[8]) = Store : r0_37, r0_38 +# 523| v0_40(void) = NoOp : +# 519| v0_41(void) = ReturnVoid : +# 519| v0_42(void) = UnmodeledUse : mu* +# 519| v0_43(void) = ExitFunction : # 530| UnionInit(int, float) -> void # 530| Block 0 @@ -2312,15 +2322,16 @@ ir.cpp: # 530| r0_4(glval) = VariableAddress[f] : # 530| m0_5(float) = InitializeParameter[f] : r0_4 # 531| r0_6(glval) = VariableAddress[u1] : -# 531| r0_7(glval) = FieldAddress[d] : r0_6 -# 531| r0_8(glval) = VariableAddress[f] : -# 531| r0_9(float) = Load : r0_8, m0_5 -# 531| r0_10(double) = Convert : r0_9 -# 531| m0_11(double) = Store : r0_7, r0_10 -# 533| v0_12(void) = NoOp : -# 530| v0_13(void) = ReturnVoid : -# 530| v0_14(void) = UnmodeledUse : mu* -# 530| v0_15(void) = ExitFunction : +# 531| m0_7(U) = Uninitialized : r0_6 +# 531| r0_8(glval) = FieldAddress[d] : r0_6 +# 531| r0_9(glval) = VariableAddress[f] : +# 531| r0_10(float) = Load : r0_9, m0_5 +# 531| r0_11(double) = Convert : r0_10 +# 531| m0_12(double) = Store : r0_8, r0_11 +# 533| v0_13(void) = NoOp : +# 530| v0_14(void) = ReturnVoid : +# 530| v0_15(void) = UnmodeledUse : mu* +# 530| v0_16(void) = ExitFunction : # 535| EarlyReturn(int, int) -> void # 535| Block 0 @@ -2479,41 +2490,45 @@ ir.cpp: # 575| r0_18(glval) = VariableAddress[b] : # 575| m0_19(char[2]) = Uninitialized : r0_18 # 576| r0_20(glval) = VariableAddress[c] : -# 576| r0_21(int) = Constant[0] : -# 576| r0_22(glval) = PointerAdd : r0_20, r0_21 -# 576| r0_23(unknown[2]) = Constant[0] : -# 576| mu0_24(unknown[2]) = Store : r0_22, r0_23 -# 577| r0_25(glval) = VariableAddress[d] : -# 577| r0_26(int) = Constant[0] : -# 577| r0_27(glval) = PointerAdd : r0_25, r0_26 -# 577| r0_28(char) = Constant[0] : -# 577| mu0_29(char) = Store : r0_27, r0_28 -# 577| r0_30(int) = Constant[1] : -# 577| r0_31(glval) = PointerAdd : r0_25, r0_30 -# 577| r0_32(char) = Constant[0] : -# 577| mu0_33(char) = Store : r0_31, r0_32 -# 578| r0_34(glval) = VariableAddress[e] : -# 578| r0_35(int) = Constant[0] : -# 578| r0_36(glval) = PointerAdd : r0_34, r0_35 -# 578| r0_37(char) = Constant[0] : -# 578| mu0_38(char) = Store : r0_36, r0_37 -# 578| r0_39(int) = Constant[1] : -# 578| r0_40(glval) = PointerAdd : r0_34, r0_39 -# 578| r0_41(char) = Constant[1] : -# 578| mu0_42(char) = Store : r0_40, r0_41 -# 579| r0_43(glval) = VariableAddress[f] : -# 579| r0_44(int) = Constant[0] : -# 579| r0_45(glval) = PointerAdd : r0_43, r0_44 -# 579| r0_46(char) = Constant[0] : -# 579| mu0_47(char) = Store : r0_45, r0_46 -# 579| r0_48(int) = Constant[1] : -# 579| r0_49(glval) = PointerAdd : r0_43, r0_48 -# 579| r0_50(unknown[2]) = Constant[0] : -# 579| mu0_51(unknown[2]) = Store : r0_49, r0_50 -# 580| v0_52(void) = NoOp : -# 571| v0_53(void) = ReturnVoid : -# 571| v0_54(void) = UnmodeledUse : mu* -# 571| v0_55(void) = ExitFunction : +# 576| mu0_21(char[2]) = Uninitialized : r0_20 +# 576| r0_22(int) = Constant[0] : +# 576| r0_23(glval) = PointerAdd : r0_20, r0_22 +# 576| r0_24(unknown[2]) = Constant[0] : +# 576| mu0_25(unknown[2]) = Store : r0_23, r0_24 +# 577| r0_26(glval) = VariableAddress[d] : +# 577| mu0_27(char[2]) = Uninitialized : r0_26 +# 577| r0_28(int) = Constant[0] : +# 577| r0_29(glval) = PointerAdd : r0_26, r0_28 +# 577| r0_30(char) = Constant[0] : +# 577| mu0_31(char) = Store : r0_29, r0_30 +# 577| r0_32(int) = Constant[1] : +# 577| r0_33(glval) = PointerAdd : r0_26, r0_32 +# 577| r0_34(char) = Constant[0] : +# 577| mu0_35(char) = Store : r0_33, r0_34 +# 578| r0_36(glval) = VariableAddress[e] : +# 578| mu0_37(char[2]) = Uninitialized : r0_36 +# 578| r0_38(int) = Constant[0] : +# 578| r0_39(glval) = PointerAdd : r0_36, r0_38 +# 578| r0_40(char) = Constant[0] : +# 578| mu0_41(char) = Store : r0_39, r0_40 +# 578| r0_42(int) = Constant[1] : +# 578| r0_43(glval) = PointerAdd : r0_36, r0_42 +# 578| r0_44(char) = Constant[1] : +# 578| mu0_45(char) = Store : r0_43, r0_44 +# 579| r0_46(glval) = VariableAddress[f] : +# 579| mu0_47(char[3]) = Uninitialized : r0_46 +# 579| r0_48(int) = Constant[0] : +# 579| r0_49(glval) = PointerAdd : r0_46, r0_48 +# 579| r0_50(char) = Constant[0] : +# 579| mu0_51(char) = Store : r0_49, r0_50 +# 579| r0_52(int) = Constant[1] : +# 579| r0_53(glval) = PointerAdd : r0_46, r0_52 +# 579| r0_54(unknown[2]) = Constant[0] : +# 579| mu0_55(unknown[2]) = Store : r0_53, r0_54 +# 580| v0_56(void) = NoOp : +# 571| v0_57(void) = ReturnVoid : +# 571| v0_58(void) = UnmodeledUse : mu* +# 571| v0_59(void) = ExitFunction : # 584| VarArgs() -> void # 584| Block 0 @@ -3912,10 +3927,11 @@ ir.cpp: # 961| v0_0(void) = EnterFunction : # 961| mu0_1(unknown) = UnmodeledDefinition : # 962| r0_2(glval) = VariableAddress[a1] : -# 962| r0_3(int) = Constant[0] : -# 962| r0_4(glval) = PointerAdd : r0_2, r0_3 -# 962| r0_5(unknown[8]) = Constant[0] : -# 962| mu0_6(unknown[8]) = Store : r0_4, r0_5 +# 962| mu0_3(int[1000]) = Uninitialized : r0_2 +# 962| r0_4(int) = Constant[0] : +# 962| r0_5(glval) = PointerAdd : r0_2, r0_4 +# 962| r0_6(unknown[8]) = Constant[0] : +# 962| mu0_7(unknown[8]) = Store : r0_5, r0_6 #-----| Goto -> Block 2 # 962| Block 1 diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 5f5dc4d3f5d..55facfbd340 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -2135,40 +2135,43 @@ ir.cpp: # 503| r0_4(glval) = VariableAddress[f] : # 503| mu0_5(float) = InitializeParameter[f] : r0_4 # 504| r0_6(glval) = VariableAddress[pt1] : -# 504| r0_7(glval) = FieldAddress[x] : r0_6 -# 504| r0_8(glval) = VariableAddress[x] : -# 504| r0_9(int) = Load : r0_8, mu0_1 -# 504| mu0_10(int) = Store : r0_7, r0_9 -# 504| r0_11(glval) = FieldAddress[y] : r0_6 -# 504| r0_12(glval) = VariableAddress[f] : -# 504| r0_13(float) = Load : r0_12, mu0_1 -# 504| r0_14(int) = Convert : r0_13 -# 504| mu0_15(int) = Store : r0_11, r0_14 -# 505| r0_16(glval) = VariableAddress[pt2] : -# 505| r0_17(glval) = FieldAddress[x] : r0_16 -# 505| r0_18(glval) = VariableAddress[x] : -# 505| r0_19(int) = Load : r0_18, mu0_1 -# 505| mu0_20(int) = Store : r0_17, r0_19 -# 505| r0_21(glval) = FieldAddress[y] : r0_16 -# 505| r0_22(int) = Constant[0] : -# 505| mu0_23(int) = Store : r0_21, r0_22 -# 506| r0_24(glval) = VariableAddress[pt3] : -# 506| r0_25(glval) = FieldAddress[x] : r0_24 -# 506| r0_26(int) = Constant[0] : -# 506| mu0_27(int) = Store : r0_25, r0_26 -# 506| r0_28(glval) = FieldAddress[y] : r0_24 +# 504| mu0_7(Point) = Uninitialized : r0_6 +# 504| r0_8(glval) = FieldAddress[x] : r0_6 +# 504| r0_9(glval) = VariableAddress[x] : +# 504| r0_10(int) = Load : r0_9, mu0_1 +# 504| mu0_11(int) = Store : r0_8, r0_10 +# 504| r0_12(glval) = FieldAddress[y] : r0_6 +# 504| r0_13(glval) = VariableAddress[f] : +# 504| r0_14(float) = Load : r0_13, mu0_1 +# 504| r0_15(int) = Convert : r0_14 +# 504| mu0_16(int) = Store : r0_12, r0_15 +# 505| r0_17(glval) = VariableAddress[pt2] : +# 505| mu0_18(Point) = Uninitialized : r0_17 +# 505| r0_19(glval) = FieldAddress[x] : r0_17 +# 505| r0_20(glval) = VariableAddress[x] : +# 505| r0_21(int) = Load : r0_20, mu0_1 +# 505| mu0_22(int) = Store : r0_19, r0_21 +# 505| r0_23(glval) = FieldAddress[y] : r0_17 +# 505| r0_24(int) = Constant[0] : +# 505| mu0_25(int) = Store : r0_23, r0_24 +# 506| r0_26(glval) = VariableAddress[pt3] : +# 506| mu0_27(Point) = Uninitialized : r0_26 +# 506| r0_28(glval) = FieldAddress[x] : r0_26 # 506| r0_29(int) = Constant[0] : # 506| mu0_30(int) = Store : r0_28, r0_29 -# 508| r0_31(glval) = VariableAddress[x1] : -# 508| r0_32(int) = Constant[1] : -# 508| mu0_33(int) = Store : r0_31, r0_32 -# 509| r0_34(glval) = VariableAddress[x2] : -# 509| r0_35(int) = Constant[0] : -# 509| mu0_36(int) = Store : r0_34, r0_35 -# 510| v0_37(void) = NoOp : -# 503| v0_38(void) = ReturnVoid : -# 503| v0_39(void) = UnmodeledUse : mu* -# 503| v0_40(void) = ExitFunction : +# 506| r0_31(glval) = FieldAddress[y] : r0_26 +# 506| r0_32(int) = Constant[0] : +# 506| mu0_33(int) = Store : r0_31, r0_32 +# 508| r0_34(glval) = VariableAddress[x1] : +# 508| r0_35(int) = Constant[1] : +# 508| mu0_36(int) = Store : r0_34, r0_35 +# 509| r0_37(glval) = VariableAddress[x2] : +# 509| r0_38(int) = Constant[0] : +# 509| mu0_39(int) = Store : r0_37, r0_38 +# 510| v0_40(void) = NoOp : +# 503| v0_41(void) = ReturnVoid : +# 503| v0_42(void) = UnmodeledUse : mu* +# 503| v0_43(void) = ExitFunction : # 512| NestedInitList(int, float) -> void # 512| Block 0 @@ -2179,68 +2182,72 @@ ir.cpp: # 512| r0_4(glval) = VariableAddress[f] : # 512| mu0_5(float) = InitializeParameter[f] : r0_4 # 513| r0_6(glval) = VariableAddress[r1] : -# 513| r0_7(glval) = FieldAddress[topLeft] : r0_6 -# 513| r0_8(Point) = Constant[0] : -# 513| mu0_9(Point) = Store : r0_7, r0_8 -# 513| r0_10(glval) = FieldAddress[bottomRight] : r0_6 -# 513| r0_11(Point) = Constant[0] : -# 513| mu0_12(Point) = Store : r0_10, r0_11 -# 514| r0_13(glval) = VariableAddress[r2] : -# 514| r0_14(glval) = FieldAddress[topLeft] : r0_13 -# 514| r0_15(glval) = FieldAddress[x] : r0_14 -# 514| r0_16(glval) = VariableAddress[x] : -# 514| r0_17(int) = Load : r0_16, mu0_1 -# 514| mu0_18(int) = Store : r0_15, r0_17 -# 514| r0_19(glval) = FieldAddress[y] : r0_14 -# 514| r0_20(glval) = VariableAddress[f] : -# 514| r0_21(float) = Load : r0_20, mu0_1 -# 514| r0_22(int) = Convert : r0_21 -# 514| mu0_23(int) = Store : r0_19, r0_22 -# 514| r0_24(glval) = FieldAddress[bottomRight] : r0_13 -# 514| r0_25(Point) = Constant[0] : -# 514| mu0_26(Point) = Store : r0_24, r0_25 -# 515| r0_27(glval) = VariableAddress[r3] : -# 515| r0_28(glval) = FieldAddress[topLeft] : r0_27 -# 515| r0_29(glval) = FieldAddress[x] : r0_28 -# 515| r0_30(glval) = VariableAddress[x] : -# 515| r0_31(int) = Load : r0_30, mu0_1 -# 515| mu0_32(int) = Store : r0_29, r0_31 -# 515| r0_33(glval) = FieldAddress[y] : r0_28 -# 515| r0_34(glval) = VariableAddress[f] : -# 515| r0_35(float) = Load : r0_34, mu0_1 -# 515| r0_36(int) = Convert : r0_35 -# 515| mu0_37(int) = Store : r0_33, r0_36 -# 515| r0_38(glval) = FieldAddress[bottomRight] : r0_27 -# 515| r0_39(glval) = FieldAddress[x] : r0_38 -# 515| r0_40(glval) = VariableAddress[x] : -# 515| r0_41(int) = Load : r0_40, mu0_1 -# 515| mu0_42(int) = Store : r0_39, r0_41 -# 515| r0_43(glval) = FieldAddress[y] : r0_38 -# 515| r0_44(glval) = VariableAddress[f] : -# 515| r0_45(float) = Load : r0_44, mu0_1 -# 515| r0_46(int) = Convert : r0_45 -# 515| mu0_47(int) = Store : r0_43, r0_46 -# 516| r0_48(glval) = VariableAddress[r4] : -# 516| r0_49(glval) = FieldAddress[topLeft] : r0_48 -# 516| r0_50(glval) = FieldAddress[x] : r0_49 -# 516| r0_51(glval) = VariableAddress[x] : -# 516| r0_52(int) = Load : r0_51, mu0_1 -# 516| mu0_53(int) = Store : r0_50, r0_52 -# 516| r0_54(glval) = FieldAddress[y] : r0_49 -# 516| r0_55(int) = Constant[0] : -# 516| mu0_56(int) = Store : r0_54, r0_55 -# 516| r0_57(glval) = FieldAddress[bottomRight] : r0_48 -# 516| r0_58(glval) = FieldAddress[x] : r0_57 -# 516| r0_59(glval) = VariableAddress[x] : -# 516| r0_60(int) = Load : r0_59, mu0_1 -# 516| mu0_61(int) = Store : r0_58, r0_60 -# 516| r0_62(glval) = FieldAddress[y] : r0_57 -# 516| r0_63(int) = Constant[0] : -# 516| mu0_64(int) = Store : r0_62, r0_63 -# 517| v0_65(void) = NoOp : -# 512| v0_66(void) = ReturnVoid : -# 512| v0_67(void) = UnmodeledUse : mu* -# 512| v0_68(void) = ExitFunction : +# 513| mu0_7(Rect) = Uninitialized : r0_6 +# 513| r0_8(glval) = FieldAddress[topLeft] : r0_6 +# 513| r0_9(Point) = Constant[0] : +# 513| mu0_10(Point) = Store : r0_8, r0_9 +# 513| r0_11(glval) = FieldAddress[bottomRight] : r0_6 +# 513| r0_12(Point) = Constant[0] : +# 513| mu0_13(Point) = Store : r0_11, r0_12 +# 514| r0_14(glval) = VariableAddress[r2] : +# 514| mu0_15(Rect) = Uninitialized : r0_14 +# 514| r0_16(glval) = FieldAddress[topLeft] : r0_14 +# 514| r0_17(glval) = FieldAddress[x] : r0_16 +# 514| r0_18(glval) = VariableAddress[x] : +# 514| r0_19(int) = Load : r0_18, mu0_1 +# 514| mu0_20(int) = Store : r0_17, r0_19 +# 514| r0_21(glval) = FieldAddress[y] : r0_16 +# 514| r0_22(glval) = VariableAddress[f] : +# 514| r0_23(float) = Load : r0_22, mu0_1 +# 514| r0_24(int) = Convert : r0_23 +# 514| mu0_25(int) = Store : r0_21, r0_24 +# 514| r0_26(glval) = FieldAddress[bottomRight] : r0_14 +# 514| r0_27(Point) = Constant[0] : +# 514| mu0_28(Point) = Store : r0_26, r0_27 +# 515| r0_29(glval) = VariableAddress[r3] : +# 515| mu0_30(Rect) = Uninitialized : r0_29 +# 515| r0_31(glval) = FieldAddress[topLeft] : r0_29 +# 515| r0_32(glval) = FieldAddress[x] : r0_31 +# 515| r0_33(glval) = VariableAddress[x] : +# 515| r0_34(int) = Load : r0_33, mu0_1 +# 515| mu0_35(int) = Store : r0_32, r0_34 +# 515| r0_36(glval) = FieldAddress[y] : r0_31 +# 515| r0_37(glval) = VariableAddress[f] : +# 515| r0_38(float) = Load : r0_37, mu0_1 +# 515| r0_39(int) = Convert : r0_38 +# 515| mu0_40(int) = Store : r0_36, r0_39 +# 515| r0_41(glval) = FieldAddress[bottomRight] : r0_29 +# 515| r0_42(glval) = FieldAddress[x] : r0_41 +# 515| r0_43(glval) = VariableAddress[x] : +# 515| r0_44(int) = Load : r0_43, mu0_1 +# 515| mu0_45(int) = Store : r0_42, r0_44 +# 515| r0_46(glval) = FieldAddress[y] : r0_41 +# 515| r0_47(glval) = VariableAddress[f] : +# 515| r0_48(float) = Load : r0_47, mu0_1 +# 515| r0_49(int) = Convert : r0_48 +# 515| mu0_50(int) = Store : r0_46, r0_49 +# 516| r0_51(glval) = VariableAddress[r4] : +# 516| mu0_52(Rect) = Uninitialized : r0_51 +# 516| r0_53(glval) = FieldAddress[topLeft] : r0_51 +# 516| r0_54(glval) = FieldAddress[x] : r0_53 +# 516| r0_55(glval) = VariableAddress[x] : +# 516| r0_56(int) = Load : r0_55, mu0_1 +# 516| mu0_57(int) = Store : r0_54, r0_56 +# 516| r0_58(glval) = FieldAddress[y] : r0_53 +# 516| r0_59(int) = Constant[0] : +# 516| mu0_60(int) = Store : r0_58, r0_59 +# 516| r0_61(glval) = FieldAddress[bottomRight] : r0_51 +# 516| r0_62(glval) = FieldAddress[x] : r0_61 +# 516| r0_63(glval) = VariableAddress[x] : +# 516| r0_64(int) = Load : r0_63, mu0_1 +# 516| mu0_65(int) = Store : r0_62, r0_64 +# 516| r0_66(glval) = FieldAddress[y] : r0_61 +# 516| r0_67(int) = Constant[0] : +# 516| mu0_68(int) = Store : r0_66, r0_67 +# 517| v0_69(void) = NoOp : +# 512| v0_70(void) = ReturnVoid : +# 512| v0_71(void) = UnmodeledUse : mu* +# 512| v0_72(void) = ExitFunction : # 519| ArrayInit(int, float) -> void # 519| Block 0 @@ -2251,40 +2258,43 @@ ir.cpp: # 519| r0_4(glval) = VariableAddress[f] : # 519| mu0_5(float) = InitializeParameter[f] : r0_4 # 520| r0_6(glval) = VariableAddress[a1] : -# 520| r0_7(int) = Constant[0] : -# 520| r0_8(glval) = PointerAdd : r0_6, r0_7 -# 520| r0_9(unknown[12]) = Constant[0] : -# 520| mu0_10(unknown[12]) = Store : r0_8, r0_9 -# 521| r0_11(glval) = VariableAddress[a2] : -# 521| r0_12(int) = Constant[0] : -# 521| r0_13(glval) = PointerAdd : r0_11, r0_12 -# 521| r0_14(glval) = VariableAddress[x] : -# 521| r0_15(int) = Load : r0_14, mu0_1 -# 521| mu0_16(int) = Store : r0_13, r0_15 -# 521| r0_17(int) = Constant[1] : -# 521| r0_18(glval) = PointerAdd : r0_11, r0_17 -# 521| r0_19(glval) = VariableAddress[f] : -# 521| r0_20(float) = Load : r0_19, mu0_1 -# 521| r0_21(int) = Convert : r0_20 -# 521| mu0_22(int) = Store : r0_18, r0_21 -# 521| r0_23(int) = Constant[2] : -# 521| r0_24(glval) = PointerAdd : r0_11, r0_23 -# 521| r0_25(int) = Constant[0] : -# 521| mu0_26(int) = Store : r0_24, r0_25 -# 522| r0_27(glval) = VariableAddress[a3] : -# 522| r0_28(int) = Constant[0] : -# 522| r0_29(glval) = PointerAdd : r0_27, r0_28 -# 522| r0_30(glval) = VariableAddress[x] : -# 522| r0_31(int) = Load : r0_30, mu0_1 -# 522| mu0_32(int) = Store : r0_29, r0_31 -# 522| r0_33(int) = Constant[1] : -# 522| r0_34(glval) = PointerAdd : r0_27, r0_33 -# 522| r0_35(unknown[8]) = Constant[0] : -# 522| mu0_36(unknown[8]) = Store : r0_34, r0_35 -# 523| v0_37(void) = NoOp : -# 519| v0_38(void) = ReturnVoid : -# 519| v0_39(void) = UnmodeledUse : mu* -# 519| v0_40(void) = ExitFunction : +# 520| mu0_7(int[3]) = Uninitialized : r0_6 +# 520| r0_8(int) = Constant[0] : +# 520| r0_9(glval) = PointerAdd : r0_6, r0_8 +# 520| r0_10(unknown[12]) = Constant[0] : +# 520| mu0_11(unknown[12]) = Store : r0_9, r0_10 +# 521| r0_12(glval) = VariableAddress[a2] : +# 521| mu0_13(int[3]) = Uninitialized : r0_12 +# 521| r0_14(int) = Constant[0] : +# 521| r0_15(glval) = PointerAdd : r0_12, r0_14 +# 521| r0_16(glval) = VariableAddress[x] : +# 521| r0_17(int) = Load : r0_16, mu0_1 +# 521| mu0_18(int) = Store : r0_15, r0_17 +# 521| r0_19(int) = Constant[1] : +# 521| r0_20(glval) = PointerAdd : r0_12, r0_19 +# 521| r0_21(glval) = VariableAddress[f] : +# 521| r0_22(float) = Load : r0_21, mu0_1 +# 521| r0_23(int) = Convert : r0_22 +# 521| mu0_24(int) = Store : r0_20, r0_23 +# 521| r0_25(int) = Constant[2] : +# 521| r0_26(glval) = PointerAdd : r0_12, r0_25 +# 521| r0_27(int) = Constant[0] : +# 521| mu0_28(int) = Store : r0_26, r0_27 +# 522| r0_29(glval) = VariableAddress[a3] : +# 522| mu0_30(int[3]) = Uninitialized : r0_29 +# 522| r0_31(int) = Constant[0] : +# 522| r0_32(glval) = PointerAdd : r0_29, r0_31 +# 522| r0_33(glval) = VariableAddress[x] : +# 522| r0_34(int) = Load : r0_33, mu0_1 +# 522| mu0_35(int) = Store : r0_32, r0_34 +# 522| r0_36(int) = Constant[1] : +# 522| r0_37(glval) = PointerAdd : r0_29, r0_36 +# 522| r0_38(unknown[8]) = Constant[0] : +# 522| mu0_39(unknown[8]) = Store : r0_37, r0_38 +# 523| v0_40(void) = NoOp : +# 519| v0_41(void) = ReturnVoid : +# 519| v0_42(void) = UnmodeledUse : mu* +# 519| v0_43(void) = ExitFunction : # 530| UnionInit(int, float) -> void # 530| Block 0 @@ -2295,15 +2305,16 @@ ir.cpp: # 530| r0_4(glval) = VariableAddress[f] : # 530| mu0_5(float) = InitializeParameter[f] : r0_4 # 531| r0_6(glval) = VariableAddress[u1] : -# 531| r0_7(glval) = FieldAddress[d] : r0_6 -# 531| r0_8(glval) = VariableAddress[f] : -# 531| r0_9(float) = Load : r0_8, mu0_1 -# 531| r0_10(double) = Convert : r0_9 -# 531| mu0_11(double) = Store : r0_7, r0_10 -# 533| v0_12(void) = NoOp : -# 530| v0_13(void) = ReturnVoid : -# 530| v0_14(void) = UnmodeledUse : mu* -# 530| v0_15(void) = ExitFunction : +# 531| mu0_7(U) = Uninitialized : r0_6 +# 531| r0_8(glval) = FieldAddress[d] : r0_6 +# 531| r0_9(glval) = VariableAddress[f] : +# 531| r0_10(float) = Load : r0_9, mu0_1 +# 531| r0_11(double) = Convert : r0_10 +# 531| mu0_12(double) = Store : r0_8, r0_11 +# 533| v0_13(void) = NoOp : +# 530| v0_14(void) = ReturnVoid : +# 530| v0_15(void) = UnmodeledUse : mu* +# 530| v0_16(void) = ExitFunction : # 535| EarlyReturn(int, int) -> void # 535| Block 0 @@ -2460,41 +2471,45 @@ ir.cpp: # 575| r0_18(glval) = VariableAddress[b] : # 575| mu0_19(char[2]) = Uninitialized : r0_18 # 576| r0_20(glval) = VariableAddress[c] : -# 576| r0_21(int) = Constant[0] : -# 576| r0_22(glval) = PointerAdd : r0_20, r0_21 -# 576| r0_23(unknown[2]) = Constant[0] : -# 576| mu0_24(unknown[2]) = Store : r0_22, r0_23 -# 577| r0_25(glval) = VariableAddress[d] : -# 577| r0_26(int) = Constant[0] : -# 577| r0_27(glval) = PointerAdd : r0_25, r0_26 -# 577| r0_28(char) = Constant[0] : -# 577| mu0_29(char) = Store : r0_27, r0_28 -# 577| r0_30(int) = Constant[1] : -# 577| r0_31(glval) = PointerAdd : r0_25, r0_30 -# 577| r0_32(char) = Constant[0] : -# 577| mu0_33(char) = Store : r0_31, r0_32 -# 578| r0_34(glval) = VariableAddress[e] : -# 578| r0_35(int) = Constant[0] : -# 578| r0_36(glval) = PointerAdd : r0_34, r0_35 -# 578| r0_37(char) = Constant[0] : -# 578| mu0_38(char) = Store : r0_36, r0_37 -# 578| r0_39(int) = Constant[1] : -# 578| r0_40(glval) = PointerAdd : r0_34, r0_39 -# 578| r0_41(char) = Constant[1] : -# 578| mu0_42(char) = Store : r0_40, r0_41 -# 579| r0_43(glval) = VariableAddress[f] : -# 579| r0_44(int) = Constant[0] : -# 579| r0_45(glval) = PointerAdd : r0_43, r0_44 -# 579| r0_46(char) = Constant[0] : -# 579| mu0_47(char) = Store : r0_45, r0_46 -# 579| r0_48(int) = Constant[1] : -# 579| r0_49(glval) = PointerAdd : r0_43, r0_48 -# 579| r0_50(unknown[2]) = Constant[0] : -# 579| mu0_51(unknown[2]) = Store : r0_49, r0_50 -# 580| v0_52(void) = NoOp : -# 571| v0_53(void) = ReturnVoid : -# 571| v0_54(void) = UnmodeledUse : mu* -# 571| v0_55(void) = ExitFunction : +# 576| mu0_21(char[2]) = Uninitialized : r0_20 +# 576| r0_22(int) = Constant[0] : +# 576| r0_23(glval) = PointerAdd : r0_20, r0_22 +# 576| r0_24(unknown[2]) = Constant[0] : +# 576| mu0_25(unknown[2]) = Store : r0_23, r0_24 +# 577| r0_26(glval) = VariableAddress[d] : +# 577| mu0_27(char[2]) = Uninitialized : r0_26 +# 577| r0_28(int) = Constant[0] : +# 577| r0_29(glval) = PointerAdd : r0_26, r0_28 +# 577| r0_30(char) = Constant[0] : +# 577| mu0_31(char) = Store : r0_29, r0_30 +# 577| r0_32(int) = Constant[1] : +# 577| r0_33(glval) = PointerAdd : r0_26, r0_32 +# 577| r0_34(char) = Constant[0] : +# 577| mu0_35(char) = Store : r0_33, r0_34 +# 578| r0_36(glval) = VariableAddress[e] : +# 578| mu0_37(char[2]) = Uninitialized : r0_36 +# 578| r0_38(int) = Constant[0] : +# 578| r0_39(glval) = PointerAdd : r0_36, r0_38 +# 578| r0_40(char) = Constant[0] : +# 578| mu0_41(char) = Store : r0_39, r0_40 +# 578| r0_42(int) = Constant[1] : +# 578| r0_43(glval) = PointerAdd : r0_36, r0_42 +# 578| r0_44(char) = Constant[1] : +# 578| mu0_45(char) = Store : r0_43, r0_44 +# 579| r0_46(glval) = VariableAddress[f] : +# 579| mu0_47(char[3]) = Uninitialized : r0_46 +# 579| r0_48(int) = Constant[0] : +# 579| r0_49(glval) = PointerAdd : r0_46, r0_48 +# 579| r0_50(char) = Constant[0] : +# 579| mu0_51(char) = Store : r0_49, r0_50 +# 579| r0_52(int) = Constant[1] : +# 579| r0_53(glval) = PointerAdd : r0_46, r0_52 +# 579| r0_54(unknown[2]) = Constant[0] : +# 579| mu0_55(unknown[2]) = Store : r0_53, r0_54 +# 580| v0_56(void) = NoOp : +# 571| v0_57(void) = ReturnVoid : +# 571| v0_58(void) = UnmodeledUse : mu* +# 571| v0_59(void) = ExitFunction : # 584| VarArgs() -> void # 584| Block 0 @@ -3891,10 +3906,11 @@ ir.cpp: # 961| v0_0(void) = EnterFunction : # 961| mu0_1(unknown) = UnmodeledDefinition : # 962| r0_2(glval) = VariableAddress[a1] : -# 962| r0_3(int) = Constant[0] : -# 962| r0_4(glval) = PointerAdd : r0_2, r0_3 -# 962| r0_5(unknown[8]) = Constant[0] : -# 962| mu0_6(unknown[8]) = Store : r0_4, r0_5 +# 962| mu0_3(int[1000]) = Uninitialized : r0_2 +# 962| r0_4(int) = Constant[0] : +# 962| r0_5(glval) = PointerAdd : r0_2, r0_4 +# 962| r0_6(unknown[8]) = Constant[0] : +# 962| mu0_7(unknown[8]) = Store : r0_5, r0_6 #-----| Goto -> Block 2 # 962| Block 1 diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected index af2385fb03d..98b4934e13c 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected @@ -2152,40 +2152,43 @@ ir.cpp: # 503| r0_4(glval) = VariableAddress[f] : # 503| m0_5(float) = InitializeParameter[f] : r0_4 # 504| r0_6(glval) = VariableAddress[pt1] : -# 504| r0_7(glval) = FieldAddress[x] : r0_6 -# 504| r0_8(glval) = VariableAddress[x] : -# 504| r0_9(int) = Load : r0_8, m0_3 -# 504| m0_10(int) = Store : r0_7, r0_9 -# 504| r0_11(glval) = FieldAddress[y] : r0_6 -# 504| r0_12(glval) = VariableAddress[f] : -# 504| r0_13(float) = Load : r0_12, m0_5 -# 504| r0_14(int) = Convert : r0_13 -# 504| mu0_15(int) = Store : r0_11, r0_14 -# 505| r0_16(glval) = VariableAddress[pt2] : -# 505| r0_17(glval) = FieldAddress[x] : r0_16 -# 505| r0_18(glval) = VariableAddress[x] : -# 505| r0_19(int) = Load : r0_18, m0_3 -# 505| m0_20(int) = Store : r0_17, r0_19 -# 505| r0_21(glval) = FieldAddress[y] : r0_16 -# 505| r0_22(int) = Constant[0] : -# 505| mu0_23(int) = Store : r0_21, r0_22 -# 506| r0_24(glval) = VariableAddress[pt3] : -# 506| r0_25(glval) = FieldAddress[x] : r0_24 -# 506| r0_26(int) = Constant[0] : -# 506| m0_27(int) = Store : r0_25, r0_26 -# 506| r0_28(glval) = FieldAddress[y] : r0_24 +# 504| m0_7(Point) = Uninitialized : r0_6 +# 504| r0_8(glval) = FieldAddress[x] : r0_6 +# 504| r0_9(glval) = VariableAddress[x] : +# 504| r0_10(int) = Load : r0_9, m0_3 +# 504| m0_11(int) = Store : r0_8, r0_10 +# 504| r0_12(glval) = FieldAddress[y] : r0_6 +# 504| r0_13(glval) = VariableAddress[f] : +# 504| r0_14(float) = Load : r0_13, m0_5 +# 504| r0_15(int) = Convert : r0_14 +# 504| mu0_16(int) = Store : r0_12, r0_15 +# 505| r0_17(glval) = VariableAddress[pt2] : +# 505| m0_18(Point) = Uninitialized : r0_17 +# 505| r0_19(glval) = FieldAddress[x] : r0_17 +# 505| r0_20(glval) = VariableAddress[x] : +# 505| r0_21(int) = Load : r0_20, m0_3 +# 505| m0_22(int) = Store : r0_19, r0_21 +# 505| r0_23(glval) = FieldAddress[y] : r0_17 +# 505| r0_24(int) = Constant[0] : +# 505| mu0_25(int) = Store : r0_23, r0_24 +# 506| r0_26(glval) = VariableAddress[pt3] : +# 506| m0_27(Point) = Uninitialized : r0_26 +# 506| r0_28(glval) = FieldAddress[x] : r0_26 # 506| r0_29(int) = Constant[0] : -# 506| mu0_30(int) = Store : r0_28, r0_29 -# 508| r0_31(glval) = VariableAddress[x1] : -# 508| r0_32(int) = Constant[1] : -# 508| m0_33(int) = Store : r0_31, r0_32 -# 509| r0_34(glval) = VariableAddress[x2] : -# 509| r0_35(int) = Constant[0] : -# 509| m0_36(int) = Store : r0_34, r0_35 -# 510| v0_37(void) = NoOp : -# 503| v0_38(void) = ReturnVoid : -# 503| v0_39(void) = UnmodeledUse : mu* -# 503| v0_40(void) = ExitFunction : +# 506| m0_30(int) = Store : r0_28, r0_29 +# 506| r0_31(glval) = FieldAddress[y] : r0_26 +# 506| r0_32(int) = Constant[0] : +# 506| mu0_33(int) = Store : r0_31, r0_32 +# 508| r0_34(glval) = VariableAddress[x1] : +# 508| r0_35(int) = Constant[1] : +# 508| m0_36(int) = Store : r0_34, r0_35 +# 509| r0_37(glval) = VariableAddress[x2] : +# 509| r0_38(int) = Constant[0] : +# 509| m0_39(int) = Store : r0_37, r0_38 +# 510| v0_40(void) = NoOp : +# 503| v0_41(void) = ReturnVoid : +# 503| v0_42(void) = UnmodeledUse : mu* +# 503| v0_43(void) = ExitFunction : # 512| NestedInitList(int, float) -> void # 512| Block 0 @@ -2196,68 +2199,72 @@ ir.cpp: # 512| r0_4(glval) = VariableAddress[f] : # 512| m0_5(float) = InitializeParameter[f] : r0_4 # 513| r0_6(glval) = VariableAddress[r1] : -# 513| r0_7(glval) = FieldAddress[topLeft] : r0_6 -# 513| r0_8(Point) = Constant[0] : -# 513| m0_9(Point) = Store : r0_7, r0_8 -# 513| r0_10(glval) = FieldAddress[bottomRight] : r0_6 -# 513| r0_11(Point) = Constant[0] : -# 513| mu0_12(Point) = Store : r0_10, r0_11 -# 514| r0_13(glval) = VariableAddress[r2] : -# 514| r0_14(glval) = FieldAddress[topLeft] : r0_13 -# 514| r0_15(glval) = FieldAddress[x] : r0_14 -# 514| r0_16(glval) = VariableAddress[x] : -# 514| r0_17(int) = Load : r0_16, m0_3 -# 514| m0_18(int) = Store : r0_15, r0_17 -# 514| r0_19(glval) = FieldAddress[y] : r0_14 -# 514| r0_20(glval) = VariableAddress[f] : -# 514| r0_21(float) = Load : r0_20, m0_5 -# 514| r0_22(int) = Convert : r0_21 -# 514| mu0_23(int) = Store : r0_19, r0_22 -# 514| r0_24(glval) = FieldAddress[bottomRight] : r0_13 -# 514| r0_25(Point) = Constant[0] : -# 514| mu0_26(Point) = Store : r0_24, r0_25 -# 515| r0_27(glval) = VariableAddress[r3] : -# 515| r0_28(glval) = FieldAddress[topLeft] : r0_27 -# 515| r0_29(glval) = FieldAddress[x] : r0_28 -# 515| r0_30(glval) = VariableAddress[x] : -# 515| r0_31(int) = Load : r0_30, m0_3 -# 515| m0_32(int) = Store : r0_29, r0_31 -# 515| r0_33(glval) = FieldAddress[y] : r0_28 -# 515| r0_34(glval) = VariableAddress[f] : -# 515| r0_35(float) = Load : r0_34, m0_5 -# 515| r0_36(int) = Convert : r0_35 -# 515| mu0_37(int) = Store : r0_33, r0_36 -# 515| r0_38(glval) = FieldAddress[bottomRight] : r0_27 -# 515| r0_39(glval) = FieldAddress[x] : r0_38 -# 515| r0_40(glval) = VariableAddress[x] : -# 515| r0_41(int) = Load : r0_40, m0_3 -# 515| mu0_42(int) = Store : r0_39, r0_41 -# 515| r0_43(glval) = FieldAddress[y] : r0_38 -# 515| r0_44(glval) = VariableAddress[f] : -# 515| r0_45(float) = Load : r0_44, m0_5 -# 515| r0_46(int) = Convert : r0_45 -# 515| mu0_47(int) = Store : r0_43, r0_46 -# 516| r0_48(glval) = VariableAddress[r4] : -# 516| r0_49(glval) = FieldAddress[topLeft] : r0_48 -# 516| r0_50(glval) = FieldAddress[x] : r0_49 -# 516| r0_51(glval) = VariableAddress[x] : -# 516| r0_52(int) = Load : r0_51, m0_3 -# 516| m0_53(int) = Store : r0_50, r0_52 -# 516| r0_54(glval) = FieldAddress[y] : r0_49 -# 516| r0_55(int) = Constant[0] : -# 516| mu0_56(int) = Store : r0_54, r0_55 -# 516| r0_57(glval) = FieldAddress[bottomRight] : r0_48 -# 516| r0_58(glval) = FieldAddress[x] : r0_57 -# 516| r0_59(glval) = VariableAddress[x] : -# 516| r0_60(int) = Load : r0_59, m0_3 -# 516| mu0_61(int) = Store : r0_58, r0_60 -# 516| r0_62(glval) = FieldAddress[y] : r0_57 -# 516| r0_63(int) = Constant[0] : -# 516| mu0_64(int) = Store : r0_62, r0_63 -# 517| v0_65(void) = NoOp : -# 512| v0_66(void) = ReturnVoid : -# 512| v0_67(void) = UnmodeledUse : mu* -# 512| v0_68(void) = ExitFunction : +# 513| m0_7(Rect) = Uninitialized : r0_6 +# 513| r0_8(glval) = FieldAddress[topLeft] : r0_6 +# 513| r0_9(Point) = Constant[0] : +# 513| m0_10(Point) = Store : r0_8, r0_9 +# 513| r0_11(glval) = FieldAddress[bottomRight] : r0_6 +# 513| r0_12(Point) = Constant[0] : +# 513| mu0_13(Point) = Store : r0_11, r0_12 +# 514| r0_14(glval) = VariableAddress[r2] : +# 514| m0_15(Rect) = Uninitialized : r0_14 +# 514| r0_16(glval) = FieldAddress[topLeft] : r0_14 +# 514| r0_17(glval) = FieldAddress[x] : r0_16 +# 514| r0_18(glval) = VariableAddress[x] : +# 514| r0_19(int) = Load : r0_18, m0_3 +# 514| m0_20(int) = Store : r0_17, r0_19 +# 514| r0_21(glval) = FieldAddress[y] : r0_16 +# 514| r0_22(glval) = VariableAddress[f] : +# 514| r0_23(float) = Load : r0_22, m0_5 +# 514| r0_24(int) = Convert : r0_23 +# 514| mu0_25(int) = Store : r0_21, r0_24 +# 514| r0_26(glval) = FieldAddress[bottomRight] : r0_14 +# 514| r0_27(Point) = Constant[0] : +# 514| mu0_28(Point) = Store : r0_26, r0_27 +# 515| r0_29(glval) = VariableAddress[r3] : +# 515| m0_30(Rect) = Uninitialized : r0_29 +# 515| r0_31(glval) = FieldAddress[topLeft] : r0_29 +# 515| r0_32(glval) = FieldAddress[x] : r0_31 +# 515| r0_33(glval) = VariableAddress[x] : +# 515| r0_34(int) = Load : r0_33, m0_3 +# 515| m0_35(int) = Store : r0_32, r0_34 +# 515| r0_36(glval) = FieldAddress[y] : r0_31 +# 515| r0_37(glval) = VariableAddress[f] : +# 515| r0_38(float) = Load : r0_37, m0_5 +# 515| r0_39(int) = Convert : r0_38 +# 515| mu0_40(int) = Store : r0_36, r0_39 +# 515| r0_41(glval) = FieldAddress[bottomRight] : r0_29 +# 515| r0_42(glval) = FieldAddress[x] : r0_41 +# 515| r0_43(glval) = VariableAddress[x] : +# 515| r0_44(int) = Load : r0_43, m0_3 +# 515| mu0_45(int) = Store : r0_42, r0_44 +# 515| r0_46(glval) = FieldAddress[y] : r0_41 +# 515| r0_47(glval) = VariableAddress[f] : +# 515| r0_48(float) = Load : r0_47, m0_5 +# 515| r0_49(int) = Convert : r0_48 +# 515| mu0_50(int) = Store : r0_46, r0_49 +# 516| r0_51(glval) = VariableAddress[r4] : +# 516| m0_52(Rect) = Uninitialized : r0_51 +# 516| r0_53(glval) = FieldAddress[topLeft] : r0_51 +# 516| r0_54(glval) = FieldAddress[x] : r0_53 +# 516| r0_55(glval) = VariableAddress[x] : +# 516| r0_56(int) = Load : r0_55, m0_3 +# 516| m0_57(int) = Store : r0_54, r0_56 +# 516| r0_58(glval) = FieldAddress[y] : r0_53 +# 516| r0_59(int) = Constant[0] : +# 516| mu0_60(int) = Store : r0_58, r0_59 +# 516| r0_61(glval) = FieldAddress[bottomRight] : r0_51 +# 516| r0_62(glval) = FieldAddress[x] : r0_61 +# 516| r0_63(glval) = VariableAddress[x] : +# 516| r0_64(int) = Load : r0_63, m0_3 +# 516| mu0_65(int) = Store : r0_62, r0_64 +# 516| r0_66(glval) = FieldAddress[y] : r0_61 +# 516| r0_67(int) = Constant[0] : +# 516| mu0_68(int) = Store : r0_66, r0_67 +# 517| v0_69(void) = NoOp : +# 512| v0_70(void) = ReturnVoid : +# 512| v0_71(void) = UnmodeledUse : mu* +# 512| v0_72(void) = ExitFunction : # 519| ArrayInit(int, float) -> void # 519| Block 0 @@ -2268,40 +2275,43 @@ ir.cpp: # 519| r0_4(glval) = VariableAddress[f] : # 519| m0_5(float) = InitializeParameter[f] : r0_4 # 520| r0_6(glval) = VariableAddress[a1] : -# 520| r0_7(int) = Constant[0] : -# 520| r0_8(glval) = PointerAdd : r0_6, r0_7 -# 520| r0_9(unknown[12]) = Constant[0] : -# 520| mu0_10(unknown[12]) = Store : r0_8, r0_9 -# 521| r0_11(glval) = VariableAddress[a2] : -# 521| r0_12(int) = Constant[0] : -# 521| r0_13(glval) = PointerAdd : r0_11, r0_12 -# 521| r0_14(glval) = VariableAddress[x] : -# 521| r0_15(int) = Load : r0_14, m0_3 -# 521| mu0_16(int) = Store : r0_13, r0_15 -# 521| r0_17(int) = Constant[1] : -# 521| r0_18(glval) = PointerAdd : r0_11, r0_17 -# 521| r0_19(glval) = VariableAddress[f] : -# 521| r0_20(float) = Load : r0_19, m0_5 -# 521| r0_21(int) = Convert : r0_20 -# 521| mu0_22(int) = Store : r0_18, r0_21 -# 521| r0_23(int) = Constant[2] : -# 521| r0_24(glval) = PointerAdd : r0_11, r0_23 -# 521| r0_25(int) = Constant[0] : -# 521| mu0_26(int) = Store : r0_24, r0_25 -# 522| r0_27(glval) = VariableAddress[a3] : -# 522| r0_28(int) = Constant[0] : -# 522| r0_29(glval) = PointerAdd : r0_27, r0_28 -# 522| r0_30(glval) = VariableAddress[x] : -# 522| r0_31(int) = Load : r0_30, m0_3 -# 522| mu0_32(int) = Store : r0_29, r0_31 -# 522| r0_33(int) = Constant[1] : -# 522| r0_34(glval) = PointerAdd : r0_27, r0_33 -# 522| r0_35(unknown[8]) = Constant[0] : -# 522| mu0_36(unknown[8]) = Store : r0_34, r0_35 -# 523| v0_37(void) = NoOp : -# 519| v0_38(void) = ReturnVoid : -# 519| v0_39(void) = UnmodeledUse : mu* -# 519| v0_40(void) = ExitFunction : +# 520| mu0_7(int[3]) = Uninitialized : r0_6 +# 520| r0_8(int) = Constant[0] : +# 520| r0_9(glval) = PointerAdd : r0_6, r0_8 +# 520| r0_10(unknown[12]) = Constant[0] : +# 520| mu0_11(unknown[12]) = Store : r0_9, r0_10 +# 521| r0_12(glval) = VariableAddress[a2] : +# 521| mu0_13(int[3]) = Uninitialized : r0_12 +# 521| r0_14(int) = Constant[0] : +# 521| r0_15(glval) = PointerAdd : r0_12, r0_14 +# 521| r0_16(glval) = VariableAddress[x] : +# 521| r0_17(int) = Load : r0_16, m0_3 +# 521| mu0_18(int) = Store : r0_15, r0_17 +# 521| r0_19(int) = Constant[1] : +# 521| r0_20(glval) = PointerAdd : r0_12, r0_19 +# 521| r0_21(glval) = VariableAddress[f] : +# 521| r0_22(float) = Load : r0_21, m0_5 +# 521| r0_23(int) = Convert : r0_22 +# 521| mu0_24(int) = Store : r0_20, r0_23 +# 521| r0_25(int) = Constant[2] : +# 521| r0_26(glval) = PointerAdd : r0_12, r0_25 +# 521| r0_27(int) = Constant[0] : +# 521| mu0_28(int) = Store : r0_26, r0_27 +# 522| r0_29(glval) = VariableAddress[a3] : +# 522| mu0_30(int[3]) = Uninitialized : r0_29 +# 522| r0_31(int) = Constant[0] : +# 522| r0_32(glval) = PointerAdd : r0_29, r0_31 +# 522| r0_33(glval) = VariableAddress[x] : +# 522| r0_34(int) = Load : r0_33, m0_3 +# 522| mu0_35(int) = Store : r0_32, r0_34 +# 522| r0_36(int) = Constant[1] : +# 522| r0_37(glval) = PointerAdd : r0_29, r0_36 +# 522| r0_38(unknown[8]) = Constant[0] : +# 522| mu0_39(unknown[8]) = Store : r0_37, r0_38 +# 523| v0_40(void) = NoOp : +# 519| v0_41(void) = ReturnVoid : +# 519| v0_42(void) = UnmodeledUse : mu* +# 519| v0_43(void) = ExitFunction : # 530| UnionInit(int, float) -> void # 530| Block 0 @@ -2312,15 +2322,16 @@ ir.cpp: # 530| r0_4(glval) = VariableAddress[f] : # 530| m0_5(float) = InitializeParameter[f] : r0_4 # 531| r0_6(glval) = VariableAddress[u1] : -# 531| r0_7(glval) = FieldAddress[d] : r0_6 -# 531| r0_8(glval) = VariableAddress[f] : -# 531| r0_9(float) = Load : r0_8, m0_5 -# 531| r0_10(double) = Convert : r0_9 -# 531| m0_11(double) = Store : r0_7, r0_10 -# 533| v0_12(void) = NoOp : -# 530| v0_13(void) = ReturnVoid : -# 530| v0_14(void) = UnmodeledUse : mu* -# 530| v0_15(void) = ExitFunction : +# 531| m0_7(U) = Uninitialized : r0_6 +# 531| r0_8(glval) = FieldAddress[d] : r0_6 +# 531| r0_9(glval) = VariableAddress[f] : +# 531| r0_10(float) = Load : r0_9, m0_5 +# 531| r0_11(double) = Convert : r0_10 +# 531| m0_12(double) = Store : r0_8, r0_11 +# 533| v0_13(void) = NoOp : +# 530| v0_14(void) = ReturnVoid : +# 530| v0_15(void) = UnmodeledUse : mu* +# 530| v0_16(void) = ExitFunction : # 535| EarlyReturn(int, int) -> void # 535| Block 0 @@ -2479,41 +2490,45 @@ ir.cpp: # 575| r0_18(glval) = VariableAddress[b] : # 575| m0_19(char[2]) = Uninitialized : r0_18 # 576| r0_20(glval) = VariableAddress[c] : -# 576| r0_21(int) = Constant[0] : -# 576| r0_22(glval) = PointerAdd : r0_20, r0_21 -# 576| r0_23(unknown[2]) = Constant[0] : -# 576| mu0_24(unknown[2]) = Store : r0_22, r0_23 -# 577| r0_25(glval) = VariableAddress[d] : -# 577| r0_26(int) = Constant[0] : -# 577| r0_27(glval) = PointerAdd : r0_25, r0_26 -# 577| r0_28(char) = Constant[0] : -# 577| mu0_29(char) = Store : r0_27, r0_28 -# 577| r0_30(int) = Constant[1] : -# 577| r0_31(glval) = PointerAdd : r0_25, r0_30 -# 577| r0_32(char) = Constant[0] : -# 577| mu0_33(char) = Store : r0_31, r0_32 -# 578| r0_34(glval) = VariableAddress[e] : -# 578| r0_35(int) = Constant[0] : -# 578| r0_36(glval) = PointerAdd : r0_34, r0_35 -# 578| r0_37(char) = Constant[0] : -# 578| mu0_38(char) = Store : r0_36, r0_37 -# 578| r0_39(int) = Constant[1] : -# 578| r0_40(glval) = PointerAdd : r0_34, r0_39 -# 578| r0_41(char) = Constant[1] : -# 578| mu0_42(char) = Store : r0_40, r0_41 -# 579| r0_43(glval) = VariableAddress[f] : -# 579| r0_44(int) = Constant[0] : -# 579| r0_45(glval) = PointerAdd : r0_43, r0_44 -# 579| r0_46(char) = Constant[0] : -# 579| mu0_47(char) = Store : r0_45, r0_46 -# 579| r0_48(int) = Constant[1] : -# 579| r0_49(glval) = PointerAdd : r0_43, r0_48 -# 579| r0_50(unknown[2]) = Constant[0] : -# 579| mu0_51(unknown[2]) = Store : r0_49, r0_50 -# 580| v0_52(void) = NoOp : -# 571| v0_53(void) = ReturnVoid : -# 571| v0_54(void) = UnmodeledUse : mu* -# 571| v0_55(void) = ExitFunction : +# 576| mu0_21(char[2]) = Uninitialized : r0_20 +# 576| r0_22(int) = Constant[0] : +# 576| r0_23(glval) = PointerAdd : r0_20, r0_22 +# 576| r0_24(unknown[2]) = Constant[0] : +# 576| mu0_25(unknown[2]) = Store : r0_23, r0_24 +# 577| r0_26(glval) = VariableAddress[d] : +# 577| mu0_27(char[2]) = Uninitialized : r0_26 +# 577| r0_28(int) = Constant[0] : +# 577| r0_29(glval) = PointerAdd : r0_26, r0_28 +# 577| r0_30(char) = Constant[0] : +# 577| mu0_31(char) = Store : r0_29, r0_30 +# 577| r0_32(int) = Constant[1] : +# 577| r0_33(glval) = PointerAdd : r0_26, r0_32 +# 577| r0_34(char) = Constant[0] : +# 577| mu0_35(char) = Store : r0_33, r0_34 +# 578| r0_36(glval) = VariableAddress[e] : +# 578| mu0_37(char[2]) = Uninitialized : r0_36 +# 578| r0_38(int) = Constant[0] : +# 578| r0_39(glval) = PointerAdd : r0_36, r0_38 +# 578| r0_40(char) = Constant[0] : +# 578| mu0_41(char) = Store : r0_39, r0_40 +# 578| r0_42(int) = Constant[1] : +# 578| r0_43(glval) = PointerAdd : r0_36, r0_42 +# 578| r0_44(char) = Constant[1] : +# 578| mu0_45(char) = Store : r0_43, r0_44 +# 579| r0_46(glval) = VariableAddress[f] : +# 579| mu0_47(char[3]) = Uninitialized : r0_46 +# 579| r0_48(int) = Constant[0] : +# 579| r0_49(glval) = PointerAdd : r0_46, r0_48 +# 579| r0_50(char) = Constant[0] : +# 579| mu0_51(char) = Store : r0_49, r0_50 +# 579| r0_52(int) = Constant[1] : +# 579| r0_53(glval) = PointerAdd : r0_46, r0_52 +# 579| r0_54(unknown[2]) = Constant[0] : +# 579| mu0_55(unknown[2]) = Store : r0_53, r0_54 +# 580| v0_56(void) = NoOp : +# 571| v0_57(void) = ReturnVoid : +# 571| v0_58(void) = UnmodeledUse : mu* +# 571| v0_59(void) = ExitFunction : # 584| VarArgs() -> void # 584| Block 0 @@ -3912,10 +3927,11 @@ ir.cpp: # 961| v0_0(void) = EnterFunction : # 961| mu0_1(unknown) = UnmodeledDefinition : # 962| r0_2(glval) = VariableAddress[a1] : -# 962| r0_3(int) = Constant[0] : -# 962| r0_4(glval) = PointerAdd : r0_2, r0_3 -# 962| r0_5(unknown[8]) = Constant[0] : -# 962| mu0_6(unknown[8]) = Store : r0_4, r0_5 +# 962| mu0_3(int[1000]) = Uninitialized : r0_2 +# 962| r0_4(int) = Constant[0] : +# 962| r0_5(glval) = PointerAdd : r0_2, r0_4 +# 962| r0_6(unknown[8]) = Constant[0] : +# 962| mu0_7(unknown[8]) = Store : r0_5, r0_6 #-----| Goto -> Block 2 # 962| Block 1 From 3715215b3f46c6bc860696c474bbf964609e8fcd Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 21 Nov 2018 00:14:44 -0800 Subject: [PATCH 62/94] C++: Add IR support for ConditionalDeclExpr Also fixes several places in the library that weren't handling `ConditionalDeclExpr` correctly. --- cpp/ql/src/semmle/code/cpp/Variable.qll | 3 +- cpp/ql/src/semmle/code/cpp/exprs/Expr.qll | 3 +- .../internal/TranslatedDeclarationEntry.qll | 36 +++++ .../raw/internal/TranslatedElement.qll | 4 + .../raw/internal/TranslatedExpr.qll | 55 +++++++ .../library-tests/ir/ir/PrintAST.expected | 116 ++++++++++++++ .../ir/ir/aliased_ssa_ir.expected | 144 ++++++++++++++++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 21 +++ .../test/library-tests/ir/ir/raw_ir.expected | 144 ++++++++++++++++++ .../ir/ir/ssa_block_count.expected | 2 + .../ir/ir/unaliased_ssa_ir.expected | 144 ++++++++++++++++++ 11 files changed, 670 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/Variable.qll b/cpp/ql/src/semmle/code/cpp/Variable.qll index 958a50ebfc8..c93652f4d8a 100644 --- a/cpp/ql/src/semmle/code/cpp/Variable.qll +++ b/cpp/ql/src/semmle/code/cpp/Variable.qll @@ -291,7 +291,8 @@ class LocalVariable extends LocalScopeVariable, @localvariable { override Type getType() { localvariables(underlyingElement(this),unresolveElement(result),_) } override Function getFunction() { - exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result) + exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result) or + exists(ConditionDeclExpr e | e.getVariable() = this and e.getEnclosingFunction() = result) } } diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll index ccad37645cb..a453d817b00 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll @@ -28,7 +28,8 @@ class Expr extends StmtParent, @expr { result = this.getParent().(Expr).getEnclosingStmt() or result = this.getParent().(Stmt) or exists(Expr other | result = other.getEnclosingStmt() and other.getConversion() = this) or - exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d) + exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d) or + exists(ConditionDeclExpr cde, LocalVariable v | cde.getVariable() = v and v.getInitializer().getExpr() = this and result = cde.getEnclosingStmt()) } /** Gets the enclosing variable of this expression, if any. */ diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll index 53ab0725200..da9a3f1c2dd 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll @@ -186,3 +186,39 @@ class TranslatedVariableDeclarationEntry extends TranslatedVariableDeclaration, result = var } } + +TranslatedConditionDecl getTranslatedConditionDecl(ConditionDeclExpr expr) { + result.getAST() = expr +} + +/** + * Represents the IR translation of the declaration portion of a `ConditionDeclExpr`, which + * represents the variable declared in code such as: + * ``` + * if (int* p = &x) { + * } + * ``` + */ +class TranslatedConditionDecl extends TranslatedVariableDeclaration, TTranslatedConditionDecl { + ConditionDeclExpr conditionDeclExpr; + + TranslatedConditionDecl() { + this = TTranslatedConditionDecl(conditionDeclExpr) + } + + override string toString() { + result = "decl: " + conditionDeclExpr.toString() + } + + override Locatable getAST() { + result = conditionDeclExpr + } + + override Function getFunction() { + result = conditionDeclExpr.getEnclosingFunction() + } + + override LocalVariable getVariable() { + result = conditionDeclExpr.getVariable() + } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 1be620d1206..b91bc62099b 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -319,6 +319,10 @@ newtype TTranslatedElement = // An allocation size for a `new` or `new[]` expression TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { not ignoreExpr(newExpr) + } or + // The declaration/initialization part of a `ConditionDeclExpr` + TTranslatedConditionDecl(ConditionDeclExpr expr) { + not ignoreExpr(expr) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index de70d44d17c..175f710f265 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.internal.OperandTag private import semmle.code.cpp.ir.internal.TempVariableTag private import InstructionTag private import TranslatedCondition +private import TranslatedDeclarationEntry private import TranslatedElement private import TranslatedFunction private import TranslatedInitialization @@ -2914,3 +2915,57 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr { none() } } + +/** + * The IR translation of a `ConditionDeclExpr`, which represents the value of the declared variable + * after conversion to `bool` in code such as: + * ``` + * if (int* p = &x) { + * } + * ``` + */ +class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr { + ConditionDeclExpr condDeclExpr; + + TranslatedConditionDeclExpr() { + condDeclExpr = expr + } + + override final Instruction getFirstInstruction() { + result = getDecl().getFirstInstruction() + } + + override final TranslatedElement getChild(int id) { + id = 0 and result = getDecl() or + id = 1 and result = getConditionExpr() + } + + override Instruction getResult() { + result = getConditionExpr().getResult() + } + + override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { + none() + } + + override Instruction getChildSuccessor(TranslatedElement child) { + ( + child = getDecl() and + result = getConditionExpr().getFirstInstruction() + ) or + child = getConditionExpr() and result = getParent().getChildSuccessor(this) + } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, + boolean isGLValue) { + none() + } + + private TranslatedConditionDecl getDecl() { + result = getTranslatedConditionDecl(condDeclExpr) + } + + private TranslatedExpr getConditionExpr() { + result = getTranslatedExpr(condDeclExpr.getExpr().getFullyConverted()) + } +} diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 884abe554a6..b9080440dc3 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -6335,3 +6335,119 @@ ir.cpp: # 963| Type = int # 963| Value = 900 # 963| ValueCategory = prvalue +# 966| IfStmtWithDeclaration(int, int) -> void +# 966| params: +# 966| 0: x +# 966| Type = int +# 966| 1: y +# 966| Type = int +# 966| body: { ... } +# 967| 0: if (...) ... +# 967| 0: (condition decl) +# 967| Type = bool +# 967| ValueCategory = prvalue +# 967| 0: b +# 967| Type = bool +# 967| ValueCategory = prvalue(load) +# 967| 1: { ... } +# 968| 0: ExprStmt +# 968| 0: ... = ... +# 968| Type = int +# 968| ValueCategory = lvalue +# 968| 0: x +# 968| Type = int +# 968| ValueCategory = lvalue +# 968| 1: 5 +# 968| Type = int +# 968| Value = 5 +# 968| ValueCategory = prvalue +# 970| 2: if (...) ... +# 970| 0: (condition decl) +# 970| Type = bool +# 970| ValueCategory = prvalue +# 970| 0: (bool)... +# 970| Conversion = conversion to bool +# 970| Type = bool +# 970| ValueCategory = prvalue +# 970| expr: z +# 970| Type = int +# 970| ValueCategory = prvalue(load) +# 970| 1: { ... } +# 971| 0: ExprStmt +# 971| 0: ... = ... +# 971| Type = int +# 971| ValueCategory = lvalue +# 971| 0: y +# 971| Type = int +# 971| ValueCategory = lvalue +# 971| 1: 7 +# 971| Type = int +# 971| Value = 7 +# 971| ValueCategory = prvalue +# 973| 2: if (...) ... +# 973| 0: (condition decl) +# 973| Type = bool +# 973| ValueCategory = prvalue +# 973| 0: (bool)... +# 973| Conversion = conversion to bool +# 973| Type = bool +# 973| ValueCategory = prvalue +# 973| expr: p +# 973| Type = int * +# 973| ValueCategory = prvalue(load) +# 973| 1: { ... } +# 974| 0: ExprStmt +# 974| 0: ... = ... +# 974| Type = int +# 974| ValueCategory = lvalue +# 974| 0: * ... +# 974| Type = int +# 974| ValueCategory = lvalue +# 974| 0: p +# 974| Type = int * +# 974| ValueCategory = prvalue(load) +# 974| 1: 2 +# 974| Type = int +# 974| Value = 2 +# 974| ValueCategory = prvalue +# 976| 1: return ... +# 978| WhileStmtWithDeclaration(int, int) -> void +# 978| params: +# 978| 0: x +# 978| Type = int +# 978| 1: y +# 978| Type = int +# 978| body: { ... } +# 979| 0: while (...) ... +# 979| 0: (condition decl) +# 979| Type = bool +# 979| ValueCategory = prvalue +# 979| 0: b +# 979| Type = bool +# 979| ValueCategory = prvalue(load) +# 979| 1: { ... } +# 981| 1: while (...) ... +# 981| 0: (condition decl) +# 981| Type = bool +# 981| ValueCategory = prvalue +# 981| 0: (bool)... +# 981| Conversion = conversion to bool +# 981| Type = bool +# 981| ValueCategory = prvalue +# 981| expr: z +# 981| Type = int +# 981| ValueCategory = prvalue(load) +# 981| 1: { ... } +# 983| 2: while (...) ... +# 983| 0: (condition decl) +# 983| Type = bool +# 983| ValueCategory = prvalue +# 983| 0: (bool)... +# 983| Conversion = conversion to bool +# 983| Type = bool +# 983| ValueCategory = prvalue +# 983| expr: p +# 983| Type = int * +# 983| ValueCategory = prvalue(load) +# 983| 1: { ... } +# 985| 3: return ... diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected index 36c6cff9761..f352da9bd94 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected @@ -3968,3 +3968,147 @@ ir.cpp: # 962| r3_6(unknown[3588]) = Constant[0] : # 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6 #-----| Goto -> Block 2 + +# 966| IfStmtWithDeclaration(int, int) -> void +# 966| Block 0 +# 966| v0_0(void) = EnterFunction : +# 966| mu0_1(unknown) = UnmodeledDefinition : +# 966| r0_2(glval) = VariableAddress[x] : +# 966| m0_3(int) = InitializeParameter[x] : r0_2 +# 966| r0_4(glval) = VariableAddress[y] : +# 966| m0_5(int) = InitializeParameter[y] : r0_4 +# 967| r0_6(glval) = VariableAddress[b] : +# 967| r0_7(glval) = VariableAddress[x] : +# 967| r0_8(int) = Load : r0_7, m0_3 +# 967| r0_9(glval) = VariableAddress[y] : +# 967| r0_10(int) = Load : r0_9, m0_5 +# 967| r0_11(bool) = CompareLT : r0_8, r0_10 +# 967| m0_12(bool) = Store : r0_6, r0_11 +# 967| r0_13(glval) = VariableAddress[b] : +# 967| r0_14(bool) = Load : r0_13, m0_12 +# 967| v0_15(void) = ConditionalBranch : r0_14 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 968| Block 1 +# 968| r1_0(int) = Constant[5] : +# 968| r1_1(glval) = VariableAddress[x] : +# 968| m1_2(int) = Store : r1_1, r1_0 +#-----| Goto -> Block 6 + +# 970| Block 2 +# 970| r2_0(glval) = VariableAddress[z] : +# 970| r2_1(glval) = VariableAddress[x] : +# 970| r2_2(int) = Load : r2_1, m0_3 +# 970| r2_3(glval) = VariableAddress[y] : +# 970| r2_4(int) = Load : r2_3, m0_5 +# 970| r2_5(int) = Add : r2_2, r2_4 +# 970| m2_6(int) = Store : r2_0, r2_5 +# 970| r2_7(glval) = VariableAddress[z] : +# 970| r2_8(int) = Load : r2_7, m2_6 +# 970| r2_9(int) = Constant[0] : +# 970| r2_10(bool) = CompareNE : r2_8, r2_9 +# 970| v2_11(void) = ConditionalBranch : r2_10 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 971| Block 3 +# 971| r3_0(int) = Constant[7] : +# 971| r3_1(glval) = VariableAddress[y] : +# 971| m3_2(int) = Store : r3_1, r3_0 +#-----| Goto -> Block 6 + +# 973| Block 4 +# 973| r4_0(glval) = VariableAddress[p] : +# 973| r4_1(glval) = VariableAddress[x] : +# 973| m4_2(int *) = Store : r4_0, r4_1 +# 973| r4_3(glval) = VariableAddress[p] : +# 973| r4_4(int *) = Load : r4_3, m4_2 +# 973| r4_5(int *) = Constant[0] : +# 973| r4_6(bool) = CompareNE : r4_4, r4_5 +# 973| v4_7(void) = ConditionalBranch : r4_6 +#-----| False -> Block 6 +#-----| True -> Block 5 + +# 974| Block 5 +# 974| r5_0(int) = Constant[2] : +# 974| r5_1(glval) = VariableAddress[p] : +# 974| r5_2(int *) = Load : r5_1, m4_2 +# 974| m5_3(int) = Store : r5_2, r5_0 +#-----| Goto -> Block 6 + +# 976| Block 6 +# 976| v6_0(void) = NoOp : +# 966| v6_1(void) = ReturnVoid : +# 966| v6_2(void) = UnmodeledUse : mu* +# 966| v6_3(void) = ExitFunction : + +# 978| WhileStmtWithDeclaration(int, int) -> void +# 978| Block 0 +# 978| v0_0(void) = EnterFunction : +# 978| mu0_1(unknown) = UnmodeledDefinition : +# 978| r0_2(glval) = VariableAddress[x] : +# 978| m0_3(int) = InitializeParameter[x] : r0_2 +# 978| r0_4(glval) = VariableAddress[y] : +# 978| m0_5(int) = InitializeParameter[y] : r0_4 +#-----| Goto -> Block 7 + +# 979| Block 1 +# 979| v1_0(void) = NoOp : +#-----| Goto -> Block 7 + +# 981| Block 2 +# 981| r2_0(glval) = VariableAddress[z] : +# 981| r2_1(glval) = VariableAddress[x] : +# 981| r2_2(int) = Load : r2_1, m0_3 +# 981| r2_3(glval) = VariableAddress[y] : +# 981| r2_4(int) = Load : r2_3, m0_5 +# 981| r2_5(int) = Add : r2_2, r2_4 +# 981| m2_6(int) = Store : r2_0, r2_5 +# 981| r2_7(glval) = VariableAddress[z] : +# 981| r2_8(int) = Load : r2_7, m2_6 +# 981| r2_9(int) = Constant[0] : +# 981| r2_10(bool) = CompareNE : r2_8, r2_9 +# 981| v2_11(void) = ConditionalBranch : r2_10 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 981| Block 3 +# 981| v3_0(void) = NoOp : +#-----| Goto -> Block 2 + +# 983| Block 4 +# 983| r4_0(glval) = VariableAddress[p] : +# 983| r4_1(glval) = VariableAddress[x] : +# 983| m4_2(int *) = Store : r4_0, r4_1 +# 983| r4_3(glval) = VariableAddress[p] : +# 983| r4_4(int *) = Load : r4_3, m4_2 +# 983| r4_5(int *) = Constant[0] : +# 983| r4_6(bool) = CompareNE : r4_4, r4_5 +# 983| v4_7(void) = ConditionalBranch : r4_6 +#-----| False -> Block 6 +#-----| True -> Block 5 + +# 983| Block 5 +# 983| v5_0(void) = NoOp : +#-----| Goto -> Block 4 + +# 985| Block 6 +# 985| v6_0(void) = NoOp : +# 978| v6_1(void) = ReturnVoid : +# 978| v6_2(void) = UnmodeledUse : mu* +# 978| v6_3(void) = ExitFunction : + +# 979| Block 7 +# 979| r7_0(glval) = VariableAddress[b] : +# 979| r7_1(glval) = VariableAddress[x] : +# 979| r7_2(int) = Load : r7_1, m0_3 +# 979| r7_3(glval) = VariableAddress[y] : +# 979| r7_4(int) = Load : r7_3, m0_5 +# 979| r7_5(bool) = CompareLT : r7_2, r7_4 +# 979| m7_6(bool) = Store : r7_0, r7_5 +# 979| r7_7(glval) = VariableAddress[b] : +# 979| r7_8(bool) = Load : r7_7, m7_6 +# 979| v7_9(void) = ConditionalBranch : r7_8 +#-----| False -> Block 2 +#-----| True -> Block 1 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 3ff4c53c17e..95486aa55e1 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -963,6 +963,27 @@ int designatedInit() { return a1[900]; } +void IfStmtWithDeclaration(int x, int y) { + if (bool b = x < y) { + x = 5; + } + else if (int z = x + y) { + y = 7; + } + else if (int* p = &x) { + *p = 2; + } +} + +void WhileStmtWithDeclaration(int x, int y) { + while (bool b = x < y) { + } + while (int z = x + y) { + } + while (int* p = &x) { + } +} + #if 0 void OperatorDelete() { delete static_cast(nullptr); // No destructor diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 55facfbd340..d3a7ebbc417 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -3947,3 +3947,147 @@ ir.cpp: # 962| r3_6(unknown[3588]) = Constant[0] : # 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6 #-----| Goto -> Block 2 + +# 966| IfStmtWithDeclaration(int, int) -> void +# 966| Block 0 +# 966| v0_0(void) = EnterFunction : +# 966| mu0_1(unknown) = UnmodeledDefinition : +# 966| r0_2(glval) = VariableAddress[x] : +# 966| mu0_3(int) = InitializeParameter[x] : r0_2 +# 966| r0_4(glval) = VariableAddress[y] : +# 966| mu0_5(int) = InitializeParameter[y] : r0_4 +# 967| r0_6(glval) = VariableAddress[b] : +# 967| r0_7(glval) = VariableAddress[x] : +# 967| r0_8(int) = Load : r0_7, mu0_1 +# 967| r0_9(glval) = VariableAddress[y] : +# 967| r0_10(int) = Load : r0_9, mu0_1 +# 967| r0_11(bool) = CompareLT : r0_8, r0_10 +# 967| mu0_12(bool) = Store : r0_6, r0_11 +# 967| r0_13(glval) = VariableAddress[b] : +# 967| r0_14(bool) = Load : r0_13, mu0_1 +# 967| v0_15(void) = ConditionalBranch : r0_14 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 968| Block 1 +# 968| r1_0(int) = Constant[5] : +# 968| r1_1(glval) = VariableAddress[x] : +# 968| mu1_2(int) = Store : r1_1, r1_0 +#-----| Goto -> Block 6 + +# 970| Block 2 +# 970| r2_0(glval) = VariableAddress[z] : +# 970| r2_1(glval) = VariableAddress[x] : +# 970| r2_2(int) = Load : r2_1, mu0_1 +# 970| r2_3(glval) = VariableAddress[y] : +# 970| r2_4(int) = Load : r2_3, mu0_1 +# 970| r2_5(int) = Add : r2_2, r2_4 +# 970| mu2_6(int) = Store : r2_0, r2_5 +# 970| r2_7(glval) = VariableAddress[z] : +# 970| r2_8(int) = Load : r2_7, mu0_1 +# 970| r2_9(int) = Constant[0] : +# 970| r2_10(bool) = CompareNE : r2_8, r2_9 +# 970| v2_11(void) = ConditionalBranch : r2_10 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 971| Block 3 +# 971| r3_0(int) = Constant[7] : +# 971| r3_1(glval) = VariableAddress[y] : +# 971| mu3_2(int) = Store : r3_1, r3_0 +#-----| Goto -> Block 6 + +# 973| Block 4 +# 973| r4_0(glval) = VariableAddress[p] : +# 973| r4_1(glval) = VariableAddress[x] : +# 973| mu4_2(int *) = Store : r4_0, r4_1 +# 973| r4_3(glval) = VariableAddress[p] : +# 973| r4_4(int *) = Load : r4_3, mu0_1 +# 973| r4_5(int *) = Constant[0] : +# 973| r4_6(bool) = CompareNE : r4_4, r4_5 +# 973| v4_7(void) = ConditionalBranch : r4_6 +#-----| False -> Block 6 +#-----| True -> Block 5 + +# 974| Block 5 +# 974| r5_0(int) = Constant[2] : +# 974| r5_1(glval) = VariableAddress[p] : +# 974| r5_2(int *) = Load : r5_1, mu0_1 +# 974| mu5_3(int) = Store : r5_2, r5_0 +#-----| Goto -> Block 6 + +# 976| Block 6 +# 976| v6_0(void) = NoOp : +# 966| v6_1(void) = ReturnVoid : +# 966| v6_2(void) = UnmodeledUse : mu* +# 966| v6_3(void) = ExitFunction : + +# 978| WhileStmtWithDeclaration(int, int) -> void +# 978| Block 0 +# 978| v0_0(void) = EnterFunction : +# 978| mu0_1(unknown) = UnmodeledDefinition : +# 978| r0_2(glval) = VariableAddress[x] : +# 978| mu0_3(int) = InitializeParameter[x] : r0_2 +# 978| r0_4(glval) = VariableAddress[y] : +# 978| mu0_5(int) = InitializeParameter[y] : r0_4 +#-----| Goto -> Block 7 + +# 979| Block 1 +# 979| v1_0(void) = NoOp : +#-----| Goto -> Block 7 + +# 981| Block 2 +# 981| r2_0(glval) = VariableAddress[z] : +# 981| r2_1(glval) = VariableAddress[x] : +# 981| r2_2(int) = Load : r2_1, mu0_1 +# 981| r2_3(glval) = VariableAddress[y] : +# 981| r2_4(int) = Load : r2_3, mu0_1 +# 981| r2_5(int) = Add : r2_2, r2_4 +# 981| mu2_6(int) = Store : r2_0, r2_5 +# 981| r2_7(glval) = VariableAddress[z] : +# 981| r2_8(int) = Load : r2_7, mu0_1 +# 981| r2_9(int) = Constant[0] : +# 981| r2_10(bool) = CompareNE : r2_8, r2_9 +# 981| v2_11(void) = ConditionalBranch : r2_10 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 981| Block 3 +# 981| v3_0(void) = NoOp : +#-----| Goto -> Block 2 + +# 983| Block 4 +# 983| r4_0(glval) = VariableAddress[p] : +# 983| r4_1(glval) = VariableAddress[x] : +# 983| mu4_2(int *) = Store : r4_0, r4_1 +# 983| r4_3(glval) = VariableAddress[p] : +# 983| r4_4(int *) = Load : r4_3, mu0_1 +# 983| r4_5(int *) = Constant[0] : +# 983| r4_6(bool) = CompareNE : r4_4, r4_5 +# 983| v4_7(void) = ConditionalBranch : r4_6 +#-----| False -> Block 6 +#-----| True -> Block 5 + +# 983| Block 5 +# 983| v5_0(void) = NoOp : +#-----| Goto -> Block 4 + +# 985| Block 6 +# 985| v6_0(void) = NoOp : +# 978| v6_1(void) = ReturnVoid : +# 978| v6_2(void) = UnmodeledUse : mu* +# 978| v6_3(void) = ExitFunction : + +# 979| Block 7 +# 979| r7_0(glval) = VariableAddress[b] : +# 979| r7_1(glval) = VariableAddress[x] : +# 979| r7_2(int) = Load : r7_1, mu0_1 +# 979| r7_3(glval) = VariableAddress[y] : +# 979| r7_4(int) = Load : r7_3, mu0_1 +# 979| r7_5(bool) = CompareLT : r7_2, r7_4 +# 979| mu7_6(bool) = Store : r7_0, r7_5 +# 979| r7_7(glval) = VariableAddress[b] : +# 979| r7_8(bool) = Load : r7_7, mu0_1 +# 979| v7_9(void) = ConditionalBranch : r7_8 +#-----| False -> Block 2 +#-----| True -> Block 1 diff --git a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected index 0ef298fee3d..458c3c8220e 100644 --- a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected +++ b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected @@ -53,6 +53,7 @@ | IR: FunctionReferences | 1 | | IR: HierarchyConversions | 1 | | IR: IfStatements | 8 | +| IR: IfStmtWithDeclaration | 7 | | IR: InitArray | 1 | | IR: InitList | 1 | | IR: InitReference | 1 | @@ -92,6 +93,7 @@ | IR: VarArgs | 1 | | IR: VirtualMemberFunction | 1 | | IR: WhileStatements | 4 | +| IR: WhileStmtWithDeclaration | 8 | | IR: designatedInit | 4 | | IR: min | 4 | | IR: operator= | 1 | diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected index 98b4934e13c..f7cba2a08c9 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected @@ -3968,3 +3968,147 @@ ir.cpp: # 962| r3_6(unknown[3588]) = Constant[0] : # 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6 #-----| Goto -> Block 2 + +# 966| IfStmtWithDeclaration(int, int) -> void +# 966| Block 0 +# 966| v0_0(void) = EnterFunction : +# 966| mu0_1(unknown) = UnmodeledDefinition : +# 966| r0_2(glval) = VariableAddress[x] : +# 966| mu0_3(int) = InitializeParameter[x] : r0_2 +# 966| r0_4(glval) = VariableAddress[y] : +# 966| m0_5(int) = InitializeParameter[y] : r0_4 +# 967| r0_6(glval) = VariableAddress[b] : +# 967| r0_7(glval) = VariableAddress[x] : +# 967| r0_8(int) = Load : r0_7, mu0_1 +# 967| r0_9(glval) = VariableAddress[y] : +# 967| r0_10(int) = Load : r0_9, m0_5 +# 967| r0_11(bool) = CompareLT : r0_8, r0_10 +# 967| m0_12(bool) = Store : r0_6, r0_11 +# 967| r0_13(glval) = VariableAddress[b] : +# 967| r0_14(bool) = Load : r0_13, m0_12 +# 967| v0_15(void) = ConditionalBranch : r0_14 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 968| Block 1 +# 968| r1_0(int) = Constant[5] : +# 968| r1_1(glval) = VariableAddress[x] : +# 968| mu1_2(int) = Store : r1_1, r1_0 +#-----| Goto -> Block 6 + +# 970| Block 2 +# 970| r2_0(glval) = VariableAddress[z] : +# 970| r2_1(glval) = VariableAddress[x] : +# 970| r2_2(int) = Load : r2_1, mu0_1 +# 970| r2_3(glval) = VariableAddress[y] : +# 970| r2_4(int) = Load : r2_3, m0_5 +# 970| r2_5(int) = Add : r2_2, r2_4 +# 970| m2_6(int) = Store : r2_0, r2_5 +# 970| r2_7(glval) = VariableAddress[z] : +# 970| r2_8(int) = Load : r2_7, m2_6 +# 970| r2_9(int) = Constant[0] : +# 970| r2_10(bool) = CompareNE : r2_8, r2_9 +# 970| v2_11(void) = ConditionalBranch : r2_10 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 971| Block 3 +# 971| r3_0(int) = Constant[7] : +# 971| r3_1(glval) = VariableAddress[y] : +# 971| m3_2(int) = Store : r3_1, r3_0 +#-----| Goto -> Block 6 + +# 973| Block 4 +# 973| r4_0(glval) = VariableAddress[p] : +# 973| r4_1(glval) = VariableAddress[x] : +# 973| m4_2(int *) = Store : r4_0, r4_1 +# 973| r4_3(glval) = VariableAddress[p] : +# 973| r4_4(int *) = Load : r4_3, m4_2 +# 973| r4_5(int *) = Constant[0] : +# 973| r4_6(bool) = CompareNE : r4_4, r4_5 +# 973| v4_7(void) = ConditionalBranch : r4_6 +#-----| False -> Block 6 +#-----| True -> Block 5 + +# 974| Block 5 +# 974| r5_0(int) = Constant[2] : +# 974| r5_1(glval) = VariableAddress[p] : +# 974| r5_2(int *) = Load : r5_1, m4_2 +# 974| mu5_3(int) = Store : r5_2, r5_0 +#-----| Goto -> Block 6 + +# 976| Block 6 +# 976| v6_0(void) = NoOp : +# 966| v6_1(void) = ReturnVoid : +# 966| v6_2(void) = UnmodeledUse : mu* +# 966| v6_3(void) = ExitFunction : + +# 978| WhileStmtWithDeclaration(int, int) -> void +# 978| Block 0 +# 978| v0_0(void) = EnterFunction : +# 978| mu0_1(unknown) = UnmodeledDefinition : +# 978| r0_2(glval) = VariableAddress[x] : +# 978| mu0_3(int) = InitializeParameter[x] : r0_2 +# 978| r0_4(glval) = VariableAddress[y] : +# 978| m0_5(int) = InitializeParameter[y] : r0_4 +#-----| Goto -> Block 7 + +# 979| Block 1 +# 979| v1_0(void) = NoOp : +#-----| Goto -> Block 7 + +# 981| Block 2 +# 981| r2_0(glval) = VariableAddress[z] : +# 981| r2_1(glval) = VariableAddress[x] : +# 981| r2_2(int) = Load : r2_1, mu0_1 +# 981| r2_3(glval) = VariableAddress[y] : +# 981| r2_4(int) = Load : r2_3, m0_5 +# 981| r2_5(int) = Add : r2_2, r2_4 +# 981| m2_6(int) = Store : r2_0, r2_5 +# 981| r2_7(glval) = VariableAddress[z] : +# 981| r2_8(int) = Load : r2_7, m2_6 +# 981| r2_9(int) = Constant[0] : +# 981| r2_10(bool) = CompareNE : r2_8, r2_9 +# 981| v2_11(void) = ConditionalBranch : r2_10 +#-----| False -> Block 4 +#-----| True -> Block 3 + +# 981| Block 3 +# 981| v3_0(void) = NoOp : +#-----| Goto -> Block 2 + +# 983| Block 4 +# 983| r4_0(glval) = VariableAddress[p] : +# 983| r4_1(glval) = VariableAddress[x] : +# 983| m4_2(int *) = Store : r4_0, r4_1 +# 983| r4_3(glval) = VariableAddress[p] : +# 983| r4_4(int *) = Load : r4_3, m4_2 +# 983| r4_5(int *) = Constant[0] : +# 983| r4_6(bool) = CompareNE : r4_4, r4_5 +# 983| v4_7(void) = ConditionalBranch : r4_6 +#-----| False -> Block 6 +#-----| True -> Block 5 + +# 983| Block 5 +# 983| v5_0(void) = NoOp : +#-----| Goto -> Block 4 + +# 985| Block 6 +# 985| v6_0(void) = NoOp : +# 978| v6_1(void) = ReturnVoid : +# 978| v6_2(void) = UnmodeledUse : mu* +# 978| v6_3(void) = ExitFunction : + +# 979| Block 7 +# 979| r7_0(glval) = VariableAddress[b] : +# 979| r7_1(glval) = VariableAddress[x] : +# 979| r7_2(int) = Load : r7_1, mu0_1 +# 979| r7_3(glval) = VariableAddress[y] : +# 979| r7_4(int) = Load : r7_3, m0_5 +# 979| r7_5(bool) = CompareLT : r7_2, r7_4 +# 979| m7_6(bool) = Store : r7_0, r7_5 +# 979| r7_7(glval) = VariableAddress[b] : +# 979| r7_8(bool) = Load : r7_7, m7_6 +# 979| v7_9(void) = ConditionalBranch : r7_8 +#-----| False -> Block 2 +#-----| True -> Block 1 From 01ad9ed8bc179d18c565a91790f21d073504e8f9 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Wed, 21 Nov 2018 09:18:52 +0100 Subject: [PATCH 63/94] JS: address review comments --- javascript/ql/src/Declarations/MissingThisQualifier.ql | 1 + .../MissingThisQualifier/MissingThisQualifier.expected | 1 + .../Declarations/MissingThisQualifier/indirection.js | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/javascript/ql/src/Declarations/MissingThisQualifier.ql b/javascript/ql/src/Declarations/MissingThisQualifier.ql index 93f4fa665e4..9a57ec987f8 100644 --- a/javascript/ql/src/Declarations/MissingThisQualifier.ql +++ b/javascript/ql/src/Declarations/MissingThisQualifier.ql @@ -56,6 +56,7 @@ where maybeMissingThis(call, intendedTarget, gv) intendedTarget.getBody() = self and call.getEnclosingFunction() = self and call.flow().(DataFlow::CallNode).getNumArgument() > self.getNumParameter() and + not self.hasRestParameter() and not self.usesArgumentsObject() ) ) diff --git a/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/MissingThisQualifier.expected b/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/MissingThisQualifier.expected index 37122e8266b..c9bd449006f 100644 --- a/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/MissingThisQualifier.expected +++ b/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/MissingThisQualifier.expected @@ -1,4 +1,5 @@ | abstract-missing.ts:3:5:3:24 | setAudioProperties() | This call refers to a global function, and not the local method $@. | abstract-missing.ts:6:3:6:32 | abstrac ... ties(); | setAudioProperties | +| indirection.js:7:9:7:20 | m("default") | This call refers to a global function, and not the local method $@. | indirection.js:2:5:4:5 | m() {\\n ... K\\n } | m | | missing1.js:3:5:3:24 | setAudioProperties() | This call refers to a global function, and not the local method $@. | missing1.js:6:3:7:3 | setAudi ... (){\\n } | setAudioProperties | | missing2.js:3:5:3:24 | setAudioProperties() | This call refers to a global function, and not the local method $@. | missing2.js:7:3:8:3 | static ... (){\\n } | setAudioProperties | | namespaces-uses.ts:3:5:3:20 | globalFunction() | This call refers to a global function, and not the local method $@. | namespaces-uses.ts:2:3:4:3 | globalF ... OK\\n } | globalFunction | diff --git a/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js b/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js index 60488458ac4..086a8ba03c2 100644 --- a/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js +++ b/javascript/ql/test/query-tests/Declarations/MissingThisQualifier/indirection.js @@ -2,4 +2,8 @@ class X { m() { m("default"); // OK } + + resty(...x) { + m("default"); // NOT OK + } } From caea6212ed95d33ba35a1b5c0a82ef6535b43aec Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Tue, 20 Nov 2018 09:29:16 +0100 Subject: [PATCH 64/94] JS: use inheritance in `js/mixed-static-instance-this-access` --- change-notes/1.19/analysis-javascript.md | 1 + .../MixedStaticInstanceThisAccess.ql | 10 +++++--- .../ql/src/semmle/javascript/Classes.qll | 7 ++++++ .../MixedStaticInstanceThisAccess.expected | 1 + .../MixedStaticInstanceThisAccess/tst.js | 25 +++++++++++++++++++ 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index d190d16dc14..d68ccd6008b 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -56,6 +56,7 @@ | Unused variable, import, function or class | Fewer results | This rule now flags import statements with multiple unused imports once. | | Useless assignment to local variable | Fewer false-positive results | This rule now recognizes additional ways default values can be set. | | Whitespace contradicts operator precedence | Fewer false-positive results | This rule no longer flags operators with asymmetric whitespace. | +| Wrong use of 'this' for static method | More results, fewer false-positive results | This rule now recognizes inherited methods. | ## Changes to QL libraries diff --git a/javascript/ql/src/Declarations/MixedStaticInstanceThisAccess.ql b/javascript/ql/src/Declarations/MixedStaticInstanceThisAccess.ql index 8ba3de13a3a..bd7d8fe9f14 100644 --- a/javascript/ql/src/Declarations/MixedStaticInstanceThisAccess.ql +++ b/javascript/ql/src/Declarations/MixedStaticInstanceThisAccess.ql @@ -10,15 +10,19 @@ */ import javascript +/** Holds if `base` declares or inherits method `m` with the given `name`. */ +predicate hasMethod(ClassDefinition base, string name, MethodDefinition m) { + m = base.getMethod(name) or + hasMethod(base.getSuperClassDefinition(), name, m) +} /** * Holds if `access` is in`fromMethod`, and it references `toMethod` through `this`. */ predicate isLocalMethodAccess(PropAccess access, MethodDefinition fromMethod, MethodDefinition toMethod) { - fromMethod.getDeclaringClass() = toMethod.getDeclaringClass() and + hasMethod(fromMethod.getDeclaringClass(), access.getPropertyName(), toMethod) and access.getEnclosingFunction() = fromMethod.getBody() and - access.getBase() instanceof ThisExpr and - access.getPropertyName() = toMethod.getName() + access.getBase() instanceof ThisExpr } string getKind(MethodDefinition m) { diff --git a/javascript/ql/src/semmle/javascript/Classes.qll b/javascript/ql/src/semmle/javascript/Classes.qll index 637f828beff..cfdb16b76cf 100644 --- a/javascript/ql/src/semmle/javascript/Classes.qll +++ b/javascript/ql/src/semmle/javascript/Classes.qll @@ -216,6 +216,13 @@ class ClassDefinition extends @classdefinition, ClassOrInterface, AST::ValueNode ) } + /** + * Gets the definition of the super class of this class, if it can be determined. + */ + ClassDefinition getSuperClassDefinition() { + result = getSuperClass().analyze().getAValue().(AbstractClass).getClass() + } + } /** diff --git a/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/MixedStaticInstanceThisAccess.expected b/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/MixedStaticInstanceThisAccess.expected index efb708b4e47..1e5f4d64324 100644 --- a/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/MixedStaticInstanceThisAccess.expected +++ b/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/MixedStaticInstanceThisAccess.expected @@ -1,2 +1,3 @@ | instanceStatic.js:3:9:3:16 | this.baz | Access to instance method $@ from static method $@ is not possible through `this`. | instanceStatic.js:5:5:7:5 | baz(){\\n\\n } | baz | instanceStatic.js:2:5:4:5 | static ... K\\n } | bar | | staticInstance.js:3:9:3:16 | this.baz | Access to static method $@ from instance method $@ is not possible through `this`. | staticInstance.js:5:5:6:5 | static baz(){\\n } | baz | staticInstance.js:2:5:4:5 | bar(){\\n ... K\\n } | bar | +| tst.js:66:9:66:14 | this.f | Access to instance method $@ from static method $@ is not possible through `this`. | tst.js:60:5:62:5 | f() {\\n\\n } | f | tst.js:65:5:67:5 | static ... K\\n } | test | diff --git a/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/tst.js b/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/tst.js index 74bb77217a2..a00731827d8 100644 --- a/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/tst.js +++ b/javascript/ql/test/query-tests/Declarations/MixedStaticInstanceThisAccess/tst.js @@ -41,3 +41,28 @@ class C4 { } } C4.f = x; + +class C5_super { + f() { + + } +} +class C5 extends C5_super{ + static f() { + + } + test() { + this.f; // OK + } +} + +class C6_super { + f() { + + } +} +class C6 extends C6_super{ + static test() { + this.f; // NOT OK + } +} From 8c753d7e94c8e3e596d23c85b51f317c616b4069 Mon Sep 17 00:00:00 2001 From: calum Date: Wed, 21 Nov 2018 11:15:55 +0000 Subject: [PATCH 65/94] C#: Fix ReDoS query. --- csharp/ql/src/Security Features/CWE-730/ReDoS.ql | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql index bb159cc0c6a..f1dbe5a068e 100644 --- a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql +++ b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql @@ -16,8 +16,14 @@ import semmle.code.csharp.frameworks.system.text.RegularExpressions import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink -where c.hasFlowPath(source, sink) +where + c.hasFlowPath(source, sink) and // No global timeout set - and not exists(RegexGlobalTimeout r) -select sink.getNode().(Sink), source, sink, + not exists(RegexGlobalTimeout r) and + ( + sink.getNode() instanceof Sink + or + sink.getNode() instanceof ExponentialRegexSink + ) +select sink.getNode(), source, sink, "$@ flows to regular expression operation with dangerous regex.", source.getNode(), "User-provided value" From 19aa12106cfff7175593c890bbb3b59f545167f0 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Mon, 19 Nov 2018 16:41:32 +0000 Subject: [PATCH 66/94] JavaScript: Teach AutoBuild to exclude minified files from extraction by default . This adds default exclusion filters for `**/*.min.js` and `**/*-min.js` to the JavaScript auto-builder, meaning that files matching these patterns will no longer be extracted, unless they are re-included in the `.lgtm.yml` file. Alerts in minified code aren't shown by default anyway, so we can save ourselves some work by not analyzing them in the first place. While including minified files in the snapshot can in theory improve analysis results in non-minified files, this is likely to be rare in practice. --- change-notes/1.19/extractor-javascript.md | 12 ++++++++++-- .../com/semmle/js/extractor/AutoBuild.java | 15 ++++++++++++++- .../js/extractor/test/AutoBuildTests.java | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/change-notes/1.19/extractor-javascript.md b/change-notes/1.19/extractor-javascript.md index bff31271434..0ad335af0dc 100644 --- a/change-notes/1.19/extractor-javascript.md +++ b/change-notes/1.19/extractor-javascript.md @@ -16,8 +16,16 @@ ## General improvements -> Changes that affect alerts in many files or from many queries -> For example, changes to file classification +* On LGTM, files whose name ends in `.min.js` or `-min.js` are no longer extracted by default, since they most likely contain minified code and results in these files would be hidden by default anyway. To extract such files anyway, you can add the following filters to your `lgtm.yml` file (or add them to existing filters): + +```yaml +extraction: + javascript: + index: + filters: + - include: "**/*.min.js" + - include: "**/*-min.js" +``` ## Changes to code extraction diff --git a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java index c04db341407..16a0226321c 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java +++ b/javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java @@ -111,7 +111,7 @@ import com.semmle.util.trap.TrapWriter; * *

* The filtering phase is parameterised by a list of include/exclude patterns in the style of - * {@link ProjectLayout} specifications. There are some built-in include patterns discussed + * {@link ProjectLayout} specifications. There are some built-in include/exclude patterns discussed * below. Additionally, the environment variable LGTM_INDEX_FILTERS is interpreted * as a newline-separated list of patterns to append to that list (hence taking precedence over * the built-in patterns). Unlike for {@link ProjectLayout}, patterns in @@ -140,6 +140,15 @@ import com.semmle.util.trap.TrapWriter; *

* *

+ * The default exclusion patterns cause the following files to be excluded: + *

+ *
    + *
  • All JavaScript files whose name ends with -min.js or .min.js. + * Such files typically contain minified code. Since LGTM by default does not show results + * in minified files, it is not usually worth extracting them in the first place.
  • + *
+ * + *

* JavaScript files are normally extracted with {@link SourceType#AUTO}, but an explicit * source type can be specified in the environment variable LGTM_INDEX_SOURCE_TYPE. *

@@ -317,6 +326,10 @@ public class AutoBuild { patterns.add("**/.eslintrc*"); patterns.add("**/package.json"); + // exclude files whose name strongly suggests they are minified + patterns.add("-**/*.min.js"); + patterns.add("-**/*-min.js"); + String base = LGTM_SRC.toString().replace('\\', '/'); // process `$LGTM_INDEX_FILTERS` for (String pattern : Main.NEWLINE.split(getEnvVar("LGTM_INDEX_FILTERS", ""))) { diff --git a/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java b/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java index 7969c093f4e..300fa708289 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java +++ b/javascript/extractor/src/com/semmle/js/extractor/test/AutoBuildTests.java @@ -433,4 +433,23 @@ public class AutoBuildTests { addFile(true, LGTM_SRC, "tst.js"); runTest(); } + + @Test + public void minifiedFilesAreExcluded() throws IOException { + addFile(true, LGTM_SRC, "admin.js"); + addFile(false, LGTM_SRC, "jquery.min.js"); + addFile(false, LGTM_SRC, "lib", "lodash-min.js"); + addFile(true, LGTM_SRC, "compute_min.js"); + runTest(); + } + + @Test + public void minifiedFilesCanBeReIncluded() throws IOException { + envVars.put("LGTM_INDEX_FILTERS", "include:**/*.min.js\ninclude:**/*-min.js"); + addFile(true, LGTM_SRC, "admin.js"); + addFile(true, LGTM_SRC, "jquery.min.js"); + addFile(true, LGTM_SRC, "lib", "lodash-min.js"); + addFile(true, LGTM_SRC, "compute_min.js"); + runTest(); + } } From 69ab1ed5bd1d577c3264f6399a7686a12db29a87 Mon Sep 17 00:00:00 2001 From: calum Date: Wed, 21 Nov 2018 12:35:05 +0000 Subject: [PATCH 67/94] C#: Add `nodes` predicate to all path queries. --- .../semmle/code/csharp/dataflow/DataFlow.qll | 3 +++ .../CWE-022/TaintedPath/TaintedPath.expected | 9 ++++++++ .../CWE-022/ZipSlip/ZipSlip.expected | 15 +++++++++++++ .../CWE-078/CommandInjection.expected | 9 ++++++++ .../CWE-078/StoredCommandInjection.expected | 3 +++ .../CWE-079/StoredXSS/StoredXSS.expected | 3 +++ .../CWE-089/SecondOrderSqlInjection.expected | 3 +++ .../CWE-089/SqlInjection.expected | 10 +++++++++ .../CWE-090/LDAPInjection.expected | 8 +++++++ .../CWE-090/StoredLDAPInjection.expected | 3 +++ .../CWE-094/CodeInjection.expected | 4 ++++ .../CWE-099/ResourceInjection.expected | 4 ++++ .../CWE-112/MissingXMLValidation.expected | 15 +++++++++++++ .../CWE-117/LogForging.expected | 4 ++++ .../ExposureInTransmittedData.expected | 12 +++++++++++ .../ExceptionInformationExposure.expected | 6 ++++++ .../CWE-312/CleartextStorage.expected | 6 ++++++ .../DontInstallRootCert.expected | 7 +++++++ .../CWE-338/InsecureRandomness.expected | 11 ++++++++++ .../ExposureOfPrivateInformation.expected | 4 ++++ .../CWE-601/UrlRedirect/UrlRedirect.expected | 21 +++++++++++++++++++ .../CWE-611/UntrustedDataInsecureXml.expected | 5 +++++ .../CWE-643/StoredXPathInjection.expected | 5 +++++ .../CWE-643/XPathInjection.expected | 5 +++++ .../CWE-730/ReDoS/ReDoS.expected | 19 +++++++++++++++++ .../CWE-730/ReDoSGlobalTimeout/ReDoS.expected | 4 ++++ .../RegexInjection/RegexInjection.expected | 3 +++ .../HardcodedConnectionString.expected | 14 +++++++++++++ .../CWE-798/HardcodedCredentials.expected | 12 +++++++++++ .../CWE-807/ConditionalBypass.expected | 13 ++++++++++++ .../CWE-838/InappropriateEncoding.expected | 21 +++++++++++++++++++ 31 files changed, 261 insertions(+) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index 6843d67087b..dfd7885899c 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -130,6 +130,9 @@ module DataFlow { module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } + + /** Holds if `node` is a node in the graph of data flow path explanations. */ + query predicate nodes(PathNode node) { any() } } /** diff --git a/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected b/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected index 8586fc5266d..9207136a1c6 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/TaintedPath.expected @@ -6,6 +6,15 @@ edges | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:38:25:38:31 | access to local variable badPath | | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:40:49:40:55 | access to local variable badPath | | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:53:26:53:29 | access to local variable path | +nodes +| TaintedPath.cs:12:23:12:45 | access to property QueryString | +| TaintedPath.cs:14:50:14:53 | access to local variable path | +| TaintedPath.cs:19:51:19:54 | access to local variable path | +| TaintedPath.cs:27:30:27:33 | access to local variable path | +| TaintedPath.cs:33:30:33:33 | access to local variable path | +| TaintedPath.cs:38:25:38:31 | access to local variable badPath | +| TaintedPath.cs:40:49:40:55 | access to local variable badPath | +| TaintedPath.cs:53:26:53:29 | access to local variable path | #select | TaintedPath.cs:14:50:14:53 | access to local variable path | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:14:50:14:53 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | | TaintedPath.cs:19:51:19:54 | access to local variable path | TaintedPath.cs:12:23:12:45 | access to property QueryString | TaintedPath.cs:19:51:19:54 | access to local variable path | $@ flows to here and is used in a path. | TaintedPath.cs:12:23:12:45 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected b/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected index 2672f945a62..a95aff9ad55 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/ZipSlip.expected @@ -10,6 +10,21 @@ edges | ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:83:57:83:68 | access to local variable destFilePath | | ZipSlip.cs:62:72:62:85 | access to property FullName | ZipSlip.cs:91:58:91:69 | access to local variable destFilePath | | ZipSlipBad.cs:9:59:9:72 | access to property FullName | ZipSlipBad.cs:10:29:10:40 | access to local variable destFileName | +nodes +| ZipSlip.cs:16:52:16:65 | access to property FullName | +| ZipSlip.cs:19:31:19:44 | access to property FullName | +| ZipSlip.cs:24:41:24:52 | access to local variable destFileName | +| ZipSlip.cs:32:41:32:52 | access to local variable destFilePath | +| ZipSlip.cs:36:45:36:56 | access to local variable destFilePath | +| ZipSlip.cs:39:53:39:89 | call to method Combine | +| ZipSlip.cs:40:41:40:52 | access to local variable destFilePath | +| ZipSlip.cs:62:72:62:85 | access to property FullName | +| ZipSlip.cs:69:74:69:85 | access to local variable destFilePath | +| ZipSlip.cs:76:71:76:82 | access to local variable destFilePath | +| ZipSlip.cs:83:57:83:68 | access to local variable destFilePath | +| ZipSlip.cs:91:58:91:69 | access to local variable destFilePath | +| ZipSlipBad.cs:9:59:9:72 | access to property FullName | +| ZipSlipBad.cs:10:29:10:40 | access to local variable destFileName | #select | ZipSlip.cs:24:41:24:52 | access to local variable destFileName | ZipSlip.cs:19:31:19:44 | access to property FullName | ZipSlip.cs:24:41:24:52 | access to local variable destFileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:19:31:19:44 | access to property FullName | item path | | ZipSlip.cs:32:41:32:52 | access to local variable destFilePath | ZipSlip.cs:16:52:16:65 | access to property FullName | ZipSlip.cs:32:41:32:52 | access to local variable destFilePath | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlip.cs:16:52:16:65 | access to property FullName | item path | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected index 7c2a68cec35..433556e9ede 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-078/CommandInjection.expected @@ -6,6 +6,15 @@ edges | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:32:39:32:47 | access to local variable userInput | | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:33:40:33:48 | access to local variable userInput | | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:34:47:34:55 | access to local variable userInput | +nodes +| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | +| CommandInjection.cs:26:27:26:47 | ... + ... | +| CommandInjection.cs:26:50:26:66 | ... + ... | +| CommandInjection.cs:28:63:28:71 | access to local variable userInput | +| CommandInjection.cs:28:74:28:82 | access to local variable userInput | +| CommandInjection.cs:32:39:32:47 | access to local variable userInput | +| CommandInjection.cs:33:40:33:48 | access to local variable userInput | +| CommandInjection.cs:34:47:34:55 | access to local variable userInput | #select | CommandInjection.cs:26:27:26:47 | ... + ... | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:26:27:26:47 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | | CommandInjection.cs:26:50:26:66 | ... + ... | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | CommandInjection.cs:26:50:26:66 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected index 8c41bafe5b5..a66196c3c15 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-078/StoredCommandInjection.expected @@ -1,4 +1,7 @@ edges | StoredCommandInjection.cs:24:54:24:80 | call to method GetString | StoredCommandInjection.cs:24:46:24:80 | ... + ... | +nodes +| StoredCommandInjection.cs:24:46:24:80 | ... + ... | +| StoredCommandInjection.cs:24:54:24:80 | call to method GetString | #select | StoredCommandInjection.cs:24:46:24:80 | ... + ... | StoredCommandInjection.cs:24:54:24:80 | call to method GetString | StoredCommandInjection.cs:24:46:24:80 | ... + ... | $@ flows to here and is used in a command. | StoredCommandInjection.cs:24:54:24:80 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected index 91263323cae..fb150f87411 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected @@ -1,4 +1,7 @@ edges | StoredXSS.cs:24:60:24:86 | call to method GetString | StoredXSS.cs:24:44:24:86 | ... + ... | +nodes +| StoredXSS.cs:24:44:24:86 | ... + ... | +| StoredXSS.cs:24:60:24:86 | call to method GetString | #select | StoredXSS.cs:24:44:24:86 | ... + ... | StoredXSS.cs:24:60:24:86 | call to method GetString | StoredXSS.cs:24:44:24:86 | ... + ... | $@ flows to here and is written to HTML or JavaScript. | StoredXSS.cs:24:60:24:86 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected index 9789f8d2dd7..e51bc365ccb 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SecondOrderSqlInjection.expected @@ -1,4 +1,7 @@ edges | SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | +nodes +| SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | +| SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | #select | SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | SecondOrderSqlInjection.cs:21:71:21:145 | ... + ... | $@ flows to here and is used in an SQL query. | SecondOrderSqlInjection.cs:21:119:21:145 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected index cd94b55c638..1bc4ebc4764 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected @@ -18,6 +18,16 @@ edges | SqlInjection.cs:61:62:61:81 | access to property Text | SqlInjection.cs:75:55:75:60 | access to local variable query1 | | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | +nodes +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | +| SqlInjection.cs:39:50:39:55 | access to local variable query1 | +| SqlInjection.cs:49:62:49:76 | access to field categoryTextBox | +| SqlInjection.cs:49:62:49:81 | access to property Text | +| SqlInjection.cs:61:62:61:76 | access to field categoryTextBox | +| SqlInjection.cs:61:62:61:81 | access to property Text | +| SqlInjection.cs:73:33:73:47 | access to field categoryTextBox | +| SqlInjection.cs:74:56:74:61 | access to local variable query1 | +| SqlInjection.cs:75:55:75:60 | access to local variable query1 | #select | SqlInjection.cs:39:50:39:55 | access to local variable query1 | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:39:50:39:55 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | | SqlInjection.cs:74:56:74:61 | access to local variable query1 | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox | this ASP.NET user input | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected index b41e03c73da..4d78cbb644c 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-090/LDAPInjection.expected @@ -5,6 +5,14 @@ edges | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:26:53:26:77 | ... + ... | | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:29:48:29:70 | ... + ... | | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:31:20:31:42 | ... + ... | +nodes +| LDAPInjection.cs:13:27:13:49 | access to property QueryString | +| LDAPInjection.cs:16:54:16:78 | ... + ... | +| LDAPInjection.cs:18:21:18:45 | ... + ... | +| LDAPInjection.cs:25:21:25:45 | ... + ... | +| LDAPInjection.cs:26:53:26:77 | ... + ... | +| LDAPInjection.cs:29:48:29:70 | ... + ... | +| LDAPInjection.cs:31:20:31:42 | ... + ... | #select | LDAPInjection.cs:16:54:16:78 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:16:54:16:78 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | | LDAPInjection.cs:18:21:18:45 | ... + ... | LDAPInjection.cs:13:27:13:49 | access to property QueryString | LDAPInjection.cs:18:21:18:45 | ... + ... | $@ flows to here and is used in an LDAP query. | LDAPInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected index 8fd27bbc970..9b1065d2ea2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-090/StoredLDAPInjection.expected @@ -1,4 +1,7 @@ edges | StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | StoredLDAPInjection.cs:24:66:24:109 | ... + ... | +nodes +| StoredLDAPInjection.cs:24:66:24:109 | ... + ... | +| StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | #select | StoredLDAPInjection.cs:24:66:24:109 | ... + ... | StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | StoredLDAPInjection.cs:24:66:24:109 | ... + ... | $@ flows to here and is used in an LDAP query. | StoredLDAPInjection.cs:24:83:24:109 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected index aa41bff2494..696a6e4841a 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-094/CodeInjection.expected @@ -1,6 +1,10 @@ edges | CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:31:64:31:67 | access to local variable code | | CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:42:36:42:39 | access to local variable code | +nodes +| CodeInjection.cs:25:23:25:45 | access to property QueryString | +| CodeInjection.cs:31:64:31:67 | access to local variable code | +| CodeInjection.cs:42:36:42:39 | access to local variable code | #select | CodeInjection.cs:31:64:31:67 | access to local variable code | CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:31:64:31:67 | access to local variable code | $@ flows to here and is compiled as code. | CodeInjection.cs:25:23:25:45 | access to property QueryString | User-provided value | | CodeInjection.cs:42:36:42:39 | access to local variable code | CodeInjection.cs:25:23:25:45 | access to property QueryString | CodeInjection.cs:42:36:42:39 | access to local variable code | $@ flows to here and is compiled as code. | CodeInjection.cs:25:23:25:45 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected index df107579427..a362b1d9ad5 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-099/ResourceInjection.expected @@ -1,6 +1,10 @@ edges | ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | | ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | +nodes +| ResourceInjection.cs:10:27:10:49 | access to property QueryString | +| ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | +| ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | #select | ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:13:57:13:72 | access to local variable connectionString | $@ flows to here and is used in a resource descriptor. | ResourceInjection.cs:10:27:10:49 | access to property QueryString | User-provided value | | ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | ResourceInjection.cs:10:27:10:49 | access to property QueryString | ResourceInjection.cs:15:42:15:57 | access to local variable connectionString | $@ flows to here and is used in a resource descriptor. | ResourceInjection.cs:10:27:10:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected b/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected index b9732e9b44c..2345ce84755 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected @@ -8,6 +8,21 @@ edges | MissingXMLValidation.cs:27:42:27:64 | object creation of type XmlReaderSettings | MissingXMLValidation.cs:29:61:29:72 | access to local variable badSettings2 | | MissingXMLValidation.cs:32:42:32:64 | object creation of type XmlReaderSettings | MissingXMLValidation.cs:37:61:37:72 | access to local variable goodSettings | | MissingXMLValidation.cs:40:42:40:64 | object creation of type XmlReaderSettings | MissingXMLValidation.cs:47:61:47:72 | access to local variable badSettings3 | +nodes +| MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | +| MissingXMLValidation.cs:18:26:18:58 | object creation of type StringReader | +| MissingXMLValidation.cs:22:42:22:64 | object creation of type XmlReaderSettings | +| MissingXMLValidation.cs:23:26:23:58 | object creation of type StringReader | +| MissingXMLValidation.cs:23:61:23:72 | access to local variable badSettings1 | +| MissingXMLValidation.cs:27:42:27:64 | object creation of type XmlReaderSettings | +| MissingXMLValidation.cs:29:26:29:58 | object creation of type StringReader | +| MissingXMLValidation.cs:29:61:29:72 | access to local variable badSettings2 | +| MissingXMLValidation.cs:32:42:32:64 | object creation of type XmlReaderSettings | +| MissingXMLValidation.cs:37:26:37:58 | object creation of type StringReader | +| MissingXMLValidation.cs:37:61:37:72 | access to local variable goodSettings | +| MissingXMLValidation.cs:40:42:40:64 | object creation of type XmlReaderSettings | +| MissingXMLValidation.cs:47:26:47:58 | object creation of type StringReader | +| MissingXMLValidation.cs:47:61:47:72 | access to local variable badSettings3 | #select | MissingXMLValidation.cs:18:26:18:58 | object creation of type StringReader | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:18:26:18:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because there is no 'XmlReaderSettings' instance specifying schema validation. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | | MissingXMLValidation.cs:23:26:23:58 | object creation of type StringReader | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | MissingXMLValidation.cs:23:26:23:58 | object creation of type StringReader | $@ flows to here and is processed as XML without validation because the 'XmlReaderSettings' instance does not specify the 'ValidationType' as 'Schema'. | MissingXMLValidation.cs:14:34:14:56 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected b/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected index fdda0a73e98..5cba04b42c2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-117/LogForging.expected @@ -1,6 +1,10 @@ edges | LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:22:21:22:43 | ... + ... | | LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:28:50:28:72 | ... + ... | +nodes +| LogForging.cs:19:27:19:49 | access to property QueryString | +| LogForging.cs:22:21:22:43 | ... + ... | +| LogForging.cs:28:50:28:72 | ... + ... | #select | LogForging.cs:22:21:22:43 | ... + ... | LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:22:21:22:43 | ... + ... | $@ flows to log entry. | LogForging.cs:19:27:19:49 | access to property QueryString | User-provided value | | LogForging.cs:28:50:28:72 | ... + ... | LogForging.cs:19:27:19:49 | access to property QueryString | LogForging.cs:28:50:28:72 | ... + ... | $@ flows to log entry. | LogForging.cs:19:27:19:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected b/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected index 7f512300244..78ef8bdf19e 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/ExposureInTransmittedData.expected @@ -4,6 +4,18 @@ edges | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:33:56:33:56 | access to local variable p | | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:34:24:34:52 | ... + ... | | ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | ExposureInTransmittedData.cs:35:27:35:27 | access to local variable p | +nodes +| ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | +| ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | +| ExposureInTransmittedData.cs:24:32:24:41 | access to property Message | +| ExposureInTransmittedData.cs:25:32:25:44 | call to method ToString | +| ExposureInTransmittedData.cs:26:32:26:38 | access to property Data | +| ExposureInTransmittedData.cs:26:32:26:50 | access to indexer | +| ExposureInTransmittedData.cs:32:17:32:36 | call to method GetField | +| ExposureInTransmittedData.cs:33:53:33:53 | access to local variable p | +| ExposureInTransmittedData.cs:33:56:33:56 | access to local variable p | +| ExposureInTransmittedData.cs:34:24:34:52 | ... + ... | +| ExposureInTransmittedData.cs:35:27:35:27 | access to local variable p | #select | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:16:32:16:39 | access to local variable password | access to local variable password | | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | Sensitive information from $@ flows to here, and is transmitted to the user. | ExposureInTransmittedData.cs:20:32:20:44 | call to method ToString | call to method ToString | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected b/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected index 734ac5b026c..7d3578bc71e 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-209/ExceptionInformationExposure.expected @@ -1,5 +1,11 @@ edges | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | +nodes +| ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | +| ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | +| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | +| ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | +| ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | #select | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | call to method ToString | | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | access to local variable ex | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected b/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected index 8bf93c08f85..7d564153bca 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-312/CleartextStorage.expected @@ -1,4 +1,10 @@ edges +nodes +| CleartextStorage.cs:14:50:14:59 | access to field accountKey | +| CleartextStorage.cs:15:62:15:74 | call to method GetPassword | +| CleartextStorage.cs:16:69:16:81 | call to method GetPassword | +| CleartextStorage.cs:17:50:17:63 | call to method GetAccountID | +| CleartextStorage.cs:25:21:25:33 | call to method GetPassword | #select | CleartextStorage.cs:14:50:14:59 | access to field accountKey | CleartextStorage.cs:14:50:14:59 | access to field accountKey | CleartextStorage.cs:14:50:14:59 | access to field accountKey | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:14:50:14:59 | access to field accountKey | access to field accountKey | | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | Sensitive data returned by $@ is stored here. | CleartextStorage.cs:15:62:15:74 | call to method GetPassword | call to method GetPassword | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected b/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected index c766b3581ea..5ef8bf77643 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-327/DontInstallRootCert/DontInstallRootCert.expected @@ -2,6 +2,13 @@ edges | Test.cs:17:31:17:59 | object creation of type X509Store | Test.cs:20:13:20:17 | access to local variable store | | Test.cs:27:31:27:86 | object creation of type X509Store | Test.cs:30:13:30:17 | access to local variable store | | Test.cs:72:31:72:86 | object creation of type X509Store | Test.cs:75:13:75:17 | access to local variable store | +nodes +| Test.cs:17:31:17:59 | object creation of type X509Store | +| Test.cs:20:13:20:17 | access to local variable store | +| Test.cs:27:31:27:86 | object creation of type X509Store | +| Test.cs:30:13:30:17 | access to local variable store | +| Test.cs:72:31:72:86 | object creation of type X509Store | +| Test.cs:75:13:75:17 | access to local variable store | #select | Test.cs:20:13:20:17 | access to local variable store | Test.cs:17:31:17:59 | object creation of type X509Store | Test.cs:20:13:20:17 | access to local variable store | Certificate added to the root certificate store. | | Test.cs:30:13:30:17 | access to local variable store | Test.cs:27:31:27:86 | object creation of type X509Store | Test.cs:30:13:30:17 | access to local variable store | Certificate added to the root certificate store. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected index dd5727c7a46..a5fb3480409 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected @@ -7,6 +7,17 @@ edges | InsecureRandomness.cs:62:16:62:32 | call to method ToString | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | | InsecureRandomness.cs:72:31:72:39 | call to method Next | InsecureRandomness.cs:74:16:74:21 | access to local variable result | | InsecureRandomness.cs:74:16:74:21 | access to local variable result | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | +nodes +| InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | +| InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | +| InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | +| InsecureRandomness.cs:28:29:28:43 | call to method Next | +| InsecureRandomness.cs:29:27:29:61 | call to method GetString | +| InsecureRandomness.cs:31:16:31:32 | call to method ToString | +| InsecureRandomness.cs:60:31:60:39 | call to method Next | +| InsecureRandomness.cs:62:16:62:32 | call to method ToString | +| InsecureRandomness.cs:72:31:72:39 | call to method Next | +| InsecureRandomness.cs:74:16:74:21 | access to local variable result | #select | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:28:29:28:43 | call to method Next | call to method Next | | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:60:31:60:39 | call to method Next | call to method Next | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected b/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected index 09d661ed9c7..e0a0bcbe3fe 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-359/ExposureOfPrivateInformation.expected @@ -1,4 +1,8 @@ edges +nodes +| ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | +| ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | +| ExposureOfPrivateInformation.cs:24:21:24:36 | call to method getTelephone | #select | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:18:50:18:84 | access to indexer | access to indexer | | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | Private data returned by $@ is written to an external location. | ExposureOfPrivateInformation.cs:20:50:20:65 | call to method getTelephone | call to method getTelephone | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected b/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected index 97a7725ef1b..ea4b2b5a605 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/UrlRedirect.expected @@ -13,6 +13,27 @@ edges | UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:50:28:50:32 | access to parameter value | | UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:55:32:55:45 | object creation of type Uri | | UrlRedirectCore.cs:47:51:47:55 | value | UrlRedirectCore.cs:58:31:58:35 | access to parameter value | +nodes +| UrlRedirect.cs:14:31:14:53 | access to property QueryString | +| UrlRedirect.cs:14:31:14:61 | access to indexer | +| UrlRedirect.cs:24:22:24:44 | access to property QueryString | +| UrlRedirect.cs:39:44:39:66 | access to property QueryString | +| UrlRedirect.cs:39:44:39:74 | access to indexer | +| UrlRedirect.cs:40:47:40:69 | access to property QueryString | +| UrlRedirect.cs:40:47:40:77 | access to indexer | +| UrlRedirect.cs:49:29:49:31 | access to local variable url | +| UrlRedirectCore.cs:15:44:15:48 | value | +| UrlRedirectCore.cs:18:22:18:26 | access to parameter value | +| UrlRedirectCore.cs:21:44:21:48 | call to operator implicit conversion | +| UrlRedirectCore.cs:27:46:27:50 | call to operator implicit conversion | +| UrlRedirectCore.cs:33:66:33:70 | access to parameter value | +| UrlRedirectCore.cs:36:49:36:53 | call to operator implicit conversion | +| UrlRedirectCore.cs:39:69:39:73 | access to parameter value | +| UrlRedirectCore.cs:42:39:42:53 | ... + ... | +| UrlRedirectCore.cs:47:51:47:55 | value | +| UrlRedirectCore.cs:50:28:50:32 | access to parameter value | +| UrlRedirectCore.cs:55:32:55:45 | object creation of type Uri | +| UrlRedirectCore.cs:58:31:58:35 | access to parameter value | #select | UrlRedirect.cs:14:31:14:61 | access to indexer | UrlRedirect.cs:14:31:14:53 | access to property QueryString | UrlRedirect.cs:14:31:14:61 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:14:31:14:53 | access to property QueryString | user-provided value | | UrlRedirect.cs:39:44:39:74 | access to indexer | UrlRedirect.cs:39:44:39:66 | access to property QueryString | UrlRedirect.cs:39:44:39:74 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:39:44:39:66 | access to property QueryString | user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected b/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected index 6dd51cf91ed..5f68dc30cd0 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-611/UntrustedDataInsecureXml.expected @@ -1,5 +1,10 @@ edges | Test.cs:13:50:13:72 | access to property QueryString | Test.cs:13:50:13:84 | access to indexer | | Test.cs:18:38:18:60 | object creation of type XmlReaderSettings | Test.cs:23:55:23:62 | access to local variable settings | +nodes +| Test.cs:13:50:13:72 | access to property QueryString | +| Test.cs:13:50:13:84 | access to indexer | +| Test.cs:18:38:18:60 | object creation of type XmlReaderSettings | +| Test.cs:23:55:23:62 | access to local variable settings | #select | Test.cs:13:50:13:84 | access to indexer | Test.cs:13:50:13:72 | access to property QueryString | Test.cs:13:50:13:84 | access to indexer | $@ flows to here and is loaded insecurely as XML (DTD processing is enabled with an insecure resolver). | Test.cs:13:50:13:72 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected index 0b2c001a155..3415ec96976 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-643/StoredXPathInjection.expected @@ -3,6 +3,11 @@ edges | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | StoredXPathInjection.cs:30:41:30:144 | ... + ... | | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | StoredXPathInjection.cs:27:45:27:148 | ... + ... | | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | StoredXPathInjection.cs:30:41:30:144 | ... + ... | +nodes +| StoredXPathInjection.cs:24:39:24:65 | call to method GetString | +| StoredXPathInjection.cs:25:39:25:65 | call to method GetString | +| StoredXPathInjection.cs:27:45:27:148 | ... + ... | +| StoredXPathInjection.cs:30:41:30:144 | ... + ... | #select | StoredXPathInjection.cs:27:45:27:148 | ... + ... | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | StoredXPathInjection.cs:27:45:27:148 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:24:39:24:65 | call to method GetString | Stored user-provided value | | StoredXPathInjection.cs:27:45:27:148 | ... + ... | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | StoredXPathInjection.cs:27:45:27:148 | ... + ... | $@ flows to here and is used in an XPath expression. | StoredXPathInjection.cs:25:39:25:65 | call to method GetString | Stored user-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected index 7106a842df1..84f46930c1a 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-643/XPathInjection.expected @@ -3,6 +3,11 @@ edges | XPathInjection.cs:12:27:12:49 | access to property QueryString | XPathInjection.cs:19:29:19:132 | ... + ... | | XPathInjection.cs:13:27:13:49 | access to property QueryString | XPathInjection.cs:16:33:16:136 | ... + ... | | XPathInjection.cs:13:27:13:49 | access to property QueryString | XPathInjection.cs:19:29:19:132 | ... + ... | +nodes +| XPathInjection.cs:12:27:12:49 | access to property QueryString | +| XPathInjection.cs:13:27:13:49 | access to property QueryString | +| XPathInjection.cs:16:33:16:136 | ... + ... | +| XPathInjection.cs:19:29:19:132 | ... + ... | #select | XPathInjection.cs:16:33:16:136 | ... + ... | XPathInjection.cs:12:27:12:49 | access to property QueryString | XPathInjection.cs:16:33:16:136 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:12:27:12:49 | access to property QueryString | User-provided value | | XPathInjection.cs:16:33:16:136 | ... + ... | XPathInjection.cs:13:27:13:49 | access to property QueryString | XPathInjection.cs:16:33:16:136 | ... + ... | $@ flows to here and is used in an XPath expression. | XPathInjection.cs:13:27:13:49 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected index 69cd0591560..370665a4e63 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/ReDoS.expected @@ -14,6 +14,25 @@ edges | ExponentialRegex.cs:24:19:24:34 | access to field JAVA_CLASS_REGEX | ExponentialRegex.cs:26:32:26:47 | access to field JAVA_CLASS_REGEX | | ExponentialRegex.cs:24:19:24:34 | access to field JAVA_CLASS_REGEX | ExponentialRegex.cs:30:32:30:47 | access to field JAVA_CLASS_REGEX | | ExponentialRegex.cs:26:32:26:47 | access to field JAVA_CLASS_REGEX | ExponentialRegex.cs:30:32:30:47 | access to field JAVA_CLASS_REGEX | +nodes +| ExponentialRegex.cs:9:55:9:83 | "^(([a-z])+.)+[A-Z]([a-z])+$" | +| ExponentialRegex.cs:13:28:13:50 | access to property QueryString | +| ExponentialRegex.cs:17:19:17:31 | "^([a-z]+)+$" | +| ExponentialRegex.cs:17:40:17:48 | access to local variable userInput | +| ExponentialRegex.cs:18:19:18:31 | "^([a-z]*)*$" | +| ExponentialRegex.cs:18:42:18:50 | access to local variable userInput | +| ExponentialRegex.cs:21:19:21:130 | "^([a-zA-Z0-9])(([\\-.]\|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})\|([a-z]{2,3}[.]{1}[a-z]{2,3}))$" | +| ExponentialRegex.cs:21:139:21:147 | access to local variable userInput | +| ExponentialRegex.cs:24:19:24:34 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:24:43:24:51 | access to local variable userInput | +| ExponentialRegex.cs:26:21:26:29 | access to local variable userInput | +| ExponentialRegex.cs:26:32:26:47 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:28:47:28:55 | access to local variable userInput | +| ExponentialRegex.cs:29:19:29:31 | "^([a-z]+)+$" | +| ExponentialRegex.cs:29:90:29:98 | access to local variable userInput | +| ExponentialRegex.cs:30:21:30:29 | access to local variable userInput | +| ExponentialRegex.cs:30:32:30:47 | access to field JAVA_CLASS_REGEX | +| ExponentialRegex.cs:32:57:32:65 | access to local variable userInput | #select | ExponentialRegex.cs:17:40:17:48 | access to local variable userInput | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:17:40:17:48 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | | ExponentialRegex.cs:18:42:18:50 | access to local variable userInput | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | ExponentialRegex.cs:18:42:18:50 | access to local variable userInput | $@ flows to regular expression operation with dangerous regex. | ExponentialRegex.cs:13:28:13:50 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected index 3c7330c9035..140050954bc 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/ReDoS.expected @@ -1,3 +1,7 @@ edges | ExponentialRegex.cs:15:28:15:50 | access to property QueryString | ExponentialRegex.cs:18:40:18:48 | access to local variable userInput | +nodes +| ExponentialRegex.cs:15:28:15:50 | access to property QueryString | +| ExponentialRegex.cs:18:19:18:31 | "^([a-z]+)+$" | +| ExponentialRegex.cs:18:40:18:48 | access to local variable userInput | #select diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected index 50b64034e09..b17c5030694 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/RegexInjection.expected @@ -1,4 +1,7 @@ edges | RegexInjection.cs:12:24:12:46 | access to property QueryString | RegexInjection.cs:16:19:16:23 | access to local variable regex | +nodes +| RegexInjection.cs:12:24:12:46 | access to property QueryString | +| RegexInjection.cs:16:19:16:23 | access to local variable regex | #select | RegexInjection.cs:16:19:16:23 | access to local variable regex | RegexInjection.cs:12:24:12:46 | access to property QueryString | RegexInjection.cs:16:19:16:23 | access to local variable regex | $@ flows to the construction of a regular expression. | RegexInjection.cs:12:24:12:46 | access to property QueryString | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected index 985c4d67e31..6d67b199670 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedConnectionString.expected @@ -1,5 +1,19 @@ edges | HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | +nodes +| HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | +| HardcodedCredentials.cs:33:19:33:28 | "username" | +| HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | +| HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | +| HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | +| HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | +| HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | +| HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | +| HardcodedCredentials.cs:76:31:76:42 | "myusername" | +| HardcodedCredentials.cs:76:45:76:56 | "mypassword" | +| TestHardcodedCredentials.cs:21:31:21:42 | "myusername" | +| TestHardcodedCredentials.cs:21:45:21:56 | "mypassword" | +| TestHardcodedCredentials.cs:26:19:26:28 | "username" | #select | HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | HardcodedCredentials.cs:56:48:56:63 | "Password=12345" | 'ConnectionString' property includes hard-coded credentials set in $@. | HardcodedCredentials.cs:56:30:56:64 | object creation of type SqlConnection | object creation of type SqlConnection | | HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | HardcodedCredentials.cs:58:49:58:63 | "User Id=12345" | 'ConnectionString' property includes hard-coded credentials set in $@. | HardcodedCredentials.cs:58:31:58:64 | object creation of type SqlConnection | object creation of type SqlConnection | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected index 0276293a89a..20d70fe7a37 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-798/HardcodedCredentials.expected @@ -1,5 +1,17 @@ edges | HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | +nodes +| HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | +| HardcodedCredentials.cs:33:19:33:28 | "username" | +| HardcodedCredentials.cs:47:39:47:53 | "myNewPa55word" | +| HardcodedCredentials.cs:49:30:49:60 | array creation of type Byte[] | +| HardcodedCredentials.cs:52:13:52:23 | access to local variable rawCertData | +| HardcodedCredentials.cs:53:13:53:24 | "myPa55word" | +| HardcodedCredentials.cs:76:31:76:42 | "myusername" | +| HardcodedCredentials.cs:76:45:76:56 | "mypassword" | +| TestHardcodedCredentials.cs:21:31:21:42 | "myusername" | +| TestHardcodedCredentials.cs:21:45:21:56 | "mypassword" | +| TestHardcodedCredentials.cs:26:19:26:28 | "username" | #select | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | The hard-coded value "myPa55word" flows to $@ which is compared against $@. | HardcodedCredentials.cs:17:25:17:36 | "myPa55word" | "myPa55word" | HardcodedCredentials.cs:17:13:17:20 | access to local variable password | access to local variable password | | HardcodedCredentials.cs:33:19:33:28 | "username" | HardcodedCredentials.cs:33:19:33:28 | "username" | HardcodedCredentials.cs:33:19:33:28 | "username" | The hard-coded value "username" flows to the $@ parameter in $@. | HardcodedCredentials.cs:33:19:33:28 | "username" | name | HardcodedCredentials.cs:31:31:45:13 | object creation of type MembershipUser | object creation of type MembershipUser | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected b/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected index f04e8969bfc..016f6b802df 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-807/ConditionalBypass.expected @@ -6,6 +6,19 @@ edges | ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | ConditionalBypass.cs:51:13:51:29 | access to property HostName | | ConditionalBypass.cs:72:34:72:52 | access to property Cookies | ConditionalBypass.cs:74:13:74:40 | ... == ... | | ConditionalBypass.cs:85:34:85:52 | access to property Cookies | ConditionalBypass.cs:86:13:86:40 | ... == ... | +nodes +| ConditionalBypass.cs:14:26:14:48 | access to property QueryString | +| ConditionalBypass.cs:18:13:18:30 | ... == ... | +| ConditionalBypass.cs:21:34:21:52 | access to property Cookies | +| ConditionalBypass.cs:24:13:24:45 | call to method Equals | +| ConditionalBypass.cs:29:13:29:40 | ... == ... | +| ConditionalBypass.cs:44:32:44:66 | call to method GetHostByAddress | +| ConditionalBypass.cs:46:13:46:46 | ... == ... | +| ConditionalBypass.cs:51:13:51:29 | access to property HostName | +| ConditionalBypass.cs:72:34:72:52 | access to property Cookies | +| ConditionalBypass.cs:74:13:74:40 | ... == ... | +| ConditionalBypass.cs:85:34:85:52 | access to property Cookies | +| ConditionalBypass.cs:86:13:86:40 | ... == ... | #select | ConditionalBypass.cs:19:13:19:33 | call to method login | ConditionalBypass.cs:14:26:14:48 | access to property QueryString | ConditionalBypass.cs:18:13:18:30 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:18:13:18:30 | ... == ... | this condition | ConditionalBypass.cs:14:26:14:48 | access to property QueryString | user input | | ConditionalBypass.cs:25:13:25:33 | call to method login | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | ConditionalBypass.cs:24:13:24:45 | call to method Equals | Sensitive method may not be executed depending on $@, which flows from $@. | ConditionalBypass.cs:24:13:24:45 | call to method Equals | this condition | ConditionalBypass.cs:21:34:21:52 | access to property Cookies | user input | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected index 9fea9d5d65b..5f031e3db29 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected @@ -9,6 +9,27 @@ edges | InappropriateEncoding.cs:68:16:68:42 | call to method Replace | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | | SqlEncode.cs:16:62:16:87 | call to method Replace | SqlEncode.cs:17:46:17:50 | access to local variable query | | UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | UrlEncode.cs:12:31:12:69 | ... + ... | +nodes +| HtmlEncode.cs:12:28:12:65 | ... + ... | +| HtmlEncode.cs:12:40:12:65 | call to method UrlEncode | +| InappropriateEncoding.cs:15:28:15:40 | call to method Encode | +| InappropriateEncoding.cs:15:28:15:40 | call to method Encode | +| InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | +| InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | +| InappropriateEncoding.cs:33:22:33:34 | call to method Encode | +| InappropriateEncoding.cs:34:22:34:49 | call to method UrlEncode | +| InappropriateEncoding.cs:35:22:35:73 | call to method UrlEncode | +| InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | +| InappropriateEncoding.cs:37:32:37:43 | access to local variable encodedValue | +| InappropriateEncoding.cs:38:22:38:59 | ... + ... | +| InappropriateEncoding.cs:39:22:39:71 | call to method Format | +| InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | +| InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | +| InappropriateEncoding.cs:68:16:68:42 | call to method Replace | +| SqlEncode.cs:16:62:16:87 | call to method Replace | +| SqlEncode.cs:17:46:17:50 | access to local variable query | +| UrlEncode.cs:12:31:12:69 | ... + ... | +| UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | #select | HtmlEncode.cs:12:28:12:65 | ... + ... | HtmlEncode.cs:12:40:12:65 | call to method UrlEncode | HtmlEncode.cs:12:28:12:65 | ... + ... | This HTML expression may include data from a $@. | HtmlEncode.cs:12:40:12:65 | call to method UrlEncode | possibly inappropriately encoded value | | InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | InappropriateEncoding.cs:20:46:20:51 | access to local variable query1 | This SQL expression may include data from a $@. | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | possibly inappropriately encoded value | From b4846dc99579843589757db84ad178ed1129c8ce Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 Nov 2018 13:11:08 +0000 Subject: [PATCH 68/94] CPP: Modify NVIHub.ql. --- cpp/ql/src/Best Practices/NVIHub.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Best Practices/NVIHub.ql b/cpp/ql/src/Best Practices/NVIHub.ql index 8f87c89809a..a5e67a2cbee 100644 --- a/cpp/ql/src/Best Practices/NVIHub.ql +++ b/cpp/ql/src/Best Practices/NVIHub.ql @@ -4,7 +4,7 @@ * to enforce invariants that should hold for the whole hierarchy. * This is especially problematic in classes with many * dependencies or dependents. - * @kind table + * @kind problem * @id cpp/nvi-hub * @problem.severity recommendation * @precision low @@ -22,4 +22,4 @@ where f.hasSpecifier("public") and fclass = f.getDeclaringType() and hubIndex = fclass.getMetrics().getAfferentCoupling() * fclass.getMetrics().getEfferentCoupling() and hubIndex > 100 -select f.getFile(), f, "Avoid having public virtual methods (NVI idiom)" +select f, "Avoid having public virtual methods (NVI idiom)" From cab6f1e87cd47fc1242de088ac669403d58e6984 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 Nov 2018 14:39:22 +0000 Subject: [PATCH 69/94] CPP: Backticks. --- change-notes/1.19/analysis-cpp.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index d8c2baa273e..19968ff24c6 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -9,10 +9,10 @@ | Cast between `HRESULT` and a Boolean type (`cpp/hresult-boolean-conversion`) | external/cwe/cwe-253 | Finds logic errors caused by mistakenly treating the Windows `HRESULT` type as a Boolean instead of testing it with the appropriate macros. Enabled by default. | | Setting a DACL to `NULL` in a `SECURITY_DESCRIPTOR` (`cpp/unsafe-dacl-security-descriptor`) | external/cwe/cwe-732 | This query finds code that creates world-writable objects on Windows by setting their DACL to `NULL`. Enabled by default. | | Cast from `char*` to `wchar_t*` | security, external/cwe/cwe-704 | Detects potentially dangerous casts from `char*` to `wchar_t*`. Enabled by default on LGTM. | -| Dead code due to `goto` or `break` statement (`cpp/dead-code-goto`) | maintainability, external/cwe/cwe-561 | Detects dead code following a goto or break statement. Enabled by default on LGTM. | -| Inconsistent direction of for loop | correctness, external/cwe/cwe-835 | This query detects for loops where the increment and guard condition don't appear to correspond. Enabled by default on LGTM. | -| Incorrect Not Operator Usage | security, external/cwe/cwe-480 | This query finds uses of the logical not (!) operator that look like they should be bit-wise not (~). Available but not displayed by default on LGTM. | -| NULL application name with an unquoted path in call to CreateProcess | security, external/cwe/cwe-428 | This query finds unsafe uses of the CreateProcess function. Available but not displayed by default on LGTM. | +| Dead code due to `goto` or `break` statement (`cpp/dead-code-goto`) | maintainability, external/cwe/cwe-561 | Detects dead code following a `goto` or `break` statement. Enabled by default on LGTM. | +| Inconsistent direction of for loop | correctness, external/cwe/cwe-835 | This query detects `for` loops where the increment and guard condition don't appear to correspond. Enabled by default on LGTM. | +| Incorrect Not Operator Usage | security, external/cwe/cwe-480 | This query finds uses of the logical not (`!`) operator that look like they should be bit-wise not (`~`). Available but not displayed by default on LGTM. | +| NULL application name with an unquoted path in call to CreateProcess | security, external/cwe/cwe-428 | This query finds unsafe uses of the `CreateProcess` function. Available but not displayed by default on LGTM. | ## Changes to existing queries From 1b69006c206080906cfa0ba5f171cbae8a9ab7ec Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 Nov 2018 15:09:09 +0000 Subject: [PATCH 70/94] CPP: Combine two of the Missing return statement change notes. --- change-notes/1.19/analysis-cpp.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index 19968ff24c6..6d176ae6b5a 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -22,12 +22,11 @@ | Expression has no effect | Fewer false positive results | Expressions in template instantiations are now excluded from this query. | | Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. Also fixed an issue where false positives could occur if the destructor body was not in the snapshot. | | Missing return statement (`cpp/missing-return`) | Visible by default | The precision of this query has been increased from 'medium' to 'high', which makes it visible by default in LGTM. It was 'medium' in release 1.17 and 1.18 because it had false positives due to an extractor bug that was fixed in 1.18. | -| Missing return statement | Fewer false positive results | The query is now produces correct results when a function returns a template-dependent type. | +| Missing return statement | Fewer false positive results | The query is now produces correct results when a function returns a template-dependent type, or makes a non-returning call to another function. | | Call to memory access function may overflow buffer | More correct results | Array indexing with a negative index is now detected by this query. | | Suspicious call to memset | Fewer false positive results | Types involving decltype are now correctly compared. | | Suspicious add with sizeof | Fewer false positive results | Arithmetic with void pointers (where allowed) is now excluded from this query. | | Wrong type of arguments to formatting function | Fewer false positive results | False positive results involving typedefs have been removed. Expected argument types are determined more accurately, especially for wide string and pointer types. Custom (non-standard) formatting functions are also identified more accurately. | -| Missing return statement | Fewer false positive results | Functions which make a non-returning function call are no longer expected to have a return statement after that call. | | AV Rule 164 | Fewer false positive results | This query now accounts for explicit casts. | | Negation of unsigned value | Fewer false positive results | This query now accounts for explicit casts. | | Variable scope too large | Fewer false positive results | Variables with declarations in header files, or that are used at file scope, are now excluded from this query. | From 3eae1cd500a6898aca824119d70f88d9d73994f5 Mon Sep 17 00:00:00 2001 From: calum Date: Wed, 21 Nov 2018 17:28:48 +0000 Subject: [PATCH 71/94] C#: Update test outputs. --- .../dataflow/global/DataFlowPath.expected | 130 +++++++++++++ .../global/TaintTrackingPath.expected | 175 ++++++++++++++++++ 2 files changed, 305 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected index e76529ab3ae..d02b28059d6 100644 --- a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected @@ -172,6 +172,136 @@ edges | GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | | GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +nodes +| Capture.cs:7:20:7:26 | tainted | +| Capture.cs:9:9:13:9 | SSA capture def(tainted) | +| Capture.cs:12:19:12:24 | access to local variable sink27 | +| Capture.cs:14:9:14:20 | tainted [implicit argument] | +| Capture.cs:18:13:22:13 | SSA capture def(tainted) | +| Capture.cs:21:23:21:28 | access to local variable sink28 | +| Capture.cs:25:9:25:20 | tainted [implicit argument] | +| Capture.cs:27:43:32:9 | SSA capture def(tainted) | +| Capture.cs:30:19:30:24 | access to local variable sink29 | +| Capture.cs:33:9:33:40 | tainted [implicit argument] | +| Capture.cs:57:13:57:35 | SSA def(sink30) | +| Capture.cs:57:22:57:35 | "taint source" | +| Capture.cs:59:9:59:21 | SSA call def(sink30) | +| Capture.cs:60:15:60:20 | access to local variable sink30 | +| Capture.cs:67:17:67:39 | SSA def(sink31) | +| Capture.cs:67:26:67:39 | "taint source" | +| Capture.cs:71:9:71:21 | SSA call def(sink31) | +| Capture.cs:72:15:72:20 | access to local variable sink31 | +| Capture.cs:77:13:77:35 | SSA def(sink32) | +| Capture.cs:77:22:77:35 | "taint source" | +| Capture.cs:80:9:80:41 | SSA call def(sink32) | +| Capture.cs:81:15:81:20 | access to local variable sink32 | +| Capture.cs:101:25:101:31 | tainted | +| Capture.cs:108:9:108:25 | SSA call def(sink33) | +| Capture.cs:108:9:108:25 | tainted [implicit argument] | +| Capture.cs:109:15:109:20 | access to local variable sink33 | +| Capture.cs:120:9:120:25 | SSA call def(sink34) | +| Capture.cs:120:9:120:25 | tainted [implicit argument] | +| Capture.cs:121:15:121:20 | access to local variable sink34 | +| Capture.cs:129:9:129:45 | SSA call def(sink35) | +| Capture.cs:129:9:129:45 | tainted [implicit argument] | +| Capture.cs:130:15:130:20 | access to local variable sink35 | +| Capture.cs:136:22:136:38 | call to local function CaptureThrough4 | +| Capture.cs:136:22:136:38 | tainted [implicit argument] | +| Capture.cs:137:15:137:20 | access to local variable sink36 | +| Capture.cs:144:9:144:32 | SSA call def(sink37) | +| Capture.cs:144:25:144:31 | access to parameter tainted | +| Capture.cs:145:15:145:20 | access to local variable sink37 | +| Capture.cs:170:22:170:32 | call to local function Id | +| Capture.cs:170:25:170:31 | access to parameter tainted | +| Capture.cs:171:15:171:20 | access to local variable sink38 | +| GlobalDataFlow.cs:17:27:17:40 | "taint source" | +| GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | +| GlobalDataFlow.cs:26:15:26:32 | access to property SinkProperty0 | +| GlobalDataFlow.cs:35:13:35:30 | access to property SinkProperty0 | +| GlobalDataFlow.cs:37:35:37:52 | access to property SinkProperty0 | +| GlobalDataFlow.cs:44:30:44:39 | sinkParam2 | +| GlobalDataFlow.cs:44:50:44:59 | access to parameter sinkParam2 | +| GlobalDataFlow.cs:45:13:45:30 | access to property SinkProperty0 | +| GlobalDataFlow.cs:52:20:52:37 | access to property SinkProperty0 | +| GlobalDataFlow.cs:53:15:53:15 | x | +| GlobalDataFlow.cs:53:24:53:24 | access to parameter x | +| GlobalDataFlow.cs:53:28:53:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:54:44:54:61 | access to property SinkProperty0 | +| GlobalDataFlow.cs:55:28:55:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:56:37:56:37 | x | +| GlobalDataFlow.cs:56:46:56:46 | access to parameter x | +| GlobalDataFlow.cs:57:35:57:52 | access to property SinkProperty0 | +| GlobalDataFlow.cs:64:22:64:39 | access to property SinkProperty0 | +| GlobalDataFlow.cs:70:21:70:46 | call to method Return | +| GlobalDataFlow.cs:70:28:70:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | +| GlobalDataFlow.cs:72:29:72:101 | call to method Invoke | +| GlobalDataFlow.cs:72:94:72:98 | access to local variable sink0 | +| GlobalDataFlow.cs:73:15:73:19 | access to local variable sink1 | +| GlobalDataFlow.cs:75:19:75:23 | access to local variable sink1 | +| GlobalDataFlow.cs:75:30:75:34 | SSA def(sink2) | +| GlobalDataFlow.cs:76:15:76:19 | access to local variable sink2 | +| GlobalDataFlow.cs:78:19:78:23 | access to local variable sink2 | +| GlobalDataFlow.cs:78:30:78:34 | SSA def(sink3) | +| GlobalDataFlow.cs:79:15:79:19 | access to local variable sink3 | +| GlobalDataFlow.cs:131:21:131:34 | delegate call | +| GlobalDataFlow.cs:131:29:131:33 | access to local variable sink3 | +| GlobalDataFlow.cs:132:15:132:19 | access to local variable sink4 | +| GlobalDataFlow.cs:139:21:139:44 | call to method ApplyFunc | +| GlobalDataFlow.cs:139:39:139:43 | access to local variable sink4 | +| GlobalDataFlow.cs:140:15:140:19 | access to local variable sink5 | +| GlobalDataFlow.cs:149:21:149:25 | call to method Out | +| GlobalDataFlow.cs:150:15:150:19 | access to local variable sink6 | +| GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | +| GlobalDataFlow.cs:153:15:153:19 | access to local variable sink7 | +| GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | +| GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | +| GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | +| GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | +| GlobalDataFlow.cs:175:35:175:48 | "taint source" | +| GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | +| GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:186:15:186:20 | access to local variable sink10 | +| GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:194:15:194:20 | access to local variable sink19 | +| GlobalDataFlow.cs:230:26:230:35 | sinkParam0 | +| GlobalDataFlow.cs:230:26:230:35 | sinkParam0 | +| GlobalDataFlow.cs:232:16:232:25 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:232:16:232:25 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:236:26:236:35 | sinkParam1 | +| GlobalDataFlow.cs:238:15:238:24 | access to parameter sinkParam1 | +| GlobalDataFlow.cs:241:26:241:35 | sinkParam3 | +| GlobalDataFlow.cs:243:15:243:24 | access to parameter sinkParam3 | +| GlobalDataFlow.cs:246:26:246:35 | sinkParam4 | +| GlobalDataFlow.cs:248:15:248:24 | access to parameter sinkParam4 | +| GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | +| GlobalDataFlow.cs:253:15:253:24 | access to parameter sinkParam5 | +| GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | +| GlobalDataFlow.cs:258:15:258:24 | access to parameter sinkParam6 | +| GlobalDataFlow.cs:261:26:261:35 | sinkParam7 | +| GlobalDataFlow.cs:263:15:263:24 | access to parameter sinkParam7 | +| GlobalDataFlow.cs:313:16:313:29 | "taint source" | +| GlobalDataFlow.cs:318:13:318:26 | "taint source" | +| GlobalDataFlow.cs:323:13:323:26 | "taint source" | +| GlobalDataFlow.cs:354:41:354:41 | x | +| GlobalDataFlow.cs:354:41:354:41 | x | +| GlobalDataFlow.cs:356:11:356:11 | access to parameter x | +| GlobalDataFlow.cs:356:11:356:11 | access to parameter x | +| GlobalDataFlow.cs:368:52:368:52 | x | +| GlobalDataFlow.cs:368:52:368:52 | x | +| GlobalDataFlow.cs:368:52:368:52 | x | +| GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:373:39:373:45 | tainted | +| GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | +| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | +| GlobalDataFlow.cs:399:9:399:11 | value | +| GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | +| GlobalDataFlow.cs:410:22:410:35 | "taint source" | #select | GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | access to field SinkField0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | | GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | access to local variable sink0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected index 08dc92d3b26..7c1c2b73e46 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected @@ -215,6 +215,181 @@ edges | GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | | GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +nodes +| Capture.cs:7:20:7:26 | tainted | +| Capture.cs:9:9:13:9 | SSA capture def(tainted) | +| Capture.cs:12:19:12:24 | access to local variable sink27 | +| Capture.cs:14:9:14:20 | tainted [implicit argument] | +| Capture.cs:18:13:22:13 | SSA capture def(tainted) | +| Capture.cs:21:23:21:28 | access to local variable sink28 | +| Capture.cs:25:9:25:20 | tainted [implicit argument] | +| Capture.cs:27:43:32:9 | SSA capture def(tainted) | +| Capture.cs:30:19:30:24 | access to local variable sink29 | +| Capture.cs:33:9:33:40 | tainted [implicit argument] | +| Capture.cs:57:13:57:35 | SSA def(sink30) | +| Capture.cs:57:22:57:35 | "taint source" | +| Capture.cs:59:9:59:21 | SSA call def(sink30) | +| Capture.cs:60:15:60:20 | access to local variable sink30 | +| Capture.cs:67:17:67:39 | SSA def(sink31) | +| Capture.cs:67:26:67:39 | "taint source" | +| Capture.cs:71:9:71:21 | SSA call def(sink31) | +| Capture.cs:72:15:72:20 | access to local variable sink31 | +| Capture.cs:77:13:77:35 | SSA def(sink32) | +| Capture.cs:77:22:77:35 | "taint source" | +| Capture.cs:80:9:80:41 | SSA call def(sink32) | +| Capture.cs:81:15:81:20 | access to local variable sink32 | +| Capture.cs:101:25:101:31 | tainted | +| Capture.cs:108:9:108:25 | SSA call def(sink33) | +| Capture.cs:108:9:108:25 | tainted [implicit argument] | +| Capture.cs:109:15:109:20 | access to local variable sink33 | +| Capture.cs:120:9:120:25 | SSA call def(sink34) | +| Capture.cs:120:9:120:25 | tainted [implicit argument] | +| Capture.cs:121:15:121:20 | access to local variable sink34 | +| Capture.cs:129:9:129:45 | SSA call def(sink35) | +| Capture.cs:129:9:129:45 | tainted [implicit argument] | +| Capture.cs:130:15:130:20 | access to local variable sink35 | +| Capture.cs:136:22:136:38 | call to local function CaptureThrough4 | +| Capture.cs:136:22:136:38 | tainted [implicit argument] | +| Capture.cs:137:15:137:20 | access to local variable sink36 | +| Capture.cs:144:9:144:32 | SSA call def(sink37) | +| Capture.cs:144:25:144:31 | access to parameter tainted | +| Capture.cs:145:15:145:20 | access to local variable sink37 | +| Capture.cs:170:22:170:32 | call to local function Id | +| Capture.cs:170:25:170:31 | access to parameter tainted | +| Capture.cs:171:15:171:20 | access to local variable sink38 | +| GlobalDataFlow.cs:17:27:17:40 | "taint source" | +| GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | +| GlobalDataFlow.cs:26:15:26:32 | access to property SinkProperty0 | +| GlobalDataFlow.cs:35:13:35:30 | access to property SinkProperty0 | +| GlobalDataFlow.cs:37:35:37:52 | access to property SinkProperty0 | +| GlobalDataFlow.cs:44:30:44:39 | sinkParam2 | +| GlobalDataFlow.cs:44:50:44:59 | access to parameter sinkParam2 | +| GlobalDataFlow.cs:45:13:45:30 | access to property SinkProperty0 | +| GlobalDataFlow.cs:52:20:52:37 | access to property SinkProperty0 | +| GlobalDataFlow.cs:53:15:53:15 | x | +| GlobalDataFlow.cs:53:24:53:24 | access to parameter x | +| GlobalDataFlow.cs:53:28:53:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:54:44:54:61 | access to property SinkProperty0 | +| GlobalDataFlow.cs:55:28:55:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:56:37:56:37 | x | +| GlobalDataFlow.cs:56:46:56:46 | access to parameter x | +| GlobalDataFlow.cs:57:35:57:52 | access to property SinkProperty0 | +| GlobalDataFlow.cs:64:22:64:39 | access to property SinkProperty0 | +| GlobalDataFlow.cs:70:21:70:46 | call to method Return | +| GlobalDataFlow.cs:70:28:70:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | +| GlobalDataFlow.cs:72:29:72:101 | call to method Invoke | +| GlobalDataFlow.cs:72:94:72:98 | access to local variable sink0 | +| GlobalDataFlow.cs:73:15:73:19 | access to local variable sink1 | +| GlobalDataFlow.cs:75:19:75:23 | access to local variable sink1 | +| GlobalDataFlow.cs:75:30:75:34 | SSA def(sink2) | +| GlobalDataFlow.cs:76:15:76:19 | access to local variable sink2 | +| GlobalDataFlow.cs:78:19:78:23 | access to local variable sink2 | +| GlobalDataFlow.cs:78:30:78:34 | SSA def(sink3) | +| GlobalDataFlow.cs:79:15:79:19 | access to local variable sink3 | +| GlobalDataFlow.cs:80:22:80:85 | call to method SelectEven | +| GlobalDataFlow.cs:80:23:80:65 | (...) ... | +| GlobalDataFlow.cs:81:15:81:20 | access to local variable sink13 | +| GlobalDataFlow.cs:82:23:82:74 | (...) ... | +| GlobalDataFlow.cs:82:84:82:94 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:83:15:83:20 | access to local variable sink14 | +| GlobalDataFlow.cs:84:23:84:74 | (...) ... | +| GlobalDataFlow.cs:84:125:84:135 | [implicit call] (...) => ... | +| GlobalDataFlow.cs:85:15:85:20 | access to local variable sink15 | +| GlobalDataFlow.cs:86:70:86:121 | (...) ... | +| GlobalDataFlow.cs:86:125:86:135 | [implicit call] (...) => ... | +| GlobalDataFlow.cs:87:15:87:20 | access to local variable sink16 | +| GlobalDataFlow.cs:88:22:88:27 | access to local variable sink14 | +| GlobalDataFlow.cs:88:43:88:61 | [implicit call] (...) => ... | +| GlobalDataFlow.cs:88:64:88:69 | [implicit call] (...) => ... | +| GlobalDataFlow.cs:89:15:89:20 | access to local variable sink17 | +| GlobalDataFlow.cs:90:75:90:88 | call to method First | +| GlobalDataFlow.cs:90:91:90:109 | [implicit call] (...) => ... | +| GlobalDataFlow.cs:90:112:90:117 | [implicit call] (...) => ... | +| GlobalDataFlow.cs:91:15:91:20 | access to local variable sink18 | +| GlobalDataFlow.cs:94:15:94:20 | access to local variable sink21 | +| GlobalDataFlow.cs:97:15:97:20 | access to local variable sink22 | +| GlobalDataFlow.cs:131:21:131:34 | delegate call | +| GlobalDataFlow.cs:131:29:131:33 | access to local variable sink3 | +| GlobalDataFlow.cs:132:15:132:19 | access to local variable sink4 | +| GlobalDataFlow.cs:139:21:139:44 | call to method ApplyFunc | +| GlobalDataFlow.cs:139:39:139:43 | access to local variable sink4 | +| GlobalDataFlow.cs:140:15:140:19 | access to local variable sink5 | +| GlobalDataFlow.cs:149:21:149:25 | call to method Out | +| GlobalDataFlow.cs:150:15:150:19 | access to local variable sink6 | +| GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | +| GlobalDataFlow.cs:153:15:153:19 | access to local variable sink7 | +| GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | +| GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | +| GlobalDataFlow.cs:157:22:157:31 | call to method OutYield | +| GlobalDataFlow.cs:158:15:158:20 | access to local variable sink12 | +| GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | +| GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | +| GlobalDataFlow.cs:175:35:175:48 | "taint source" | +| GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | +| GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:186:15:186:20 | access to local variable sink10 | +| GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:194:15:194:20 | access to local variable sink19 | +| GlobalDataFlow.cs:201:39:201:45 | tainted | +| GlobalDataFlow.cs:204:35:204:45 | sinkParam10 | +| GlobalDataFlow.cs:204:58:204:68 | access to parameter sinkParam10 | +| GlobalDataFlow.cs:205:71:205:71 | x | +| GlobalDataFlow.cs:205:89:205:89 | access to parameter x | +| GlobalDataFlow.cs:206:22:206:28 | access to parameter tainted | +| GlobalDataFlow.cs:206:37:206:38 | [implicit call] access to local variable f1 | +| GlobalDataFlow.cs:207:15:207:20 | access to local variable sink24 | +| GlobalDataFlow.cs:208:22:208:28 | access to parameter tainted | +| GlobalDataFlow.cs:208:37:208:38 | [implicit call] access to local variable f2 | +| GlobalDataFlow.cs:209:15:209:20 | access to local variable sink25 | +| GlobalDataFlow.cs:210:22:210:28 | access to parameter tainted | +| GlobalDataFlow.cs:210:37:210:48 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:211:15:211:20 | access to local variable sink26 | +| GlobalDataFlow.cs:230:26:230:35 | sinkParam0 | +| GlobalDataFlow.cs:230:26:230:35 | sinkParam0 | +| GlobalDataFlow.cs:232:16:232:25 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:232:16:232:25 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | +| GlobalDataFlow.cs:236:26:236:35 | sinkParam1 | +| GlobalDataFlow.cs:238:15:238:24 | access to parameter sinkParam1 | +| GlobalDataFlow.cs:241:26:241:35 | sinkParam3 | +| GlobalDataFlow.cs:243:15:243:24 | access to parameter sinkParam3 | +| GlobalDataFlow.cs:246:26:246:35 | sinkParam4 | +| GlobalDataFlow.cs:248:15:248:24 | access to parameter sinkParam4 | +| GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | +| GlobalDataFlow.cs:253:15:253:24 | access to parameter sinkParam5 | +| GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | +| GlobalDataFlow.cs:258:15:258:24 | access to parameter sinkParam6 | +| GlobalDataFlow.cs:261:26:261:35 | sinkParam7 | +| GlobalDataFlow.cs:263:15:263:24 | access to parameter sinkParam7 | +| GlobalDataFlow.cs:287:31:287:40 | sinkParam8 | +| GlobalDataFlow.cs:289:15:289:24 | access to parameter sinkParam8 | +| GlobalDataFlow.cs:293:32:293:41 | sinkParam9 | +| GlobalDataFlow.cs:295:15:295:24 | access to parameter sinkParam9 | +| GlobalDataFlow.cs:299:32:299:42 | sinkParam11 | +| GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 | +| GlobalDataFlow.cs:313:16:313:29 | "taint source" | +| GlobalDataFlow.cs:318:13:318:26 | "taint source" | +| GlobalDataFlow.cs:323:13:323:26 | "taint source" | +| GlobalDataFlow.cs:329:22:329:35 | "taint source" | +| GlobalDataFlow.cs:354:41:354:41 | x | +| GlobalDataFlow.cs:354:41:354:41 | x | +| GlobalDataFlow.cs:356:11:356:11 | access to parameter x | +| GlobalDataFlow.cs:356:11:356:11 | access to parameter x | +| GlobalDataFlow.cs:368:52:368:52 | x | +| GlobalDataFlow.cs:368:52:368:52 | x | +| GlobalDataFlow.cs:368:52:368:52 | x | +| GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:373:39:373:45 | tainted | +| GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | +| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | +| GlobalDataFlow.cs:399:9:399:11 | value | +| GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | +| GlobalDataFlow.cs:410:22:410:35 | "taint source" | #select | GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | access to field SinkField0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | | GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | access to local variable sink0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | From 03802ed409ffc0e953fce024c519a9ad5bbe1879 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 21 Nov 2018 15:35:05 -0800 Subject: [PATCH 72/94] C++: Allow filtering of IR creation to speed up dumps This change provides a mechanism by which a query can tell the IR package to only create IR for certain functions. This is mostly useful for "PrintIR.qll", which uses this feature to avoid the expense of creating IR for functions that aren't going to be printed. --- cpp/ql/src/semmle/code/cpp/PrintAST.qll | 26 ++++++++-- .../semmle/code/cpp/ir/IRConfiguration.qll | 19 ++++++++ .../cpp/ir/implementation/raw/PrintIR.qll | 47 +++++++++++++++++-- 3 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 cpp/ql/src/semmle/code/cpp/ir/IRConfiguration.qll diff --git a/cpp/ql/src/semmle/code/cpp/PrintAST.qll b/cpp/ql/src/semmle/code/cpp/PrintAST.qll index 3956ac428c1..803758f986c 100644 --- a/cpp/ql/src/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/src/semmle/code/cpp/PrintAST.qll @@ -59,18 +59,36 @@ private predicate locationSortKeys(Locatable ast, string file, int line, ) } +private Function getEnclosingFunction(Locatable ast) { + result = ast.(Expr).getEnclosingFunction() or + result = ast.(Stmt).getEnclosingFunction() or + result = ast.(Initializer).getExpr().getEnclosingFunction() or + result = ast.(Parameter).getFunction() or + exists(DeclStmt stmt | + stmt.getADeclarationEntry() = ast and + result = stmt.getEnclosingFunction() + ) or + result = ast +} + /** * Most nodes are just a wrapper around `Locatable`, but we do synthesize new * nodes for things like parameter lists and constructor init lists. */ private newtype TPrintASTNode = - TASTNode(Locatable ast) or - TParametersNode(Function func) or + TASTNode(Locatable ast) { + shouldPrintFunction(getEnclosingFunction(ast)) + } or + TParametersNode(Function func) { + shouldPrintFunction(func) + } or TConstructorInitializersNode(Constructor ctor) { - ctor.hasEntryPoint() + ctor.hasEntryPoint() and + shouldPrintFunction(ctor) } or TDestructorDestructionsNode(Destructor dtor) { - dtor.hasEntryPoint() + dtor.hasEntryPoint() and + shouldPrintFunction(dtor) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/IRConfiguration.qll b/cpp/ql/src/semmle/code/cpp/ir/IRConfiguration.qll new file mode 100644 index 00000000000..feb510b2ab8 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/IRConfiguration.qll @@ -0,0 +1,19 @@ +import cpp + +private newtype TIRConfiguration = MkIRConfiguration() + +/** + * The query can extend this class to control which functions have IR generated for them. + */ +class IRConfiguration extends TIRConfiguration { + string toString() { + result = "IRConfiguration" + } + + /** + * Holds if IR should be created for function `func`. By default, holds for all functions. + */ + predicate shouldCreateIRForFunction(Function func) { + any() + } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll index 478e92fac5c..8fb77621426 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll @@ -1,5 +1,40 @@ private import IR import cpp +import semmle.code.cpp.ir.IRConfiguration + +private newtype TPrintIRConfiguration = MkPrintIRConfiguration() + +/** + * The query can extend this class to control which functions are printed. + */ +class PrintIRConfiguration extends TPrintIRConfiguration { + string toString() { + result = "PrintIRConfiguration" + } + + /** + * Holds if the IR for `func` should be printed. By default, holds for all + * functions. + */ + predicate shouldPrintFunction(Function func) { + any() + } +} + +private predicate shouldPrintFunction(Function func) { + exists(PrintIRConfiguration config | + config.shouldPrintFunction(func) + ) +} + +/** + * Override of `IRConfiguration` to only create IR for the functions that are to be dumped. + */ +private class FilteredIRConfiguration extends IRConfiguration { + override predicate shouldCreateIRForFunction(Function func) { + shouldPrintFunction(func) + } +} private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | @@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) { } private newtype TPrintableIRNode = - TPrintableFunctionIR(FunctionIR funcIR) or - TPrintableIRBlock(IRBlock block) or - TPrintableInstruction(Instruction instr) + TPrintableFunctionIR(FunctionIR funcIR) { + shouldPrintFunction(funcIR.getFunction()) + } or + TPrintableIRBlock(IRBlock block) { + shouldPrintFunction(block.getFunction()) + } or + TPrintableInstruction(Instruction instr) { + shouldPrintFunction(instr.getFunction()) + } /** * A node to be emitted in the IR graph. From 7db36b2a22eb7349faf728f3f5949aabd02653c5 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 21 Nov 2018 15:38:56 -0800 Subject: [PATCH 73/94] C++: Skip IR translation for functions with invalid ASTs An slightly invalid AST can cause IR construction to generate extremely bad IR. This change provides a single place to detect invalid ASTs, and to skip IR construction for the affected functions. --- .../raw/internal/TranslatedElement.qll | 75 ++++++++++++++++--- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 1be620d1206..7d30fc74076 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -1,5 +1,7 @@ import cpp +import cpp import semmle.code.cpp.ir.implementation.raw.IR +private import semmle.code.cpp.ir.IRConfiguration private import semmle.code.cpp.ir.implementation.Opcode private import semmle.code.cpp.ir.internal.OperandTag private import semmle.code.cpp.ir.internal.TempVariableTag @@ -83,7 +85,8 @@ private predicate ignoreExprOnly(Expr expr) { // Ignore the allocator call, because we always synthesize it. Don't ignore // its arguments, though, because we use them as part of the synthesis. newExpr.getAllocatorCall() = expr - ) + ) or + not translateFunction(expr.getEnclosingFunction()) } /** @@ -94,6 +97,49 @@ private predicate ignoreExpr(Expr expr) { ignoreExprAndDescendants(getRealParent*(expr)) } +/** + * Holds if `func` contains an AST that cannot be translated into IR. This is mostly used to work + * around extractor bugs. Once the relevant extractor bugs are fixed, this predicate can be removed. + */ +private predicate isInvalidFunction(Function func) { + exists(Literal literal | + // Constructor field inits within a compiler-generated copy constructor have a source expression + // that is a `Literal` with no value. + literal = func.(Constructor).getAnInitializer().(ConstructorFieldInit).getExpr() and + not exists(literal.getValue()) + ) or + exists(ThisExpr thisExpr | + // An instantiation of a member function template is not treated as a `MemberFunction` if it has + // only non-type template arguments. + thisExpr.getEnclosingFunction() = func and + not func instanceof MemberFunction + ) or + exists(Expr expr | + // Expression missing a type. + expr.getEnclosingFunction() = func and + not exists(expr.getType()) + ) +} + +/** + * Holds if `func` should be translated to IR. + */ +private predicate translateFunction(Function func) { + not func.isFromUninstantiatedTemplate(_) and + func.hasEntryPoint() and + not isInvalidFunction(func) and + exists(IRConfiguration config | + config.shouldCreateIRForFunction(func) + ) +} + +/** + * Holds if `stmt` should be translated to IR. + */ +private predicate translateStmt(Stmt stmt) { + translateFunction(stmt.getEnclosingFunction()) +} + /** * Holds if `expr` is most naturally evaluated as control flow, rather than as * a value. @@ -236,7 +282,7 @@ newtype TTranslatedElement = } or // The initialization of a field via a member of an initializer list. TTranslatedExplicitFieldInitialization(Expr ast, Field field, - Expr expr) { + Expr expr) { exists(ClassAggregateLiteral initList | not ignoreExpr(initList) and ast = initList and @@ -260,14 +306,14 @@ newtype TTranslatedElement = } or // The initialization of an array element via a member of an initializer list. TTranslatedExplicitElementInitialization( - ArrayAggregateLiteral initList, int elementIndex) { + ArrayAggregateLiteral initList, int elementIndex) { not ignoreExpr(initList) and exists(initList.getElementExpr(elementIndex)) } or // The value initialization of a range of array elements that were omitted // from an initializer list. TTranslatedElementValueInitialization(ArrayAggregateLiteral initList, - int elementIndex, int elementCount) { + int elementIndex, int elementCount) { not ignoreExpr(initList) and isFirstValueInitializedElementInRange(initList, elementIndex) and elementCount = @@ -287,28 +333,35 @@ newtype TTranslatedElement = not ignoreExpr(destruction) } or // A statement - TTranslatedStmt(Stmt stmt) or + TTranslatedStmt(Stmt stmt) { + translateStmt(stmt) + } or // A function TTranslatedFunction(Function func) { - func.hasEntryPoint() and - not func.isFromUninstantiatedTemplate(_) + translateFunction(func) } or // A constructor init list TTranslatedConstructorInitList(Function func) { - func.hasEntryPoint() + translateFunction(func) } or // A destructor destruction list TTranslatedDestructorDestructionList(Function func) { - func.hasEntryPoint() + translateFunction(func) } or // A function parameter TTranslatedParameter(Parameter param) { - param.getFunction().hasEntryPoint() or - exists(param.getCatchBlock()) + exists(Function func | + ( + func = param.getFunction() or + func = param.getCatchBlock().getEnclosingFunction() + ) and + translateFunction(func) + ) } or // A local declaration TTranslatedDeclarationEntry(DeclarationEntry entry) { exists(DeclStmt declStmt | + translateStmt(declStmt) and declStmt.getADeclarationEntry() = entry ) } or From 97fd7b46cccea9a953bb1b469ea82810824982cd Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 21 Nov 2018 16:39:08 -0800 Subject: [PATCH 74/94] C++: Add tests for filtering bad ASTs --- .../library-tests/ir/ir/PrintAST.expected | 136 ++++++++++++++++++ .../ir/ir/aliased_ssa_ir.expected | 45 ++++++ cpp/ql/test/library-tests/ir/ir/bad_asts.cpp | 29 ++++ .../test/library-tests/ir/ir/raw_ir.expected | 45 ++++++ .../ir/ir/ssa_block_count.expected | 3 + .../ir/ir/unaliased_ssa_ir.expected | 45 ++++++ 6 files changed, 303 insertions(+) create mode 100644 cpp/ql/test/library-tests/ir/ir/bad_asts.cpp diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 884abe554a6..355c0d707aa 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -34,6 +34,142 @@ #-----| Type = unsigned long #-----| 1: p#1 #-----| Type = align_val_t +bad_asts.cpp: +# 5| Bad::S::operator=(S &&) -> S & +# 5| params: +#-----| 0: p#0 +#-----| Type = S && +# 5| Bad::S::operator=(const S &) -> S & +# 5| params: +#-----| 0: p#0 +#-----| Type = const S & +# 9| Bad::S::MemberFunction(int) -> int +# 9| params: +# 9| 0: y +# 9| Type = int +# 9| body: { ... } +# 10| 0: return ... +# 10| 0: ... + ... +# 10| Type = int +# 10| ValueCategory = prvalue +# 10| 0: ... + ... +# 10| Type = int +# 10| ValueCategory = prvalue +# 10| 0: Unknown literal +# 10| Type = int +# 10| ValueCategory = prvalue +# 10| 1: x +# 10| Type = int +# 10| ValueCategory = prvalue(load) +#-----| -1: this +#-----| Type = S * +#-----| ValueCategory = prvalue(load) +# 10| 1: y +# 10| Type = int +# 10| ValueCategory = prvalue(load) +# 9| MemberFunction(int) -> int +# 9| params: +# 9| 0: y +# 9| Type = int +# 9| body: { ... } +# 10| 0: return ... +# 10| 0: ... + ... +# 10| Type = int +# 10| ValueCategory = prvalue +# 10| 0: ... + ... +# 10| Type = int +# 10| ValueCategory = prvalue +# 10| 0: 6 +# 10| Type = int +# 10| Value = 6 +# 10| ValueCategory = prvalue +# 10| 1: x +# 10| Type = int +# 10| ValueCategory = prvalue(load) +#-----| -1: this +#-----| Type = S * +#-----| ValueCategory = prvalue(load) +# 10| 1: y +# 10| Type = int +# 10| ValueCategory = prvalue(load) +# 14| Bad::CallBadMemberFunction() -> void +# 14| params: +# 14| body: { ... } +# 15| 0: declaration +# 15| 0: definition of s +# 15| Type = S +# 15| init: initializer for s +# 15| expr: {...} +# 15| Type = S +# 15| ValueCategory = prvalue +# 16| 1: ExprStmt +# 16| 0: call to MemberFunction +# 16| Type = int +# 16| ValueCategory = prvalue +# 16| -1: s +# 16| Type = S +# 16| ValueCategory = lvalue +# 16| 0: 1 +# 16| Type = int +# 16| Value = 1 +# 16| ValueCategory = prvalue +# 17| 2: return ... +# 19| Bad::Point::Point(Point &&) -> void +# 19| params: +#-----| 0: p#0 +#-----| Type = Point && +# 19| Bad::Point::Point(const Point &) -> void +# 19| params: +#-----| 0: p#0 +#-----| Type = const Point & +# 19| initializations: +# 19| 0: constructor init of field x +# 19| Type = int +# 19| ValueCategory = prvalue +# 19| 0: Unknown literal +# 19| Type = int +# 19| ValueCategory = prvalue +# 19| 1: constructor init of field y +# 19| Type = int +# 19| ValueCategory = prvalue +# 19| 0: Unknown literal +# 19| Type = int +# 19| ValueCategory = prvalue +# 19| body: { ... } +# 19| 0: return ... +# 19| Bad::Point::operator=(Point &&) -> Point & +# 19| params: +#-----| 0: p#0 +#-----| Type = Point && +# 19| Bad::Point::operator=(const Point &) -> Point & +# 19| params: +#-----| 0: p#0 +#-----| Type = const Point & +# 22| Bad::Point::Point() -> void +# 22| params: +# 22| initializations: +# 22| body: { ... } +# 23| 0: return ... +# 26| Bad::CallCopyConstructor(const Point &) -> void +# 26| params: +# 26| 0: a +# 26| Type = const Point & +# 26| body: { ... } +# 27| 0: declaration +# 27| 0: definition of b +# 27| Type = Point +# 27| init: initializer for b +# 27| expr: (Point)... +# 27| Conversion = glvalue conversion +# 27| Type = Point +# 27| ValueCategory = prvalue(load) +# 27| expr: (reference dereference) +# 27| Type = const Point +# 27| ValueCategory = lvalue +# 27| expr: a +# 27| Type = const Point & +# 27| ValueCategory = prvalue(load) +# 28| 1: return ... ir.cpp: # 1| Constants() -> void # 1| params: diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected index 5fbbec2afb7..d5a8844e8c5 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected @@ -1,3 +1,48 @@ +bad_asts.cpp: +# 14| Bad::CallBadMemberFunction() -> void +# 14| Block 0 +# 14| v0_0(void) = EnterFunction : +# 14| mu0_1(unknown) = UnmodeledDefinition : +# 15| r0_2(glval) = VariableAddress[s] : +# 15| r0_3(glval) = FieldAddress[x] : r0_2 +# 15| r0_4(int) = Constant[0] : +# 15| mu0_5(int) = Store : r0_3, r0_4 +# 16| r0_6(glval) = VariableAddress[s] : +# 16| r0_7(glval) = FunctionAddress[MemberFunction] : +# 16| r0_8(int) = Constant[1] : +# 16| r0_9(int) = Call : r0_7, this:r0_6, r0_8 +# 17| v0_10(void) = NoOp : +# 14| v0_11(void) = ReturnVoid : +# 14| v0_12(void) = UnmodeledUse : mu* +# 14| v0_13(void) = ExitFunction : + +# 22| Bad::Point::Point() -> void +# 22| Block 0 +# 22| v0_0(void) = EnterFunction : +# 22| mu0_1(unknown) = UnmodeledDefinition : +# 22| r0_2(glval) = InitializeThis : +# 23| v0_3(void) = NoOp : +# 22| v0_4(void) = ReturnVoid : +# 22| v0_5(void) = UnmodeledUse : mu* +# 22| v0_6(void) = ExitFunction : + +# 26| Bad::CallCopyConstructor(const Point &) -> void +# 26| Block 0 +# 26| v0_0(void) = EnterFunction : +# 26| mu0_1(unknown) = UnmodeledDefinition : +# 26| r0_2(glval) = VariableAddress[a] : +# 26| m0_3(Point &) = InitializeParameter[a] : r0_2 +# 27| r0_4(glval) = VariableAddress[b] : +# 27| r0_5(glval) = VariableAddress[a] : +# 27| r0_6(Point &) = Load : r0_5, m0_3 +# 27| r0_7(glval) = Convert : r0_6 +# 27| r0_8(Point) = Load : r0_7, mu0_1 +# 27| m0_9(Point) = Store : r0_4, r0_8 +# 28| v0_10(void) = NoOp : +# 26| v0_11(void) = ReturnVoid : +# 26| v0_12(void) = UnmodeledUse : mu* +# 26| v0_13(void) = ExitFunction : + ir.cpp: # 1| Constants() -> void # 1| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/bad_asts.cpp b/cpp/ql/test/library-tests/ir/ir/bad_asts.cpp new file mode 100644 index 00000000000..6bd726959c7 --- /dev/null +++ b/cpp/ql/test/library-tests/ir/ir/bad_asts.cpp @@ -0,0 +1,29 @@ +// semmle-extractor-options: -std=c++17 + +// Test cases that illustrate known bad ASTs that we have to work around in IR generation. +namespace Bad { + struct S { + int x; + + template + int MemberFunction(int y) { + return t + x + y; + } + }; + + void CallBadMemberFunction() { + S s = {}; + s.MemberFunction<6>(1); // Not marked as member function in AST. + } + + struct Point { + int x; + int y; + Point() { + } + }; + + void CallCopyConstructor(const Point& a) { + Point b = a; // Copy constructor contains literal expressions with no values. + } +} diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 5f5dc4d3f5d..aa3bcd3d520 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -1,3 +1,48 @@ +bad_asts.cpp: +# 14| Bad::CallBadMemberFunction() -> void +# 14| Block 0 +# 14| v0_0(void) = EnterFunction : +# 14| mu0_1(unknown) = UnmodeledDefinition : +# 15| r0_2(glval) = VariableAddress[s] : +# 15| r0_3(glval) = FieldAddress[x] : r0_2 +# 15| r0_4(int) = Constant[0] : +# 15| mu0_5(int) = Store : r0_3, r0_4 +# 16| r0_6(glval) = VariableAddress[s] : +# 16| r0_7(glval) = FunctionAddress[MemberFunction] : +# 16| r0_8(int) = Constant[1] : +# 16| r0_9(int) = Call : r0_7, this:r0_6, r0_8 +# 17| v0_10(void) = NoOp : +# 14| v0_11(void) = ReturnVoid : +# 14| v0_12(void) = UnmodeledUse : mu* +# 14| v0_13(void) = ExitFunction : + +# 22| Bad::Point::Point() -> void +# 22| Block 0 +# 22| v0_0(void) = EnterFunction : +# 22| mu0_1(unknown) = UnmodeledDefinition : +# 22| r0_2(glval) = InitializeThis : +# 23| v0_3(void) = NoOp : +# 22| v0_4(void) = ReturnVoid : +# 22| v0_5(void) = UnmodeledUse : mu* +# 22| v0_6(void) = ExitFunction : + +# 26| Bad::CallCopyConstructor(const Point &) -> void +# 26| Block 0 +# 26| v0_0(void) = EnterFunction : +# 26| mu0_1(unknown) = UnmodeledDefinition : +# 26| r0_2(glval) = VariableAddress[a] : +# 26| mu0_3(Point &) = InitializeParameter[a] : r0_2 +# 27| r0_4(glval) = VariableAddress[b] : +# 27| r0_5(glval) = VariableAddress[a] : +# 27| r0_6(Point &) = Load : r0_5, mu0_1 +# 27| r0_7(glval) = Convert : r0_6 +# 27| r0_8(Point) = Load : r0_7, mu0_1 +# 27| mu0_9(Point) = Store : r0_4, r0_8 +# 28| v0_10(void) = NoOp : +# 26| v0_11(void) = ReturnVoid : +# 26| v0_12(void) = UnmodeledUse : mu* +# 26| v0_13(void) = ExitFunction : + ir.cpp: # 1| Constants() -> void # 1| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected index 0ef298fee3d..6b396b9bce4 100644 --- a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected +++ b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected @@ -8,6 +8,8 @@ | IR: C | 1 | | IR: Call | 1 | | IR: CallAdd | 1 | +| IR: CallBadMemberFunction | 1 | +| IR: CallCopyConstructor | 1 | | IR: CallMethods | 1 | | IR: CallMin | 1 | | IR: CallNestedTemplateFunc | 1 | @@ -73,6 +75,7 @@ | IR: OperatorNew | 1 | | IR: OperatorNewArray | 1 | | IR: Parameters | 1 | +| IR: Point | 1 | | IR: PointerCompare | 1 | | IR: PointerCrement | 1 | | IR: PointerOps | 1 | diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected index af2385fb03d..fe08e7bc967 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected @@ -1,3 +1,48 @@ +bad_asts.cpp: +# 14| Bad::CallBadMemberFunction() -> void +# 14| Block 0 +# 14| v0_0(void) = EnterFunction : +# 14| mu0_1(unknown) = UnmodeledDefinition : +# 15| r0_2(glval) = VariableAddress[s] : +# 15| r0_3(glval) = FieldAddress[x] : r0_2 +# 15| r0_4(int) = Constant[0] : +# 15| mu0_5(int) = Store : r0_3, r0_4 +# 16| r0_6(glval) = VariableAddress[s] : +# 16| r0_7(glval) = FunctionAddress[MemberFunction] : +# 16| r0_8(int) = Constant[1] : +# 16| r0_9(int) = Call : r0_7, this:r0_6, r0_8 +# 17| v0_10(void) = NoOp : +# 14| v0_11(void) = ReturnVoid : +# 14| v0_12(void) = UnmodeledUse : mu* +# 14| v0_13(void) = ExitFunction : + +# 22| Bad::Point::Point() -> void +# 22| Block 0 +# 22| v0_0(void) = EnterFunction : +# 22| mu0_1(unknown) = UnmodeledDefinition : +# 22| r0_2(glval) = InitializeThis : +# 23| v0_3(void) = NoOp : +# 22| v0_4(void) = ReturnVoid : +# 22| v0_5(void) = UnmodeledUse : mu* +# 22| v0_6(void) = ExitFunction : + +# 26| Bad::CallCopyConstructor(const Point &) -> void +# 26| Block 0 +# 26| v0_0(void) = EnterFunction : +# 26| mu0_1(unknown) = UnmodeledDefinition : +# 26| r0_2(glval) = VariableAddress[a] : +# 26| m0_3(Point &) = InitializeParameter[a] : r0_2 +# 27| r0_4(glval) = VariableAddress[b] : +# 27| r0_5(glval) = VariableAddress[a] : +# 27| r0_6(Point &) = Load : r0_5, m0_3 +# 27| r0_7(glval) = Convert : r0_6 +# 27| r0_8(Point) = Load : r0_7, mu0_1 +# 27| m0_9(Point) = Store : r0_4, r0_8 +# 28| v0_10(void) = NoOp : +# 26| v0_11(void) = ReturnVoid : +# 26| v0_12(void) = UnmodeledUse : mu* +# 26| v0_13(void) = ExitFunction : + ir.cpp: # 1| Constants() -> void # 1| Block 0 From beb9c9c0541eecdedb553b4ca2c7bc949af055a5 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 21 Nov 2018 16:51:47 -0800 Subject: [PATCH 75/94] C++: Sync identical files --- .../ir/implementation/aliased_ssa/PrintIR.qll | 47 +++++++++++++++++-- .../implementation/unaliased_ssa/PrintIR.qll | 47 +++++++++++++++++-- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll index 478e92fac5c..8fb77621426 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll @@ -1,5 +1,40 @@ private import IR import cpp +import semmle.code.cpp.ir.IRConfiguration + +private newtype TPrintIRConfiguration = MkPrintIRConfiguration() + +/** + * The query can extend this class to control which functions are printed. + */ +class PrintIRConfiguration extends TPrintIRConfiguration { + string toString() { + result = "PrintIRConfiguration" + } + + /** + * Holds if the IR for `func` should be printed. By default, holds for all + * functions. + */ + predicate shouldPrintFunction(Function func) { + any() + } +} + +private predicate shouldPrintFunction(Function func) { + exists(PrintIRConfiguration config | + config.shouldPrintFunction(func) + ) +} + +/** + * Override of `IRConfiguration` to only create IR for the functions that are to be dumped. + */ +private class FilteredIRConfiguration extends IRConfiguration { + override predicate shouldCreateIRForFunction(Function func) { + shouldPrintFunction(func) + } +} private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | @@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) { } private newtype TPrintableIRNode = - TPrintableFunctionIR(FunctionIR funcIR) or - TPrintableIRBlock(IRBlock block) or - TPrintableInstruction(Instruction instr) + TPrintableFunctionIR(FunctionIR funcIR) { + shouldPrintFunction(funcIR.getFunction()) + } or + TPrintableIRBlock(IRBlock block) { + shouldPrintFunction(block.getFunction()) + } or + TPrintableInstruction(Instruction instr) { + shouldPrintFunction(instr.getFunction()) + } /** * A node to be emitted in the IR graph. diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll index 478e92fac5c..8fb77621426 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll @@ -1,5 +1,40 @@ private import IR import cpp +import semmle.code.cpp.ir.IRConfiguration + +private newtype TPrintIRConfiguration = MkPrintIRConfiguration() + +/** + * The query can extend this class to control which functions are printed. + */ +class PrintIRConfiguration extends TPrintIRConfiguration { + string toString() { + result = "PrintIRConfiguration" + } + + /** + * Holds if the IR for `func` should be printed. By default, holds for all + * functions. + */ + predicate shouldPrintFunction(Function func) { + any() + } +} + +private predicate shouldPrintFunction(Function func) { + exists(PrintIRConfiguration config | + config.shouldPrintFunction(func) + ) +} + +/** + * Override of `IRConfiguration` to only create IR for the functions that are to be dumped. + */ +private class FilteredIRConfiguration extends IRConfiguration { + override predicate shouldCreateIRForFunction(Function func) { + shouldPrintFunction(func) + } +} private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | @@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) { } private newtype TPrintableIRNode = - TPrintableFunctionIR(FunctionIR funcIR) or - TPrintableIRBlock(IRBlock block) or - TPrintableInstruction(Instruction instr) + TPrintableFunctionIR(FunctionIR funcIR) { + shouldPrintFunction(funcIR.getFunction()) + } or + TPrintableIRBlock(IRBlock block) { + shouldPrintFunction(block.getFunction()) + } or + TPrintableInstruction(Instruction instr) { + shouldPrintFunction(instr.getFunction()) + } /** * A node to be emitted in the IR graph. From 220487bb32893807ca0fd46ad78df480883a8f2a Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Thu, 22 Nov 2018 08:21:49 +0100 Subject: [PATCH 76/94] C++: Deprecate queries using VCS.qll One query imported VCS.qll for no reason, so I removed the import instead of deprecating the query. --- cpp/ql/src/Metrics/History/HChurn.ql | 1 + cpp/ql/src/Metrics/History/HLinesAdded.ql | 1 + cpp/ql/src/Metrics/History/HLinesDeleted.ql | 1 + cpp/ql/src/Metrics/History/HNumberOfAuthors.ql | 1 + cpp/ql/src/Metrics/History/HNumberOfChanges.ql | 1 + cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql | 1 + cpp/ql/src/Metrics/History/HNumberOfReCommits.ql | 1 + cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql | 1 + cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql | 1 + cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql | 1 + cpp/ql/src/external/tests/DefectFilter.ql | 1 - cpp/ql/src/external/tests/DefectFromSVN.ql | 1 + cpp/ql/src/external/tests/MetricFromSVN.ql | 1 + cpp/ql/src/filters/RecentDefects.ql | 1 + cpp/ql/src/filters/RecentDefectsForMetric.ql | 1 + 15 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Metrics/History/HChurn.ql b/cpp/ql/src/Metrics/History/HChurn.ql index 40b4459caca..dc1f89b0e69 100644 --- a/cpp/ql/src/Metrics/History/HChurn.ql +++ b/cpp/ql/src/Metrics/History/HChurn.ql @@ -7,6 +7,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HLinesAdded.ql b/cpp/ql/src/Metrics/History/HLinesAdded.ql index 1a9fcc301e3..88d8565a4a3 100644 --- a/cpp/ql/src/Metrics/History/HLinesAdded.ql +++ b/cpp/ql/src/Metrics/History/HLinesAdded.ql @@ -7,6 +7,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HLinesDeleted.ql b/cpp/ql/src/Metrics/History/HLinesDeleted.ql index 72e54706056..b6851ce7e0e 100644 --- a/cpp/ql/src/Metrics/History/HLinesDeleted.ql +++ b/cpp/ql/src/Metrics/History/HLinesDeleted.ql @@ -7,6 +7,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql b/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql index 1da244ff31a..cce61f855f0 100644 --- a/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql +++ b/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql @@ -6,6 +6,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg min max + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HNumberOfChanges.ql b/cpp/ql/src/Metrics/History/HNumberOfChanges.ql index e3b2396662c..adb553c0d39 100644 --- a/cpp/ql/src/Metrics/History/HNumberOfChanges.ql +++ b/cpp/ql/src/Metrics/History/HNumberOfChanges.ql @@ -7,6 +7,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg min max sum + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql b/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql index 66dd1607163..e9547a58eab 100644 --- a/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql +++ b/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql @@ -7,6 +7,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg min max + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql b/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql index de958ad32b5..31edabbaad2 100644 --- a/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql +++ b/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql @@ -7,6 +7,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg min max + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql b/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql index c912897f404..5237b9e63aa 100644 --- a/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql +++ b/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql @@ -7,6 +7,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg min max + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql b/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql index 8009356cde9..ecf2ee48581 100644 --- a/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql +++ b/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql @@ -6,6 +6,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg min max sum + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql b/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql index 2ce984f40a1..e8f64e4f0a4 100644 --- a/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql +++ b/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql @@ -6,6 +6,7 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg min max sum + * @deprecated */ import cpp import external.VCS diff --git a/cpp/ql/src/external/tests/DefectFilter.ql b/cpp/ql/src/external/tests/DefectFilter.ql index 7c9459f64ce..de372930845 100644 --- a/cpp/ql/src/external/tests/DefectFilter.ql +++ b/cpp/ql/src/external/tests/DefectFilter.ql @@ -4,7 +4,6 @@ */ import cpp import external.DefectFilter -import external.VCS from DefectResult res where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200 diff --git a/cpp/ql/src/external/tests/DefectFromSVN.ql b/cpp/ql/src/external/tests/DefectFromSVN.ql index f58a6482ebc..863205834a2 100644 --- a/cpp/ql/src/external/tests/DefectFromSVN.ql +++ b/cpp/ql/src/external/tests/DefectFromSVN.ql @@ -3,6 +3,7 @@ * @description A test case for creating a defect from SVN data. * @kind problem * @problem.severity warning + * @deprecated */ import cpp diff --git a/cpp/ql/src/external/tests/MetricFromSVN.ql b/cpp/ql/src/external/tests/MetricFromSVN.ql index 32d27c7deaf..86d26323056 100644 --- a/cpp/ql/src/external/tests/MetricFromSVN.ql +++ b/cpp/ql/src/external/tests/MetricFromSVN.ql @@ -3,6 +3,7 @@ * @description Find number of commits for a file * @treemap.warnOn lowValues * @metricType file + * @deprecated */ import cpp diff --git a/cpp/ql/src/filters/RecentDefects.ql b/cpp/ql/src/filters/RecentDefects.ql index cf904d602ad..04c7afd0487 100644 --- a/cpp/ql/src/filters/RecentDefects.ql +++ b/cpp/ql/src/filters/RecentDefects.ql @@ -6,6 +6,7 @@ * before the date of the snapshot. * @kind problem * @id cpp/recent-defects-filter + * @deprecated */ import cpp import external.DefectFilter diff --git a/cpp/ql/src/filters/RecentDefectsForMetric.ql b/cpp/ql/src/filters/RecentDefectsForMetric.ql index 29515538388..00317d41750 100644 --- a/cpp/ql/src/filters/RecentDefectsForMetric.ql +++ b/cpp/ql/src/filters/RecentDefectsForMetric.ql @@ -6,6 +6,7 @@ * before the snapshot. * @kind treemap * @id cpp/recent-defects-for-metric-filter + * @deprecated */ import cpp import external.MetricFilter From a17debac3ee289c930a278e6ed53244faf796607 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Thu, 22 Nov 2018 10:48:18 +0100 Subject: [PATCH 77/94] C++: Placement-new tests for MemoryNeverFreed.ql --- .../MemoryFreed/MemoryNeverFreed.expected | 4 +++ .../query-tests/Critical/MemoryFreed/test.cpp | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected index 105bed90060..4b9ad79db52 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected @@ -8,3 +8,7 @@ | test.cpp:42:18:42:23 | call to malloc | This memory is never freed | | test.cpp:73:18:73:23 | call to malloc | This memory is never freed | | test.cpp:89:18:89:23 | call to malloc | This memory is never freed | +| test.cpp:150:3:150:21 | new | This memory is never freed | +| test.cpp:153:3:153:17 | new[] | This memory is never freed | +| test.cpp:156:3:156:26 | new | This memory is never freed | +| test.cpp:157:3:157:26 | new[] | This memory is never freed | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp index 7d05263eb4f..2d0899f2c11 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp @@ -130,3 +130,29 @@ int main() return 0; } + +// --- placement new --- + +namespace std { + typedef unsigned long size_t; + struct nothrow_t {}; + extern const nothrow_t nothrow; +} + +void* operator new (std::size_t size, void* ptr) noexcept; +void* operator new[](std::size_t size, void* ptr) noexcept; +void* operator new(std::size_t size, const std::nothrow_t&) noexcept; +void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; + +int overloadedNew() { + char buf[sizeof(int)]; + + new(&buf[0]) int(5); // GOOD [FALSE POSITIVE] + int five = *(int*)buf; + + new(buf) int[1]; // GOOD [FALSE POSITIVE] + *(int*)buf = 4; + + new(std::nothrow) int(3); // BAD + new(std::nothrow) int[2]; // BAD +} From 8cad0b6ef16c7945a5db109c359d36fc4a4ea89b Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Thu, 22 Nov 2018 10:25:41 +0000 Subject: [PATCH 78/94] Update qhelp for consistency --- .../GeneralStatistics.qhelp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp b/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp index a8230232c93..1bb15f10ed3 100644 --- a/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp +++ b/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp @@ -15,20 +15,9 @@ functions, and the total number of source code resp. comment lines.

depends on third-party libraries: low self-containedness means that many dependencies are to library classes (as opposed to source classes within the same application).

- -
-

The results of this query are purely informative and more useful for getting an overall impression of the application than for -identifying particular defects.

+identifying particular problems with the code.

+ - - - -
- - - - -
From 75873bb4a65560c8217d3151c10eb64b153dcc96 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Thu, 22 Nov 2018 11:31:19 +0100 Subject: [PATCH 79/94] C++: Detect non-allocating placement new This adds a `NewOrNewArrayExpr.getPlacementPointer` predicate and uses it in `Alloc.qll` to detect when a `new`-expression is not an allocation. User-defined replacements for `operator new` may not be allocations either, but the code continues to assume that they are. It's possible that we want to change this assumption in the future or leave it up to individual queries to decide on which side to err. It's hard to statically tell whether `operator new` has been overloaded in a particular file because it can be overloaded by a definition that is not in scope but is only linked together with that file. --- cpp/ql/src/semmle/code/cpp/commons/Alloc.qll | 4 +-- cpp/ql/src/semmle/code/cpp/exprs/Expr.qll | 16 +++++++++++ .../library-tests/allocators/allocators.cpp | 28 +++++++++++++++++++ .../allocators/allocators.expected | 4 +++ .../allocators/placement.expected | 2 ++ .../library-tests/allocators/placement.ql | 4 +++ .../MemoryFreed/MemoryNeverFreed.expected | 2 -- .../query-tests/Critical/MemoryFreed/test.cpp | 4 +-- 8 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 cpp/ql/test/library-tests/allocators/placement.expected create mode 100644 cpp/ql/test/library-tests/allocators/placement.ql diff --git a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll index e0a3f542731..0901f74ccd3 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll @@ -78,8 +78,8 @@ predicate isStdLibAllocationExpr(Expr e) */ predicate isAllocationExpr(Expr e) { allocationCall(e) - or e instanceof NewExpr - or e instanceof NewArrayExpr + or + e = any(NewOrNewArrayExpr new | not exists(new.getPlacementPointer())) } /** diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll index a453d817b00..3d3d3c5cd3f 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll @@ -664,6 +664,16 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr { * For `new int[5]` the result is `int[5]`. */ abstract Type getAllocatedType(); + + /** + * Gets the pointer `p` if this expression is of the form `new(p) T...`. + * Invocations of this form are non-allocating `new` expressions that may + * call the constructor of `T` but will not allocate memory. + */ + Expr getPlacementPointer() { + isStandardPlacementNewAllocator(this.getAllocator()) and + result = this.getAllocatorCall().getArgument(1) + } } /** @@ -961,3 +971,9 @@ private predicate convparents(Expr child, int idx, Element parent) { child = astChild.getFullyConverted() ) } + +private predicate isStandardPlacementNewAllocator(Function operatorNew) { + operatorNew.getName().matches("operator new%") and + operatorNew.getNumberOfParameters() = 2 and + operatorNew.getParameter(1).getType() instanceof VoidPointerType +} diff --git a/cpp/ql/test/library-tests/allocators/allocators.cpp b/cpp/ql/test/library-tests/allocators/allocators.cpp index 5f0a535e7f3..4b5775ab352 100644 --- a/cpp/ql/test/library-tests/allocators/allocators.cpp +++ b/cpp/ql/test/library-tests/allocators/allocators.cpp @@ -109,3 +109,31 @@ void TestFailedInit(int n) { new(1.0f) FailedInitOveraligned(); new(1.0f) FailedInitOveraligned[10]; } + +// --- non-allocating placement new --- + +namespace std { + typedef unsigned long size_t; + struct nothrow_t {}; + extern const nothrow_t nothrow; +} + +void* operator new (std::size_t size, void* ptr) noexcept; +void* operator new[](std::size_t size, void* ptr) noexcept; +void* operator new(std::size_t size, const std::nothrow_t&) noexcept; +void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; + +int overloadedNew() { + char buf[sizeof(int)]; + + new(&buf[0]) int(5); + int five = *(int*)buf; + + new(buf) int[1]; + *(int*)buf = 4; + + new(std::nothrow) int(3); // memory leak + new(std::nothrow) int[2]; // memory leak + + return five; +} diff --git a/cpp/ql/test/library-tests/allocators/allocators.expected b/cpp/ql/test/library-tests/allocators/allocators.expected index 586b82c8664..5802b13f4e9 100644 --- a/cpp/ql/test/library-tests/allocators/allocators.expected +++ b/cpp/ql/test/library-tests/allocators/allocators.expected @@ -8,6 +8,8 @@ newExprs | allocators.cpp:55:3:55:25 | new | Overaligned | operator new(size_t, align_val_t, float) -> void * | 256 | 128 | aligned | | allocators.cpp:107:3:107:18 | new | FailedInit | FailedInit::operator new(size_t) -> void * | 1 | 1 | | | allocators.cpp:109:3:109:35 | new | FailedInitOveraligned | FailedInitOveraligned::operator new(size_t, align_val_t, float) -> void * | 128 | 128 | aligned | +| allocators.cpp:129:3:129:21 | new | int | operator new(size_t, void *) -> void * | 4 | 4 | | +| allocators.cpp:135:3:135:26 | new | int | operator new(size_t, const nothrow_t &) -> void * | 4 | 4 | | newArrayExprs | allocators.cpp:68:3:68:12 | new[] | int | operator new[](unsigned long) -> void * | 4 | 4 | | | allocators.cpp:69:3:69:18 | new[] | int | operator new[](size_t, float) -> void * | 4 | 4 | | @@ -16,6 +18,8 @@ newArrayExprs | allocators.cpp:72:3:72:16 | new[] | String | operator new[](unsigned long) -> void * | 8 | 8 | | | allocators.cpp:108:3:108:19 | new[] | FailedInit | FailedInit::operator new[](size_t) -> void * | 1 | 1 | | | allocators.cpp:110:3:110:37 | new[] | FailedInitOveraligned | FailedInitOveraligned::operator new[](size_t, align_val_t, float) -> void * | 128 | 128 | aligned | +| allocators.cpp:132:3:132:17 | new[] | int | operator new[](size_t, void *) -> void * | 4 | 4 | | +| allocators.cpp:136:3:136:26 | new[] | int | operator new[](size_t, const nothrow_t &) -> void * | 4 | 4 | | newExprDeallocators | allocators.cpp:52:3:52:14 | new | String | operator delete(void *, unsigned long) -> void | 8 | 8 | sized | | allocators.cpp:53:3:53:27 | new | String | operator delete(void *, float) -> void | 8 | 8 | | diff --git a/cpp/ql/test/library-tests/allocators/placement.expected b/cpp/ql/test/library-tests/allocators/placement.expected new file mode 100644 index 00000000000..5755e349eb3 --- /dev/null +++ b/cpp/ql/test/library-tests/allocators/placement.expected @@ -0,0 +1,2 @@ +| allocators.cpp:129:3:129:21 | new | allocators.cpp:129:7:129:13 | & ... | +| allocators.cpp:132:3:132:17 | new[] | allocators.cpp:132:7:132:9 | buf | diff --git a/cpp/ql/test/library-tests/allocators/placement.ql b/cpp/ql/test/library-tests/allocators/placement.ql new file mode 100644 index 00000000000..a632c3c5afe --- /dev/null +++ b/cpp/ql/test/library-tests/allocators/placement.ql @@ -0,0 +1,4 @@ +import cpp + +from NewOrNewArrayExpr new +select new, new.getPlacementPointer() as placement diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected index 4b9ad79db52..900925d8927 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected @@ -8,7 +8,5 @@ | test.cpp:42:18:42:23 | call to malloc | This memory is never freed | | test.cpp:73:18:73:23 | call to malloc | This memory is never freed | | test.cpp:89:18:89:23 | call to malloc | This memory is never freed | -| test.cpp:150:3:150:21 | new | This memory is never freed | -| test.cpp:153:3:153:17 | new[] | This memory is never freed | | test.cpp:156:3:156:26 | new | This memory is never freed | | test.cpp:157:3:157:26 | new[] | This memory is never freed | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp index 2d0899f2c11..63636166fc8 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp @@ -147,10 +147,10 @@ void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; int overloadedNew() { char buf[sizeof(int)]; - new(&buf[0]) int(5); // GOOD [FALSE POSITIVE] + new(&buf[0]) int(5); // GOOD int five = *(int*)buf; - new(buf) int[1]; // GOOD [FALSE POSITIVE] + new(buf) int[1]; // GOOD *(int*)buf = 4; new(std::nothrow) int(3); // BAD From b780f828694f0836b898c0d6c1c8a21fa7072497 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Thu, 22 Nov 2018 13:38:43 +0100 Subject: [PATCH 80/94] JS: sharpen `js/clear-text-logging` (ODASA-7485) --- change-notes/1.19/analysis-javascript.md | 1 + .../security/dataflow/CleartextLogging.qll | 2 +- .../CWE-312/CleartextLogging.expected | 25 +++++++++++++------ .../query-tests/Security/CWE-312/passwords.js | 15 +++++++++++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index c52b5c82a70..7118faff58a 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -36,6 +36,7 @@ | **Query** | **Expected impact** | **Change** | |--------------------------------|----------------------------|----------------------------------------------| | Ambiguous HTML id attribute | Lower severity | The severity of this rule has been revised to "warning". | +| Clear-text logging of sensitive information | Fewer results | This rule now tracks flow more precisely. | | Client side cross-site scripting | More results | This rule now also flags HTML injection in the body of an email. | | Client-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. | | Conflicting HTML element attributes | Lower severity | The severity of this rule has been revised to "warning". | diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/CleartextLogging.qll b/javascript/ql/src/semmle/javascript/security/dataflow/CleartextLogging.qll index a0987cc21ef..7ab3b0689c2 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/CleartextLogging.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/CleartextLogging.qll @@ -52,7 +52,7 @@ module CleartextLogging { } override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { - any (TaintTracking::StringConcatenationTaintStep s).step(src, trg) + StringConcatenation::taintStep(src, trg) or exists (string name | name = "toString" or name = "valueOf" | src.(DataFlow::SourceNode).getAMethodCall(name) = trg diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index fb3e8e11bba..e562c22f904 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -22,10 +22,7 @@ nodes | passwords.js:28:16:28:17 | {} | | passwords.js:29:17:29:20 | obj3 | | passwords.js:30:14:30:21 | password | -| passwords.js:77:9:77:55 | temp | -| passwords.js:77:16:77:55 | { encry ... sword } | | passwords.js:77:37:77:53 | req.body.password | -| passwords.js:78:17:78:20 | temp | | passwords.js:78:17:78:38 | temp.en ... assword | | passwords.js:80:9:80:25 | secret | | passwords.js:80:18:80:25 | password | @@ -49,6 +46,13 @@ nodes | passwords.js:123:17:123:48 | name + ... lueOf() | | passwords.js:123:31:123:38 | password | | passwords.js:123:31:123:48 | password.valueOf() | +| passwords.js:127:9:132:5 | config | +| passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:130:12:130:19 | password | +| passwords.js:131:12:131:24 | getPassword() | +| passwords.js:135:17:135:22 | config | +| passwords.js:136:17:136:24 | config.x | +| passwords.js:137:17:137:24 | config.y | | passwords_in_browser1.js:2:13:2:20 | password | | passwords_in_browser2.js:2:13:2:20 | password | | passwords_in_server_1.js:6:13:6:20 | password | @@ -71,11 +75,7 @@ edges | passwords.js:28:9:28:17 | obj3 | passwords.js:29:17:29:20 | obj3 | | passwords.js:28:16:28:17 | {} | passwords.js:28:9:28:17 | obj3 | | passwords.js:30:14:30:21 | password | passwords.js:28:16:28:17 | {} | -| passwords.js:77:9:77:55 | temp | passwords.js:78:17:78:20 | temp | -| passwords.js:77:16:77:55 | { encry ... sword } | passwords.js:77:9:77:55 | temp | -| passwords.js:77:37:77:53 | req.body.password | passwords.js:77:16:77:55 | { encry ... sword } | | passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | -| passwords.js:78:17:78:20 | temp | passwords.js:78:17:78:38 | temp.en ... assword | | passwords.js:80:9:80:25 | secret | passwords.js:81:24:81:29 | secret | | passwords.js:80:18:80:25 | password | passwords.js:80:9:80:25 | secret | | passwords.js:81:24:81:29 | secret | passwords.js:81:17:81:31 | `pw: ${secret}` | @@ -89,6 +89,12 @@ edges | passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | | passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | | passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | +| passwords.js:127:9:132:5 | config | passwords.js:135:17:135:22 | config | +| passwords.js:127:18:132:5 | {\\n ... )\\n } | passwords.js:127:9:132:5 | config | +| passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | | passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:7:12:7:12 | x | | passwords_in_server_5.js:7:12:7:12 | x | passwords_in_server_5.js:8:17:8:17 | x | #select @@ -113,6 +119,11 @@ edges | passwords.js:119:21:119:46 | "Passwo ... assword | passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:119:39:119:46 | password | an access to password | | passwords.js:122:17:122:49 | name + ... tring() | passwords.js:122:31:122:38 | password | passwords.js:122:17:122:49 | name + ... tring() | Sensitive data returned by $@ is logged here. | passwords.js:122:31:122:38 | password | an access to password | | passwords.js:123:17:123:48 | name + ... lueOf() | passwords.js:123:31:123:38 | password | passwords.js:123:17:123:48 | name + ... lueOf() | Sensitive data returned by $@ is logged here. | passwords.js:123:31:123:38 | password | an access to password | +| passwords.js:135:17:135:22 | config | passwords.js:127:18:132:5 | {\\n ... )\\n } | passwords.js:135:17:135:22 | config | Sensitive data returned by $@ is logged here. | passwords.js:127:18:132:5 | {\\n ... )\\n } | an access to password | +| passwords.js:135:17:135:22 | config | passwords.js:130:12:130:19 | password | passwords.js:135:17:135:22 | config | Sensitive data returned by $@ is logged here. | passwords.js:130:12:130:19 | password | an access to password | +| passwords.js:135:17:135:22 | config | passwords.js:131:12:131:24 | getPassword() | passwords.js:135:17:135:22 | config | Sensitive data returned by $@ is logged here. | passwords.js:131:12:131:24 | getPassword() | a call to getPassword | +| passwords.js:136:17:136:24 | config.x | passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | Sensitive data returned by $@ is logged here. | passwords.js:130:12:130:19 | password | an access to password | +| passwords.js:137:17:137:24 | config.y | passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | Sensitive data returned by $@ is logged here. | passwords.js:131:12:131:24 | getPassword() | a call to getPassword | | passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_1.js:6:13:6:20 | password | an access to password | | passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_2.js:3:13:3:20 | password | an access to password | | passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_3.js:2:13:2:20 | password | an access to password | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js index 24be2573e60..d752ba7493f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js +++ b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js @@ -122,3 +122,18 @@ console.log(name + ", " + password.toString()); // NOT OK console.log(name + ", " + password.valueOf()); // NOT OK }); + +(function() { + var config = { + password: x, + hostname: "tarski", + x: password, + y: getPassword() + }; + var cfg = x? config: config; + console.log(config.hostname); // OK + console.log(config); // NOT OK + console.log(config.x); // NOT OK + console.log(config.y); // NOT OK + console.log(config[x]); // OK (probably) +}); From da26b4f856f2c15b08cc60043988461966b252e9 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Thu, 22 Nov 2018 13:52:33 +0100 Subject: [PATCH 81/94] C++: Accept test changes for IR This test was failing due to a semantic merge conflict between #509, which added `UninitializedInstruction`, and #517, which added new test code that would get `UninitializedInstruction`s in it after merging with #509. --- .../ir/ir/aliased_ssa_ir.expected | 23 ++++++++++--------- .../test/library-tests/ir/ir/raw_ir.expected | 23 ++++++++++--------- .../ir/ir/unaliased_ssa_ir.expected | 23 ++++++++++--------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected index 2c870437cf5..ab7f7ae43cb 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected @@ -4,17 +4,18 @@ bad_asts.cpp: # 14| v0_0(void) = EnterFunction : # 14| mu0_1(unknown) = UnmodeledDefinition : # 15| r0_2(glval) = VariableAddress[s] : -# 15| r0_3(glval) = FieldAddress[x] : r0_2 -# 15| r0_4(int) = Constant[0] : -# 15| mu0_5(int) = Store : r0_3, r0_4 -# 16| r0_6(glval) = VariableAddress[s] : -# 16| r0_7(glval) = FunctionAddress[MemberFunction] : -# 16| r0_8(int) = Constant[1] : -# 16| r0_9(int) = Call : r0_7, this:r0_6, r0_8 -# 17| v0_10(void) = NoOp : -# 14| v0_11(void) = ReturnVoid : -# 14| v0_12(void) = UnmodeledUse : mu* -# 14| v0_13(void) = ExitFunction : +# 15| mu0_3(S) = Uninitialized : r0_2 +# 15| r0_4(glval) = FieldAddress[x] : r0_2 +# 15| r0_5(int) = Constant[0] : +# 15| mu0_6(int) = Store : r0_4, r0_5 +# 16| r0_7(glval) = VariableAddress[s] : +# 16| r0_8(glval) = FunctionAddress[MemberFunction] : +# 16| r0_9(int) = Constant[1] : +# 16| r0_10(int) = Call : r0_8, this:r0_7, r0_9 +# 17| v0_11(void) = NoOp : +# 14| v0_12(void) = ReturnVoid : +# 14| v0_13(void) = UnmodeledUse : mu* +# 14| v0_14(void) = ExitFunction : # 22| Bad::Point::Point() -> void # 22| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index ec1b170e5ad..15f3f0867ac 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -4,17 +4,18 @@ bad_asts.cpp: # 14| v0_0(void) = EnterFunction : # 14| mu0_1(unknown) = UnmodeledDefinition : # 15| r0_2(glval) = VariableAddress[s] : -# 15| r0_3(glval) = FieldAddress[x] : r0_2 -# 15| r0_4(int) = Constant[0] : -# 15| mu0_5(int) = Store : r0_3, r0_4 -# 16| r0_6(glval) = VariableAddress[s] : -# 16| r0_7(glval) = FunctionAddress[MemberFunction] : -# 16| r0_8(int) = Constant[1] : -# 16| r0_9(int) = Call : r0_7, this:r0_6, r0_8 -# 17| v0_10(void) = NoOp : -# 14| v0_11(void) = ReturnVoid : -# 14| v0_12(void) = UnmodeledUse : mu* -# 14| v0_13(void) = ExitFunction : +# 15| mu0_3(S) = Uninitialized : r0_2 +# 15| r0_4(glval) = FieldAddress[x] : r0_2 +# 15| r0_5(int) = Constant[0] : +# 15| mu0_6(int) = Store : r0_4, r0_5 +# 16| r0_7(glval) = VariableAddress[s] : +# 16| r0_8(glval) = FunctionAddress[MemberFunction] : +# 16| r0_9(int) = Constant[1] : +# 16| r0_10(int) = Call : r0_8, this:r0_7, r0_9 +# 17| v0_11(void) = NoOp : +# 14| v0_12(void) = ReturnVoid : +# 14| v0_13(void) = UnmodeledUse : mu* +# 14| v0_14(void) = ExitFunction : # 22| Bad::Point::Point() -> void # 22| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected index 5ceea60d50d..8aa58507f26 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected @@ -4,17 +4,18 @@ bad_asts.cpp: # 14| v0_0(void) = EnterFunction : # 14| mu0_1(unknown) = UnmodeledDefinition : # 15| r0_2(glval) = VariableAddress[s] : -# 15| r0_3(glval) = FieldAddress[x] : r0_2 -# 15| r0_4(int) = Constant[0] : -# 15| mu0_5(int) = Store : r0_3, r0_4 -# 16| r0_6(glval) = VariableAddress[s] : -# 16| r0_7(glval) = FunctionAddress[MemberFunction] : -# 16| r0_8(int) = Constant[1] : -# 16| r0_9(int) = Call : r0_7, this:r0_6, r0_8 -# 17| v0_10(void) = NoOp : -# 14| v0_11(void) = ReturnVoid : -# 14| v0_12(void) = UnmodeledUse : mu* -# 14| v0_13(void) = ExitFunction : +# 15| mu0_3(S) = Uninitialized : r0_2 +# 15| r0_4(glval) = FieldAddress[x] : r0_2 +# 15| r0_5(int) = Constant[0] : +# 15| mu0_6(int) = Store : r0_4, r0_5 +# 16| r0_7(glval) = VariableAddress[s] : +# 16| r0_8(glval) = FunctionAddress[MemberFunction] : +# 16| r0_9(int) = Constant[1] : +# 16| r0_10(int) = Call : r0_8, this:r0_7, r0_9 +# 17| v0_11(void) = NoOp : +# 14| v0_12(void) = ReturnVoid : +# 14| v0_13(void) = UnmodeledUse : mu* +# 14| v0_14(void) = ExitFunction : # 22| Bad::Point::Point() -> void # 22| Block 0 From 01ba635e1de701d53efcaaa08f72fad1da549034 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 Nov 2018 19:02:27 +0000 Subject: [PATCH 82/94] CPP: Add some test cases involving dataflow. --- .../Critical/OverflowStatic/test.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp index 2311693e7a8..3b09e1ad824 100644 --- a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp +++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp @@ -25,3 +25,24 @@ void f1(void) memcpy(buffer2, buffer1, 3); // GOOD memcpy(buffer2, buffer1, 4); // BAD } + +void f2(char *src) +{ + char buffer[100]; + char *ptr; + int amount; + + amount = 100; + memcpy(buffer, src, amount); // GOOD + amount = amount + 1; + memcpy(buffer, src, amount); // BAD [NOT DETECTED] + amount = 101; + memcpy(buffer, src, amount); // BAD [NOT DETECTED] + + ptr = buffer; + memcpy(ptr, src, 101); // BAD [NOT DETECTED] + ptr = &(buffer[0]); + memcpy(ptr, src, 101); // BAD [NOT DETECTED] + ptr = &(buffer[1]); + memcpy(ptr, src, 100); // BAD [NOT DETECTED] +} From ea56a5d9cecf939a67ae2fe1d4a113b94e8e27ef Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 21 Nov 2018 18:30:24 +0000 Subject: [PATCH 83/94] CPP: Add local dataflow to (one bit of) OverflowStatic.ql. --- cpp/ql/src/Critical/OverflowStatic.ql | 23 +++++++++++++------ .../OverflowStatic/OverflowStatic.expected | 1 + .../Critical/OverflowStatic/test.cpp | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql index e8503d3a25d..3d13b656671 100644 --- a/cpp/ql/src/Critical/OverflowStatic.ql +++ b/cpp/ql/src/Critical/OverflowStatic.ql @@ -82,22 +82,31 @@ class CallWithBufferSize extends FunctionCall Expr buffer() { exists(int i | bufferAndSizeFunction(this.getTarget(), i, _) and - result = this.getArgument(i)) + result = this.getArgument(i) + ) } - Expr statedSize() { + Expr statedSizeExpr() { exists(int i | bufferAndSizeFunction(this.getTarget(), _, i) and - result = this.getArgument(i)) + result = this.getArgument(i) + ) + } + int statedSizeValue() { + exists(Expr statedSizeSrc | + DataFlow::localFlowStep*(DataFlow::exprNode(statedSizeSrc), DataFlow::exprNode(statedSizeExpr())) and + result = statedSizeSrc.getValue().toInt() + ) } } predicate wrongBufferSize(Expr error, string msg) { - exists(CallWithBufferSize call, int bufsize, Variable buf | + exists(CallWithBufferSize call, int bufsize, Variable buf, int statedSize | staticBuffer(call.buffer(), buf, bufsize) and - call.statedSize().getValue().toInt() > bufsize and - error = call.statedSize() and + statedSize = call.statedSizeValue() and + statedSize > bufsize and + error = call.statedSizeExpr() and msg = "Potential buffer-overflow: '" + buf.getName() + - "' has size " + bufsize.toString() + " not " + call.statedSize().getValue() + ".") + "' has size " + bufsize.toString() + " not " + statedSize + ".") } predicate outOfBounds(BufferAccess bufaccess, string msg) diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected b/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected index e5958e767e7..e6e2c51f7d9 100644 --- a/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected +++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected @@ -6,3 +6,4 @@ | test.cpp:20:3:20:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer2' has 3 elements. | | test.cpp:24:27:24:27 | 4 | Potential buffer-overflow: 'buffer1' has size 3 not 4. | | test.cpp:26:27:26:27 | 4 | Potential buffer-overflow: 'buffer2' has size 3 not 4. | +| test.cpp:40:22:40:27 | amount | Potential buffer-overflow: 'buffer' has size 100 not 101. | diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp index 3b09e1ad824..be9e14bd841 100644 --- a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp +++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp @@ -37,7 +37,7 @@ void f2(char *src) amount = amount + 1; memcpy(buffer, src, amount); // BAD [NOT DETECTED] amount = 101; - memcpy(buffer, src, amount); // BAD [NOT DETECTED] + memcpy(buffer, src, amount); // BAD ptr = buffer; memcpy(ptr, src, 101); // BAD [NOT DETECTED] From 16be502d6175c09a980aead7822c836ae0c1a521 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 22 Nov 2018 10:50:44 +0000 Subject: [PATCH 84/94] CPP: Add change note. --- change-notes/1.19/analysis-cpp.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index a5e8f612443..6d274150621 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -25,6 +25,7 @@ | Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. Also fixed an issue where false positives could occur if the destructor body was not in the snapshot. | | Missing return statement (`cpp/missing-return`) | Visible by default | The precision of this query has been increased from 'medium' to 'high', which makes it visible by default in LGTM. It was 'medium' in release 1.17 and 1.18 because it had false positives due to an extractor bug that was fixed in 1.18. | | Missing return statement | Fewer false positive results | The query is now produces correct results when a function returns a template-dependent type, or makes a non-returning call to another function. | +| Static array access may cause overflow | More correct results | Data flow to the size argument of a buffer operation is now checked in this query. | | Call to memory access function may overflow buffer | More correct results | Array indexing with a negative index is now detected by this query. | | Self comparison | Fewer false positive results | Code inside macro invocations is now excluded from the query. | | Suspicious call to memset | Fewer false positive results | Types involving decltype are now correctly compared. | From d57574e92c20272dee3a3563e11feb399fb0a6c7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 22 Nov 2018 14:40:06 +0000 Subject: [PATCH 85/94] CPP: localFlowStep* -> localFlow. --- cpp/ql/src/Critical/OverflowStatic.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql index 3d13b656671..aefbf585af7 100644 --- a/cpp/ql/src/Critical/OverflowStatic.ql +++ b/cpp/ql/src/Critical/OverflowStatic.ql @@ -93,7 +93,7 @@ class CallWithBufferSize extends FunctionCall } int statedSizeValue() { exists(Expr statedSizeSrc | - DataFlow::localFlowStep*(DataFlow::exprNode(statedSizeSrc), DataFlow::exprNode(statedSizeExpr())) and + DataFlow::localFlow(DataFlow::exprNode(statedSizeSrc), DataFlow::exprNode(statedSizeExpr())) and result = statedSizeSrc.getValue().toInt() ) } From cb609f4be0e672072b23ecb7c18bbcc54be688cc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 22 Nov 2018 14:41:57 +0000 Subject: [PATCH 86/94] CPP: Be conservative where there are multiple flow sources. --- cpp/ql/src/Critical/OverflowStatic.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql index aefbf585af7..386212cb676 100644 --- a/cpp/ql/src/Critical/OverflowStatic.ql +++ b/cpp/ql/src/Critical/OverflowStatic.ql @@ -102,7 +102,7 @@ class CallWithBufferSize extends FunctionCall predicate wrongBufferSize(Expr error, string msg) { exists(CallWithBufferSize call, int bufsize, Variable buf, int statedSize | staticBuffer(call.buffer(), buf, bufsize) and - statedSize = call.statedSizeValue() and + statedSize = min(call.statedSizeValue()) and statedSize > bufsize and error = call.statedSizeExpr() and msg = "Potential buffer-overflow: '" + buf.getName() + From b5008d86859ca02a0bf9a7f98f760bfdffdda687 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 22 Nov 2018 16:20:47 +0000 Subject: [PATCH 87/94] TS: only transfer offsets as part of the AST --- .../lib/typescript/src/ast_extractor.ts | 13 ++-- .../js/parser/TypeScriptASTConverter.java | 62 +++++++++++++------ 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/javascript/extractor/lib/typescript/src/ast_extractor.ts b/javascript/extractor/lib/typescript/src/ast_extractor.ts index e69714dd580..3264abcb368 100644 --- a/javascript/extractor/lib/typescript/src/ast_extractor.ts +++ b/javascript/extractor/lib/typescript/src/ast_extractor.ts @@ -9,6 +9,7 @@ export interface AugmentedSourceFile extends ts.SourceFile { parseDiagnostics?: any[]; $tokens?: Token[]; $symbol?: number; + $lineStarts?: ReadonlyArray; } export interface AugmentedNode extends ts.Node { @@ -21,9 +22,7 @@ export interface AugmentedNode extends ts.Node { $overloadIndex?: number; } -export interface AugmentedPos extends ts.LineAndCharacter { - $offset?: number; -} +export type AugmentedPos = number; export interface Token { kind: ts.SyntaxKind; @@ -66,8 +65,10 @@ function forEachNode(ast: ts.Node, callback: (node: ts.Node) => void) { } export function augmentAst(ast: AugmentedSourceFile, code: string, project: Project | null) { + ast.$lineStarts = ast.getLineStarts(); + /** - * Converts a numeric offset to a position object with line and column information. + * Converts a numeric offset to the value expected by the Java counterpart of the extractor. */ function augmentPos(pos: number, shouldSkipWhitespace?: boolean): AugmentedPos { // skip over leading spaces/comments @@ -75,9 +76,7 @@ export function augmentAst(ast: AugmentedSourceFile, code: string, project: Proj skipWhiteSpace.lastIndex = pos; pos += skipWhiteSpace.exec(code)[0].length; } - let posObject: AugmentedPos = ast.getLineAndCharacterOfPosition(pos); - posObject.$offset = pos; - return posObject; + return pos; } // Find the position of all tokens where the scanner requires parse-tree information. diff --git a/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java index 8cb4f2b2594..862dfd33663 100644 --- a/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java @@ -162,6 +162,7 @@ public class TypeScriptASTConverter { private final JsonObject syntaxKinds; private final Map nodeFlagMap = new LinkedHashMap<>(); private final Map syntaxKindMap = new LinkedHashMap<>(); + private int[] lineStarts; private int syntaxKindExtends; @@ -199,6 +200,8 @@ public class TypeScriptASTConverter { * into a parser {@link Result}. */ public Result convertAST(JsonObject ast, String source) { + this.lineStarts = toIntArray(ast.getAsJsonArray("$lineStarts")); + List errors = new ArrayList(); // process parse diagnostics (i.e., syntax errors) reported by the TypeScript compiler @@ -207,11 +210,8 @@ public class TypeScriptASTConverter { for (JsonElement elt : parseDiagnostics) { JsonObject parseDiagnostic = elt.getAsJsonObject(); String message = parseDiagnostic.get("messageText").getAsString(); - JsonObject pos = parseDiagnostic.get("$pos").getAsJsonObject(); - int line = pos.get("line").getAsInt() + 1; - int column = pos.get("character").getAsInt(); - int offset = pos.get("$offset").getAsInt(); - errors.add(new ParseError(message, line, column, offset)); + Position pos = getPosition(parseDiagnostic.get("$pos")); + errors.add(new ParseError(message, pos.getLine(), pos.getColumn(), pos.getOffset())); } return new Result(source, null, new ArrayList<>(), new ArrayList<>(), errors); } @@ -231,6 +231,36 @@ public class TypeScriptASTConverter { return new Result(source, converted, tokens, comments, errors); } + /** + * Converts a JSON array to an int array. + * The array is assumed to only contain integers. + */ + private static int[] toIntArray(JsonArray array) { + int[] result = new int[array.size()]; + for (int i = 0; i < array.size(); ++i) { + result[i] = array.get(i).getAsInt(); + } + return result; + } + + private int getLineFromPos(int pos) { + int low = 0, high = this.lineStarts.length - 1; + while (low < high) { + int mid = high - ((high - low) >> 1); // Get middle, rounding up. + int startOfLine = lineStarts[mid]; + if (startOfLine <= pos) { + low = mid; + } else { + high = mid - 1; + } + } + return low; + } + + private int getColumnFromLinePos(int line, int pos) { + return pos - lineStarts[line]; + } + /** * Extract tokens and comments from the given TypeScript AST. */ @@ -238,7 +268,7 @@ public class TypeScriptASTConverter { for (JsonElement elt : ast.get("$tokens").getAsJsonArray()) { JsonObject token = elt.getAsJsonObject(); String text = token.get("text").getAsString(); - Position start = getPosition(token.get("tokenPos").getAsJsonObject(), true); + Position start = getPosition(token.get("tokenPos")); Position end = advance(start, text); SourceLocation loc = new SourceLocation(text, start, end); String kind = getKind(token); @@ -886,7 +916,7 @@ public class TypeScriptASTConverter { } else { superInterfaces = convertSuperInterfaceClause(supers); } - afterHead = heritageClause.get("$end").getAsJsonObject().get("$offset").getAsInt(); + afterHead = heritageClause.get("$end").getAsInt(); } if (superInterfaces == null) { superInterfaces = new ArrayList<>(); @@ -2191,8 +2221,8 @@ public class TypeScriptASTConverter { * Get the source location of the given AST node. */ private SourceLocation getSourceLocation(JsonObject node) { - Position start = getPosition(node.get("$pos").getAsJsonObject(), true); - Position end = getPosition(node.get("$end").getAsJsonObject(), false); + Position start = getPosition(node.get("$pos")); + Position end = getPosition(node.get("$end")); int startOffset = start.getOffset(); int endOffset = end.getOffset(); if (startOffset > endOffset) @@ -2207,15 +2237,11 @@ public class TypeScriptASTConverter { * For start positions, we need to skip over whitespace, which is included in * the positions reported by the TypeScript compiler. */ - private Position getPosition(JsonObject pos, boolean isStart) { - int line = pos.get("line").getAsInt() + 1; - int column = pos.get("character").getAsInt(); - int offset = pos.get("$offset").getAsInt(); - if (isStart) { - while (offset < source.length() && Character.isWhitespace(source.charAt(offset))) - ++offset; - } - return new Position(line, column, offset); + private Position getPosition(JsonElement elm) { + int offset = elm.getAsInt(); + int line = getLineFromPos(offset); + int column = getColumnFromLinePos(line, offset); + return new Position(line + 1, column, offset); } private Iterable getModifiers(JsonObject node) { From 1b84fceb3c890cbd877179e9ed98923c9df144da Mon Sep 17 00:00:00 2001 From: yh-semmle Date: Thu, 22 Nov 2018 16:21:44 -0500 Subject: [PATCH 88/94] Java: deprecate queries that use `VCS.qll` --- java/ql/src/Metrics/History/HChurn.ql | 1 + java/ql/src/Metrics/History/HLinesAdded.ql | 1 + java/ql/src/Metrics/History/HLinesDeleted.ql | 1 + java/ql/src/Metrics/History/HNumberOfAuthors.ql | 1 + java/ql/src/Metrics/History/HNumberOfChanges.ql | 1 + java/ql/src/Metrics/History/HNumberOfRecentChanges.ql | 1 + java/ql/src/filters/RecentDefects.ql | 1 + java/ql/src/filters/RecentDefectsForMetric.ql | 1 + 8 files changed, 8 insertions(+) diff --git a/java/ql/src/Metrics/History/HChurn.ql b/java/ql/src/Metrics/History/HChurn.ql index 59cc7c8e634..dda841556f8 100644 --- a/java/ql/src/Metrics/History/HChurn.ql +++ b/java/ql/src/Metrics/History/HChurn.ql @@ -6,6 +6,7 @@ * @metricType file * @metricAggregate avg sum max * @id java/vcs/churn-per-file + * @deprecated */ import java diff --git a/java/ql/src/Metrics/History/HLinesAdded.ql b/java/ql/src/Metrics/History/HLinesAdded.ql index 4aa6adc74bd..e04fef82820 100644 --- a/java/ql/src/Metrics/History/HLinesAdded.ql +++ b/java/ql/src/Metrics/History/HLinesAdded.ql @@ -6,6 +6,7 @@ * @metricType file * @metricAggregate avg sum max * @id java/vcs/added-lines-per-file + * @deprecated */ import java diff --git a/java/ql/src/Metrics/History/HLinesDeleted.ql b/java/ql/src/Metrics/History/HLinesDeleted.ql index 4e476da307c..d0e923f9be7 100644 --- a/java/ql/src/Metrics/History/HLinesDeleted.ql +++ b/java/ql/src/Metrics/History/HLinesDeleted.ql @@ -6,6 +6,7 @@ * @metricType file * @metricAggregate avg sum max * @id java/vcs/deleted-lines-per-file + * @deprecated */ import java diff --git a/java/ql/src/Metrics/History/HNumberOfAuthors.ql b/java/ql/src/Metrics/History/HNumberOfAuthors.ql index fef9bc3cfdf..895eea57e8d 100644 --- a/java/ql/src/Metrics/History/HNumberOfAuthors.ql +++ b/java/ql/src/Metrics/History/HNumberOfAuthors.ql @@ -6,6 +6,7 @@ * @metricType file * @metricAggregate avg min max * @id java/vcs/authors-per-file + * @deprecated */ import java diff --git a/java/ql/src/Metrics/History/HNumberOfChanges.ql b/java/ql/src/Metrics/History/HNumberOfChanges.ql index 5209ebd7af7..c8f3a085b81 100644 --- a/java/ql/src/Metrics/History/HNumberOfChanges.ql +++ b/java/ql/src/Metrics/History/HNumberOfChanges.ql @@ -6,6 +6,7 @@ * @metricType file * @metricAggregate avg min max sum * @id java/vcs/commits-per-file + * @deprecated */ import java diff --git a/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql b/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql index e5006895faf..772470fe04c 100644 --- a/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql +++ b/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql @@ -6,6 +6,7 @@ * @metricType file * @metricAggregate avg min max sum * @id java/vcs/recent-commits-per-file + * @deprecated */ import java diff --git a/java/ql/src/filters/RecentDefects.ql b/java/ql/src/filters/RecentDefects.ql index 573ca6f5448..d52a79d0f0a 100644 --- a/java/ql/src/filters/RecentDefects.ql +++ b/java/ql/src/filters/RecentDefects.ql @@ -3,6 +3,7 @@ * @description Filter a defect query to only include results in files that have been changed recently, and modify the message. * @kind problem * @id java/recently-changed-file-filter + * @deprecated */ import java diff --git a/java/ql/src/filters/RecentDefectsForMetric.ql b/java/ql/src/filters/RecentDefectsForMetric.ql index 3587ea20d7b..8414508b1c0 100644 --- a/java/ql/src/filters/RecentDefectsForMetric.ql +++ b/java/ql/src/filters/RecentDefectsForMetric.ql @@ -3,6 +3,7 @@ * @description Filter a metric query to only include results in files that have been changed recently, and modify the message. * @kind treemap * @id java/recently-changed-file-metric-filter + * @deprecated */ import java From b95d7e53026233f6d40f0ca422d5dd7cf252800a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 19 Nov 2018 13:38:03 +0100 Subject: [PATCH 89/94] C#: Move autobuilder into separate folder --- csharp/{extractor => }/.gitignore | 0 .../CSharpExtractor.sln => CSharp.sln} | 22 +++++++++---------- .../Semmle.Autobuild.Tests/BuildScripts.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Semmle.Autobuild.Tests.csproj | 0 .../Semmle.Autobuild/AspBuildRule.cs | 0 .../Semmle.Autobuild/AutobuildOptions.cs | 0 .../Semmle.Autobuild/Autobuilder.cs | 0 .../Semmle.Autobuild/BuildActions.cs | 0 .../Semmle.Autobuild/BuildCommandAutoRule.cs | 0 .../Semmle.Autobuild/BuildCommandRule.cs | 0 .../Semmle.Autobuild/BuildScript.cs | 0 .../Semmle.Autobuild/BuildTools.cs | 0 .../Semmle.Autobuild/CommandBuilder.cs | 0 .../Semmle.Autobuild/DotNetRule.cs | 0 .../Semmle.Autobuild/Language.cs | 0 .../Semmle.Autobuild/MsBuildRule.cs | 0 .../Semmle.Autobuild/Program.cs | 0 .../Semmle.Autobuild/Project.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Semmle.Autobuild/Semmle.Autobuild.csproj | 4 ++-- .../Semmle.Autobuild/Solution.cs | 0 .../Semmle.Autobuild/StandaloneBuildRule.cs | 0 .../Semmle.Autobuild/XmlBuildRule.cs | 0 24 files changed, 13 insertions(+), 13 deletions(-) rename csharp/{extractor => }/.gitignore (100%) rename csharp/{extractor/CSharpExtractor.sln => CSharp.sln} (78%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild.Tests/BuildScripts.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild.Tests/Properties/AssemblyInfo.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild.Tests/Semmle.Autobuild.Tests.csproj (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/AspBuildRule.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/AutobuildOptions.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/Autobuilder.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/BuildActions.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/BuildCommandAutoRule.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/BuildCommandRule.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/BuildScript.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/BuildTools.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/CommandBuilder.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/DotNetRule.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/Language.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/MsBuildRule.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/Program.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/Project.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/Properties/AssemblyInfo.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/Semmle.Autobuild.csproj (77%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/Solution.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/StandaloneBuildRule.cs (100%) rename csharp/{extractor => autobuilder}/Semmle.Autobuild/XmlBuildRule.cs (100%) diff --git a/csharp/extractor/.gitignore b/csharp/.gitignore similarity index 100% rename from csharp/extractor/.gitignore rename to csharp/.gitignore diff --git a/csharp/extractor/CSharpExtractor.sln b/csharp/CSharp.sln similarity index 78% rename from csharp/extractor/CSharpExtractor.sln rename to csharp/CSharp.sln index 9f0d615ed38..78d853a5bbe 100644 --- a/csharp/extractor/CSharpExtractor.sln +++ b/csharp/CSharp.sln @@ -3,27 +3,27 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27130.2036 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Util", "Semmle.Util\Semmle.Util.csproj", "{CDD7AD69-0FD8-40F0-A9DA-F1077A2A85D6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Util", "extractor\Semmle.Util\Semmle.Util.csproj", "{CDD7AD69-0FD8-40F0-A9DA-F1077A2A85D6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction", "Semmle.Extraction\Semmle.Extraction.csproj", "{81EAAD75-4BE1-44E4-91DF-20778216DB64}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction", "extractor\Semmle.Extraction\Semmle.Extraction.csproj", "{81EAAD75-4BE1-44E4-91DF-20778216DB64}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp", "Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj", "{C4D62DA0-B64B-440B-86DC-AB52318CB8BF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp", "extractor\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj", "{C4D62DA0-B64B-440B-86DC-AB52318CB8BF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL", "Semmle.Extraction.CIL\Semmle.Extraction.CIL.csproj", "{399A1579-68F0-40F4-9A23-F241BA697F9C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL", "extractor\Semmle.Extraction.CIL\Semmle.Extraction.CIL.csproj", "{399A1579-68F0-40F4-9A23-F241BA697F9C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Autobuild", "Semmle.Autobuild\Semmle.Autobuild.csproj", "{5131EF00-0BA9-4436-A3B0-C5CDAB4B194C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Autobuild", "autobuilder\Semmle.Autobuild\Semmle.Autobuild.csproj", "{5131EF00-0BA9-4436-A3B0-C5CDAB4B194C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp.Standalone", "Semmle.Extraction.CSharp.Standalone\Semmle.Extraction.CSharp.Standalone.csproj", "{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp.Standalone", "extractor\Semmle.Extraction.CSharp.Standalone\Semmle.Extraction.CSharp.Standalone.csproj", "{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL.Driver", "Semmle.Extraction.CIL.Driver\Semmle.Extraction.CIL.Driver.csproj", "{EFA400B3-C1CE-446F-A4E2-8B44E61EF47C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL.Driver", "extractor\Semmle.Extraction.CIL.Driver\Semmle.Extraction.CIL.Driver.csproj", "{EFA400B3-C1CE-446F-A4E2-8B44E61EF47C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp.Driver", "Semmle.Extraction.CSharp.Driver\Semmle.Extraction.CSharp.Driver.csproj", "{C36453BF-0C82-448A-B15D-26947503A2D3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp.Driver", "extractor\Semmle.Extraction.CSharp.Driver\Semmle.Extraction.CSharp.Driver.csproj", "{C36453BF-0C82-448A-B15D-26947503A2D3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.Tests", "Semmle.Extraction.Tests\Semmle.Extraction.Tests.csproj", "{CD8D3F90-AD2E-4BB5-8E82-B94AA293864A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.Tests", "extractor\Semmle.Extraction.Tests\Semmle.Extraction.Tests.csproj", "{CD8D3F90-AD2E-4BB5-8E82-B94AA293864A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Util.Tests", "Semmle.Util.Tests\Semmle.Util.Tests.csproj", "{55A620F0-23F6-440D-A5BA-0567613B3C0F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Util.Tests", "extractor\Semmle.Util.Tests\Semmle.Util.Tests.csproj", "{55A620F0-23F6-440D-A5BA-0567613B3C0F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Autobuild.Tests", "Semmle.Autobuild.Tests\Semmle.Autobuild.Tests.csproj", "{CE267461-D762-4F53-A275-685A0A4EC48D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Autobuild.Tests", "autobuilder\Semmle.Autobuild.Tests\Semmle.Autobuild.Tests.csproj", "{CE267461-D762-4F53-A275-685A0A4EC48D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/csharp/extractor/Semmle.Autobuild.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild.Tests/BuildScripts.cs rename to csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs diff --git a/csharp/extractor/Semmle.Autobuild.Tests/Properties/AssemblyInfo.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/Properties/AssemblyInfo.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild.Tests/Properties/AssemblyInfo.cs rename to csharp/autobuilder/Semmle.Autobuild.Tests/Properties/AssemblyInfo.cs diff --git a/csharp/extractor/Semmle.Autobuild.Tests/Semmle.Autobuild.Tests.csproj b/csharp/autobuilder/Semmle.Autobuild.Tests/Semmle.Autobuild.Tests.csproj similarity index 100% rename from csharp/extractor/Semmle.Autobuild.Tests/Semmle.Autobuild.Tests.csproj rename to csharp/autobuilder/Semmle.Autobuild.Tests/Semmle.Autobuild.Tests.csproj diff --git a/csharp/extractor/Semmle.Autobuild/AspBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild/AspBuildRule.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/AspBuildRule.cs rename to csharp/autobuilder/Semmle.Autobuild/AspBuildRule.cs diff --git a/csharp/extractor/Semmle.Autobuild/AutobuildOptions.cs b/csharp/autobuilder/Semmle.Autobuild/AutobuildOptions.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/AutobuildOptions.cs rename to csharp/autobuilder/Semmle.Autobuild/AutobuildOptions.cs diff --git a/csharp/extractor/Semmle.Autobuild/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/Autobuilder.cs rename to csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs diff --git a/csharp/extractor/Semmle.Autobuild/BuildActions.cs b/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/BuildActions.cs rename to csharp/autobuilder/Semmle.Autobuild/BuildActions.cs diff --git a/csharp/extractor/Semmle.Autobuild/BuildCommandAutoRule.cs b/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/BuildCommandAutoRule.cs rename to csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs diff --git a/csharp/extractor/Semmle.Autobuild/BuildCommandRule.cs b/csharp/autobuilder/Semmle.Autobuild/BuildCommandRule.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/BuildCommandRule.cs rename to csharp/autobuilder/Semmle.Autobuild/BuildCommandRule.cs diff --git a/csharp/extractor/Semmle.Autobuild/BuildScript.cs b/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/BuildScript.cs rename to csharp/autobuilder/Semmle.Autobuild/BuildScript.cs diff --git a/csharp/extractor/Semmle.Autobuild/BuildTools.cs b/csharp/autobuilder/Semmle.Autobuild/BuildTools.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/BuildTools.cs rename to csharp/autobuilder/Semmle.Autobuild/BuildTools.cs diff --git a/csharp/extractor/Semmle.Autobuild/CommandBuilder.cs b/csharp/autobuilder/Semmle.Autobuild/CommandBuilder.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/CommandBuilder.cs rename to csharp/autobuilder/Semmle.Autobuild/CommandBuilder.cs diff --git a/csharp/extractor/Semmle.Autobuild/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/DotNetRule.cs rename to csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs diff --git a/csharp/extractor/Semmle.Autobuild/Language.cs b/csharp/autobuilder/Semmle.Autobuild/Language.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/Language.cs rename to csharp/autobuilder/Semmle.Autobuild/Language.cs diff --git a/csharp/extractor/Semmle.Autobuild/MsBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/MsBuildRule.cs rename to csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs diff --git a/csharp/extractor/Semmle.Autobuild/Program.cs b/csharp/autobuilder/Semmle.Autobuild/Program.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/Program.cs rename to csharp/autobuilder/Semmle.Autobuild/Program.cs diff --git a/csharp/extractor/Semmle.Autobuild/Project.cs b/csharp/autobuilder/Semmle.Autobuild/Project.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/Project.cs rename to csharp/autobuilder/Semmle.Autobuild/Project.cs diff --git a/csharp/extractor/Semmle.Autobuild/Properties/AssemblyInfo.cs b/csharp/autobuilder/Semmle.Autobuild/Properties/AssemblyInfo.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/Properties/AssemblyInfo.cs rename to csharp/autobuilder/Semmle.Autobuild/Properties/AssemblyInfo.cs diff --git a/csharp/extractor/Semmle.Autobuild/Semmle.Autobuild.csproj b/csharp/autobuilder/Semmle.Autobuild/Semmle.Autobuild.csproj similarity index 77% rename from csharp/extractor/Semmle.Autobuild/Semmle.Autobuild.csproj rename to csharp/autobuilder/Semmle.Autobuild/Semmle.Autobuild.csproj index 8a9d272169c..2d7eb6bfb6a 100644 --- a/csharp/extractor/Semmle.Autobuild/Semmle.Autobuild.csproj +++ b/csharp/autobuilder/Semmle.Autobuild/Semmle.Autobuild.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/csharp/extractor/Semmle.Autobuild/Solution.cs b/csharp/autobuilder/Semmle.Autobuild/Solution.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/Solution.cs rename to csharp/autobuilder/Semmle.Autobuild/Solution.cs diff --git a/csharp/extractor/Semmle.Autobuild/StandaloneBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild/StandaloneBuildRule.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/StandaloneBuildRule.cs rename to csharp/autobuilder/Semmle.Autobuild/StandaloneBuildRule.cs diff --git a/csharp/extractor/Semmle.Autobuild/XmlBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild/XmlBuildRule.cs similarity index 100% rename from csharp/extractor/Semmle.Autobuild/XmlBuildRule.cs rename to csharp/autobuilder/Semmle.Autobuild/XmlBuildRule.cs From 836daaf07b9d2205a792041d62c8c1b5f7428cd5 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Nov 2018 13:19:52 +0100 Subject: [PATCH 90/94] C#: Recognize `.proj` files in autobuilder When determining the target of `msbuild` or `dotnet build`, first look for `.proj` files, then `.sln` files, and finally `.csproj`/`.vcxproj` files. In all three cases, choose the project/solution file closest to the root. --- change-notes/1.19/analysis-csharp.md | 4 + .../Semmle.Autobuild.Tests/BuildScripts.cs | 277 +++++++++++++----- .../Semmle.Autobuild/Autobuilder.cs | 109 ++++--- .../Semmle.Autobuild/BuildActions.cs | 25 +- .../Semmle.Autobuild/BuildCommandAutoRule.cs | 7 +- .../Semmle.Autobuild/DotNetRule.cs | 35 +-- .../autobuilder/Semmle.Autobuild/Language.cs | 3 - .../Semmle.Autobuild/MsBuildRule.cs | 42 +-- .../autobuilder/Semmle.Autobuild/Project.cs | 65 ++-- .../Semmle.Autobuild/ProjectOrSolution.cs | 47 +++ .../autobuilder/Semmle.Autobuild/Solution.cs | 44 +-- 11 files changed, 447 insertions(+), 211 deletions(-) create mode 100644 csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs diff --git a/change-notes/1.19/analysis-csharp.md b/change-notes/1.19/analysis-csharp.md index f650fcc5813..d5ace2e7bff 100644 --- a/change-notes/1.19/analysis-csharp.md +++ b/change-notes/1.19/analysis-csharp.md @@ -29,3 +29,7 @@ * `getArgument()` on `AccessorCall` has been improved so it now takes tuple assignments into account. For example, the argument for the implicit `value` parameter in the setter of property `P` is `0` in `(P, x) = (0, 1)`. Additionally, the argument for the `value` parameter in compound assignments is now only the expanded value, for example, in `P += 7` the argument is `P + 7` and not `7`. * The predicate `isInArgument()` has been added to the `AssignableAccess` class. This holds for expressions that are passed as arguments using `in`. + +## Changes to the autobuilder + +* When determining the target of `msbuild` or `dotnet build`, first look for `.proj` files, then `.sln` files, and finally `.csproj`/`.vcxproj` files. In all three cases, choose the project/solution file closest to the root. diff --git a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs index 21235dd102b..b11f31be6f8 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System; using System.Linq; using Microsoft.Build.Construction; +using System.Xml; namespace Semmle.Extraction.Tests { @@ -129,12 +130,24 @@ namespace Semmle.Extraction.Tests string IBuildActions.PathCombine(params string[] parts) { - return string.Join('\\', parts); + return string.Join('\\', parts.Where(p => !string.IsNullOrWhiteSpace(p))); } + string IBuildActions.GetFullPath(string path) => path; + + string IBuildActions.GetDirectoryName(string path) => System.IO.Path.GetDirectoryName(path); + void IBuildActions.WriteAllText(string filename, string contents) { } + + public IDictionary LoadXml = new Dictionary(); + XmlDocument IBuildActions.LoadXml(string filename) + { + if (LoadXml.TryGetValue(filename, out var xml)) + return xml; + throw new ArgumentException("Missing LoadXml " + filename); + } } /// @@ -142,23 +155,21 @@ namespace Semmle.Extraction.Tests /// class TestSolution : ISolution { - public IEnumerable Projects => throw new NotImplementedException(); - public IEnumerable Configurations => throw new NotImplementedException(); public string DefaultConfigurationName => "Release"; public string DefaultPlatformName => "x86"; - public string Path { get; set; } - - public int ProjectCount => throw new NotImplementedException(); + public string FullPath { get; set; } public Version ToolsVersion => new Version("14.0"); + public IEnumerable IncludedProjects => throw new NotImplementedException(); + public TestSolution(string path) { - Path = path; + FullPath = path; } } @@ -318,11 +329,11 @@ namespace Semmle.Extraction.Tests } Autobuilder CreateAutoBuilder(string lgtmLanguage, bool isWindows, - string buildless=null, string solution=null, string buildCommand=null, string ignoreErrors=null, - string msBuildArguments=null, string msBuildPlatform=null, string msBuildConfiguration=null, string msBuildTarget=null, - string dotnetArguments=null, string dotnetVersion=null, string vsToolsVersion=null, - string nugetRestore=null, string allSolutions=null, - string cwd=@"C:\Project") + string buildless = null, string solution = null, string buildCommand = null, string ignoreErrors = null, + string msBuildArguments = null, string msBuildPlatform = null, string msBuildConfiguration = null, string msBuildTarget = null, + string dotnetArguments = null, string dotnetVersion = null, string vsToolsVersion = null, + string nugetRestore = null, string allSolutions = null, + string cwd = @"C:\Project") { Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa"; Actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java"; @@ -354,16 +365,26 @@ namespace Semmle.Extraction.Tests public void TestDefaultCSharpAutoBuilder() { Actions.RunProcess["cmd.exe /C dotnet --info"] = 0; - Actions.RunProcess["cmd.exe /C dotnet clean"] = 0; - Actions.RunProcess["cmd.exe /C dotnet restore"] = 0; - Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false"] = 0; + Actions.RunProcess["cmd.exe /C dotnet clean test.csproj"] = 0; + Actions.RunProcess["cmd.exe /C dotnet restore test.csproj"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0; Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\java\bin\java -jar C:\odasa\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; Actions.FileExists["csharp.log"] = true; + Actions.FileExists["test.csproj"] = true; Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; - Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\nbar.cs"; + Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\nbar.cs\ntest.csproj"; Actions.EnumerateDirectories[@"C:\Project"] = ""; + var xml = new XmlDocument(); + xml.LoadXml(@" + + Exe + netcoreapp2.1 + + +"); + Actions.LoadXml["test.csproj"] = xml; var autobuilder = CreateAutoBuilder("csharp", true); TestAutobuilderScript(autobuilder, 0, 6); @@ -373,16 +394,26 @@ namespace Semmle.Extraction.Tests public void TestLinuxCSharpAutoBuilder() { Actions.RunProcess["dotnet --info"] = 0; - Actions.RunProcess["dotnet clean"] = 0; - Actions.RunProcess["dotnet restore"] = 0; - Actions.RunProcess[@"C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false"] = 0; + Actions.RunProcess["dotnet clean test.csproj"] = 0; + Actions.RunProcess["dotnet restore test.csproj"] = 0; + Actions.RunProcess[@"C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0; Actions.RunProcess[@"C:\odasa\tools\java\bin\java -jar C:\odasa\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; Actions.FileExists["csharp.log"] = true; + Actions.FileExists["test.csproj"] = true; Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; - Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.cs"; + Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.cs\ntest.csproj"; Actions.EnumerateDirectories[@"C:\Project"] = ""; + var xml = new XmlDocument(); + xml.LoadXml(@" + + Exe + netcoreapp2.1 + + +"); + Actions.LoadXml["test.csproj"] = xml; var autobuilder = CreateAutoBuilder("csharp", false); TestAutobuilderScript(autobuilder, 0, 6); @@ -391,10 +422,6 @@ namespace Semmle.Extraction.Tests [Fact] public void TestLinuxCSharpAutoBuilderExtractorFailed() { - Actions.RunProcess["dotnet --info"] = 0; - Actions.RunProcess["dotnet clean"] = 0; - Actions.RunProcess["dotnet restore"] = 0; - Actions.RunProcess[@"C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false"] = 0; Actions.FileExists["csharp.log"] = false; Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; @@ -402,7 +429,7 @@ namespace Semmle.Extraction.Tests Actions.EnumerateDirectories[@"C:\Project"] = ""; var autobuilder = CreateAutoBuilder("csharp", false); - TestAutobuilderScript(autobuilder, 1, 4); + TestAutobuilderScript(autobuilder, 1, 0); } @@ -438,7 +465,7 @@ namespace Semmle.Extraction.Tests var autobuilder = CreateAutoBuilder("cpp", true); var solution = new TestSolution(@"C:\Project\test.sln"); - autobuilder.SolutionsToBuild.Add(solution); + autobuilder.ProjectsOrSolutionsToBuild.Add(solution); TestAutobuilderScript(autobuilder, 0, 2); } @@ -495,7 +522,7 @@ namespace Semmle.Extraction.Tests Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.sln"; Actions.EnumerateDirectories[@"C:\Project"] = ""; - var autobuilder = CreateAutoBuilder("csharp", false, buildless:"true"); + var autobuilder = CreateAutoBuilder("csharp", false, buildless: "true"); TestAutobuilderScript(autobuilder, 0, 3); } @@ -550,7 +577,7 @@ namespace Semmle.Extraction.Tests Assert.Equal(commandsRun, EndCallbackReturn.Count); var action = Actions.RunProcess.GetEnumerator(); - for(int cmd=0; cmd + + Exe + netcoreapp2.1 + - var autobuilder = CreateAutoBuilder("csharp", false, dotnetArguments:"--no-restore"); // nugetRestore=false does not work for now. +"); + Actions.LoadXml["test.csproj"] = xml; + + var autobuilder = CreateAutoBuilder("csharp", false, dotnetArguments: "--no-restore"); // nugetRestore=false does not work for now. TestAutobuilderScript(autobuilder, 0, 6); } @@ -818,19 +850,29 @@ namespace Semmle.Extraction.Tests Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0; Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project\.dotnet"] = 0; Actions.RunProcess[@"C:\Project\.dotnet\dotnet --info"] = 0; - Actions.RunProcess[@"C:\Project\.dotnet\dotnet clean"] = 0; - Actions.RunProcess[@"C:\Project\.dotnet\dotnet restore"] = 0; - Actions.RunProcess[@"C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false"] = 0; + Actions.RunProcess[@"C:\Project\.dotnet\dotnet clean test.csproj"] = 0; + Actions.RunProcess[@"C:\Project\.dotnet\dotnet restore test.csproj"] = 0; + Actions.RunProcess[@"C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0; Actions.RunProcess[@"C:\odasa\tools\java\bin\java -jar C:\odasa\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; Actions.FileExists["csharp.log"] = true; + Actions.FileExists["test.csproj"] = true; Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; Actions.GetEnvironmentVariable["PATH"] = "/bin:/usr/bin"; - Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.cs"; + Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.cs\ntest.csproj"; Actions.EnumerateDirectories[@"C:\Project"] = ""; + var xml = new XmlDocument(); + xml.LoadXml(@" + + Exe + netcoreapp2.1 + - var autobuilder = CreateAutoBuilder("csharp", false, dotnetVersion:"2.1.3"); +"); + Actions.LoadXml["test.csproj"] = xml; + + var autobuilder = CreateAutoBuilder("csharp", false, dotnetVersion: "2.1.3"); TestAutobuilderScript(autobuilder, 0, 10); } @@ -843,17 +885,27 @@ namespace Semmle.Extraction.Tests Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0; Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project\.dotnet"] = 0; Actions.RunProcess[@"C:\Project\.dotnet\dotnet --info"] = 0; - Actions.RunProcess[@"C:\Project\.dotnet\dotnet clean"] = 0; - Actions.RunProcess[@"C:\Project\.dotnet\dotnet restore"] = 0; - Actions.RunProcess[@"C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false"] = 0; + Actions.RunProcess[@"C:\Project\.dotnet\dotnet clean test.csproj"] = 0; + Actions.RunProcess[@"C:\Project\.dotnet\dotnet restore test.csproj"] = 0; + Actions.RunProcess[@"C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0; Actions.RunProcess[@"C:\odasa\tools\java\bin\java -jar C:\odasa\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; Actions.FileExists["csharp.log"] = true; + Actions.FileExists["test.csproj"] = true; Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; Actions.GetEnvironmentVariable["PATH"] = "/bin:/usr/bin"; - Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\nbar.cs"; + Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\nbar.cs\ntest.csproj"; Actions.EnumerateDirectories[@"C:\Project"] = ""; + var xml = new XmlDocument(); + xml.LoadXml(@" + + Exe + netcoreapp2.1 + + +"); + Actions.LoadXml["test.csproj"] = xml; var autobuilder = CreateAutoBuilder("csharp", false, dotnetVersion: "2.1.3"); TestAutobuilderScript(autobuilder, 0, 10); @@ -866,20 +918,109 @@ namespace Semmle.Extraction.Tests Actions.RunProcessOut["cmd.exe /C dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]"; Actions.RunProcess[@"cmd.exe /C powershell -NoProfile -ExecutionPolicy unrestricted -file C:\Project\install-dotnet.ps1 -Version 2.1.3 -InstallDir C:\Project\.dotnet"] = 0; Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0; - Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean"] = 0; - Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore"] = 0; - Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean test.csproj"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore test.csproj"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0; Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\java\bin\java -jar C:\odasa\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; Actions.FileExists["csharp.log"] = true; + Actions.FileExists["test.csproj"] = true; Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; Actions.GetEnvironmentVariable["PATH"] = "/bin:/usr/bin"; - Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.cs"; + Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.cs\ntest.csproj"; Actions.EnumerateDirectories[@"C:\Project"] = ""; + var xml = new XmlDocument(); + xml.LoadXml(@" + + Exe + netcoreapp2.1 + + +"); + Actions.LoadXml["test.csproj"] = xml; var autobuilder = CreateAutoBuilder("csharp", true, dotnetVersion: "2.1.3"); TestAutobuilderScript(autobuilder, 0, 8); } + + [Fact] + public void TestDirsProjWindows() + { + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore dirs.proj"] = 1; + Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\java\bin\java -jar C:\odasa\tools\extractor-asp.jar ."] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; + Actions.FileExists["csharp.log"] = true; + Actions.FileExists[@"a\test.csproj"] = true; + Actions.FileExists["dirs.proj"] = true; + Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false; + Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false; + Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"] = true; + Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"] = false; + Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = true; + + Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; + Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; + Actions.EnumerateFiles[@"C:\Project"] = "a\\test.cs\na\\test.csproj\ndirs.proj"; + Actions.EnumerateDirectories[@"C:\Project"] = ""; + + var csproj = new XmlDocument(); + csproj.LoadXml(@" + + + + + "); + Actions.LoadXml["a\\test.csproj"] = csproj; + + var dirsproj = new XmlDocument(); + dirsproj.LoadXml(@" + + + +"); + Actions.LoadXml["dirs.proj"] = dirsproj; + + var autobuilder = CreateAutoBuilder("csharp", true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows", msBuildPlatform: "x86", msBuildConfiguration: "Debug", + vsToolsVersion: "12", allSolutions: "true"); + TestAutobuilderScript(autobuilder, 0, 4); + } + + [Fact] + public void TestDirsProjLinux() + { + Actions.RunProcess[@"mono C:\odasa\tools\csharp\nuget\nuget.exe restore dirs.proj"] = 1; + Actions.RunProcess[@"C:\odasa\tools\odasa index --auto msbuild dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0; + Actions.RunProcess[@"C:\odasa\tools\java\bin\java -jar C:\odasa\tools\extractor-asp.jar ."] = 0; + Actions.RunProcess[@"C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; + Actions.FileExists["csharp.log"] = true; + Actions.FileExists["a/test.csproj"] = true; + Actions.FileExists["dirs.proj"] = true; + Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; + Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; + Actions.EnumerateFiles[@"C:\Project"] = "a/test.cs\na/test.csproj\ndirs.proj"; + Actions.EnumerateDirectories[@"C:\Project"] = ""; + + var csproj = new XmlDocument(); + csproj.LoadXml(@" + + + + + "); + Actions.LoadXml["a/test.csproj"] = csproj; + + var dirsproj = new XmlDocument(); + dirsproj.LoadXml(@" + + + +"); + Actions.LoadXml["dirs.proj"] = dirsproj; + + var autobuilder = CreateAutoBuilder("csharp", false); + TestAutobuilderScript(autobuilder, 0, 4); + } } } diff --git a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs index 3edcb802ffe..38e8dd11b7e 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs @@ -29,26 +29,32 @@ namespace Semmle.Autobuild public class Autobuilder { /// - /// Full file paths of files found in the project directory. + /// Full file paths of files found in the project directory, as well + /// their distance from the project root folder. The list is sorted + /// by distance in ascending order. /// - public IEnumerable Paths => pathsLazy.Value; - readonly Lazy> pathsLazy; + public IEnumerable<(string, int)> Paths => pathsLazy.Value; + readonly Lazy> pathsLazy; /// /// Gets a list of paths matching a set of extensions - /// (including the "."). + /// (including the "."), as well their distance from the project root folder. + /// The list is sorted by distance in ascending order. /// /// The extensions to find. /// The files matching the extension. - public IEnumerable GetExtensions(params string[] extensions) => - Paths.Where(p => extensions.Contains(Path.GetExtension(p))); + public IEnumerable<(string, int)> GetExtensions(params string[] extensions) => + Paths.Where(p => extensions.Contains(Path.GetExtension(p.Item1))); /// - /// Gets all paths matching a particular filename. + /// Gets all paths matching a particular filename, as well + /// their distance from the project root folder. The list is sorted + /// by distance in ascending order. /// /// The filename to find. /// Possibly empty sequence of paths with the given filename. - public IEnumerable GetFilename(string name) => Paths.Where(p => Path.GetFileName(p) == name); + public IEnumerable<(string, int)> GetFilename(string name) => + Paths.Where(p => Path.GetFileName(p.Item1) == name); /// /// Holds if a given path, relative to the root of the source directory @@ -59,30 +65,30 @@ namespace Semmle.Autobuild public bool HasRelativePath(string path) => HasPath(Actions.PathCombine(RootDirectory, path)); /// - /// List of solution files to build. + /// List of project/solution files to build. /// - public IList SolutionsToBuild => solutionsToBuildLazy.Value; - readonly Lazy> solutionsToBuildLazy; + public IList ProjectsOrSolutionsToBuild => projectsOrSolutionsToBuildLazy.Value; + readonly Lazy> projectsOrSolutionsToBuildLazy; /// /// Holds if a given path was found. /// /// The path of the file. /// True iff the path was found. - public bool HasPath(string path) => Paths.Any(p => path == p); + public bool HasPath(string path) => Paths.Any(p => path == p.Item1); - void FindFiles(string dir, int depth, IList results) + void FindFiles(string dir, int depth, int maxDepth, IList<(string, int)> results) { foreach (var f in Actions.EnumerateFiles(dir)) { - results.Add(f); + results.Add((f, depth)); } - if (depth > 1) + if (depth < maxDepth) { foreach (var d in Actions.EnumerateDirectories(dir)) { - FindFiles(d, depth - 1, results); + FindFiles(d, depth + 1, maxDepth, results); } } } @@ -113,46 +119,75 @@ namespace Semmle.Autobuild Actions = actions; Options = options; - pathsLazy = new Lazy>(() => + pathsLazy = new Lazy>(() => { - var files = new List(); - FindFiles(options.RootDirectory, options.SearchDepth, files); - return files. - OrderBy(s => s.Count(c => c == Path.DirectorySeparatorChar)). - ThenBy(s => Path.GetFileName(s).Length). - ToArray(); + var files = new List<(string, int)>(); + FindFiles(options.RootDirectory, 0, options.SearchDepth, files); + return files.OrderBy(f => f.Item2).ToArray(); }); - solutionsToBuildLazy = new Lazy>(() => + projectsOrSolutionsToBuildLazy = new Lazy>(() => { if (options.Solution.Any()) { - var ret = new List(); + var ret = new List(); foreach (var solution in options.Solution) { if (actions.FileExists(solution)) ret.Add(new Solution(this, solution)); else - Log(Severity.Error, "The specified solution file {0} was not found", solution); + Log(Severity.Error, $"The specified solution file {solution} was not found"); } return ret; } - var solutions = GetExtensions(".sln"). - Select(s => new Solution(this, s)). - Where(s => s.ProjectCount > 0). - OrderByDescending(s => s.ProjectCount). - ThenBy(s => s.Path.Length). + bool FindFiles(string extension, Func create, out IEnumerable files) + { + var allFiles = GetExtensions(extension). + Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)). + Where(p => p.ProjectOrSolution.HasLanguage(this.Options.Language)). ToArray(); - foreach (var sln in solutions) - { - Log(Severity.Info, $"Found {sln.Path} with {sln.ProjectCount} {this.Options.Language} projects, version {sln.ToolsVersion}, config {string.Join(" ", sln.Configurations.Select(c => c.FullName))}"); + if (allFiles.Length == 0) + { + files = null; + return false; + } + + if (options.AllSolutions) + { + files = allFiles.Select(p => p.ProjectOrSolution); + return true; + } + + var firstIsClosest = allFiles.Length > 1 && allFiles[0].DistanceFromRoot < allFiles[1].DistanceFromRoot; + if (allFiles.Length == 1 || firstIsClosest) + { + files = allFiles.Select(p => p.ProjectOrSolution).Take(1); + return true; + } + + var candidates = allFiles. + Where(f => f.DistanceFromRoot == allFiles[0].DistanceFromRoot). + Select(f => f.ProjectOrSolution); + Log(Severity.Info, $"Found multiple '{extension}' files, giving up: {string.Join(", ", candidates)}."); + files = new IProjectOrSolution[0]; + return true; } - return new List(options.AllSolutions ? - solutions : - solutions.Take(1)); + // First look for `.proj` files + if (FindFiles(".proj", f => new Project(this, f), out var ret1)) + return ret1.ToList(); + + // Then look for `.sln` files + if (FindFiles(".sln", f => new Solution(this, f), out var ret2)) + return ret2.ToList(); + + // Finally look for language specific project files, e.g. `.csproj` files + if (FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f), out var ret3)) + return ret3.ToList(); + + return new List(); }); SemmleDist = Actions.GetEnvironmentVariable("SEMMLE_DIST"); diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs b/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs index 906d6701c1a..d0acedbcabd 100644 --- a/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs +++ b/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Xml; namespace Semmle.Autobuild { @@ -96,12 +97,27 @@ namespace Semmle.Autobuild /// The combined path. string PathCombine(params string[] parts); + /// + /// Gets the full path for , Path.GetFullPath(). + /// + string GetFullPath(string path); + + /// + /// Gets the directory of , Path.GetDirectoryName(). + /// + string GetDirectoryName(string path); + /// /// Writes contents to file, File.WriteAllText(). /// /// The filename. /// The text. void WriteAllText(string filename, string contents); + + /// + /// Loads the XML document from . + /// + XmlDocument LoadXml(string filename); } /// @@ -167,10 +183,17 @@ namespace Semmle.Autobuild void IBuildActions.WriteAllText(string filename, string contents) => File.WriteAllText(filename, contents); - private SystemBuildActions() + XmlDocument IBuildActions.LoadXml(string filename) { + var ret = new XmlDocument(); + ret.Load(filename); + return ret; } + string IBuildActions.GetFullPath(string path) => Path.GetFullPath(path); + + string IBuildActions.GetDirectoryName(string path) => Path.GetDirectoryName(path); + public static readonly IBuildActions Instance = new SystemBuildActions(); } } diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs b/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs index 627651eaefe..151fdd70327 100644 --- a/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using Semmle.Util; using Semmle.Util.Logging; namespace Semmle.Autobuild @@ -32,7 +31,7 @@ namespace Semmle.Autobuild var extensions = builder.Actions.IsWindows() ? winExtensions : linuxExtensions; var scripts = buildScripts.SelectMany(s => extensions.Select(e => s + e)); - var scriptPath = builder.Paths.Where(p => scripts.Any(p.ToLower().EndsWith)).OrderBy(p => p.Length).FirstOrDefault(); + var scriptPath = builder.Paths.Where(p => scripts.Any(p.Item1.ToLower().EndsWith)).OrderBy(p => p.Item2).Select(p => p.Item1).FirstOrDefault(); if (scriptPath == null) return BuildScript.Failure; @@ -41,12 +40,12 @@ namespace Semmle.Autobuild chmod.RunCommand("/bin/chmod", $"u+x {scriptPath}"); var chmodScript = builder.Actions.IsWindows() ? BuildScript.Success : BuildScript.Try(chmod.Script); - var path = Path.GetDirectoryName(scriptPath); + var dir = builder.Actions.GetDirectoryName(scriptPath); // A specific .NET Core version may be required return chmodScript & DotNetRule.WithDotNet(builder, dotNet => { - var command = new CommandBuilder(builder.Actions, path, dotNet?.Environment); + var command = new CommandBuilder(builder.Actions, dir, dotNet?.Environment); // A specific Visual Studio version may be required var vsTools = MsBuildRule.GetVcVarsBatFile(builder); diff --git a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs index a862a4f1a1b..c9622d2cf26 100644 --- a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs @@ -4,6 +4,7 @@ using System.Linq; using Newtonsoft.Json.Linq; using System.Collections.Generic; using System.IO; +using Semmle.Util; namespace Semmle.Autobuild { @@ -15,46 +16,36 @@ namespace Semmle.Autobuild { public BuildScript Analyse(Autobuilder builder) { - builder.Log(Severity.Info, "Attempting to build using .NET Core"); + if (!builder.ProjectsOrSolutionsToBuild.Any()) + return BuildScript.Failure; - var projects = builder.SolutionsToBuild.Any() - ? builder.SolutionsToBuild.SelectMany(s => s.Projects).ToArray() - : builder.GetExtensions(Language.CSharp.ProjectExtension).Select(p => new Project(builder, p)).ToArray(); - - var notDotNetProject = projects.FirstOrDefault(p => !p.DotNetProject); + var notDotNetProject = builder.ProjectsOrSolutionsToBuild. + SelectMany(p => Enumerators.Singleton(p).Concat(p.IncludedProjects)). + OfType(). + FirstOrDefault(p => !p.DotNetProject); if (notDotNetProject != null) { builder.Log(Severity.Info, "Not using .NET Core because of incompatible project {0}", notDotNetProject); return BuildScript.Failure; } - if (!builder.SolutionsToBuild.Any()) - // Attempt dotnet build in root folder - return WithDotNet(builder, dotNet => - { - var info = GetInfoCommand(builder.Actions, dotNet); - var clean = GetCleanCommand(builder.Actions, dotNet).Script; - var restore = GetRestoreCommand(builder.Actions, dotNet).Script; - var build = GetBuildCommand(builder, dotNet).Script; - return info & clean & BuildScript.Try(restore) & build; - }); + builder.Log(Severity.Info, "Attempting to build using .NET Core"); - // Attempt dotnet build on each solution return WithDotNet(builder, dotNet => { var ret = GetInfoCommand(builder.Actions, dotNet); - foreach (var solution in builder.SolutionsToBuild) + foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild) { var cleanCommand = GetCleanCommand(builder.Actions, dotNet); - cleanCommand.QuoteArgument(solution.Path); + cleanCommand.QuoteArgument(projectOrSolution.FullPath); var clean = cleanCommand.Script; var restoreCommand = GetRestoreCommand(builder.Actions, dotNet); - restoreCommand.QuoteArgument(solution.Path); + restoreCommand.QuoteArgument(projectOrSolution.FullPath); var restore = restoreCommand.Script; var buildCommand = GetBuildCommand(builder, dotNet); - buildCommand.QuoteArgument(solution.Path); + buildCommand.QuoteArgument(projectOrSolution.FullPath); var build = buildCommand.Script; ret &= clean & BuildScript.Try(restore) & build; @@ -110,7 +101,7 @@ namespace Semmle.Autobuild // See https://docs.microsoft.com/en-us/dotnet/core/tools/global-json var installScript = BuildScript.Success; var validGlobalJson = false; - foreach (var path in builder.Paths.Where(p => p.EndsWith("global.json", StringComparison.Ordinal))) + foreach (var path in builder.Paths.Select(p => p.Item1).Where(p => p.EndsWith("global.json", StringComparison.Ordinal))) { string version; try diff --git a/csharp/autobuilder/Semmle.Autobuild/Language.cs b/csharp/autobuilder/Semmle.Autobuild/Language.cs index 6f8d73b2a47..5049506be57 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Language.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Language.cs @@ -8,9 +8,6 @@ public bool ProjectFileHasThisLanguage(string path) => System.IO.Path.GetExtension(path) == ProjectExtension; - public static bool IsProjectFileForAnySupportedLanguage(string path) => - Cpp.ProjectFileHasThisLanguage(path) || CSharp.ProjectFileHasThisLanguage(path); - public readonly string ProjectExtension; private Language(string extension) diff --git a/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs index cb7eae2c23b..141504075cf 100644 --- a/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs @@ -16,19 +16,19 @@ namespace Semmle.Autobuild public BuildScript Analyse(Autobuilder builder) { - builder.Log(Severity.Info, "Attempting to build using MSBuild"); - - if (!builder.SolutionsToBuild.Any()) - { - builder.Log(Severity.Info, "Could not find a suitable solution file to build"); + if (!builder.ProjectsOrSolutionsToBuild.Any()) return BuildScript.Failure; - } + + builder.Log(Severity.Info, "Attempting to build using MSBuild"); var vsTools = GetVcVarsBatFile(builder); - if (vsTools == null && builder.SolutionsToBuild.Any()) + if (vsTools == null && builder.ProjectsOrSolutionsToBuild.Any()) { - vsTools = BuildTools.FindCompatibleVcVars(builder.Actions, builder.SolutionsToBuild.First()); + var firstSolution = builder.ProjectsOrSolutionsToBuild.OfType().FirstOrDefault(); + vsTools = firstSolution != null + ? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution) + : BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault(); } if (vsTools == null && builder.Actions.IsWindows()) @@ -40,36 +40,42 @@ namespace Semmle.Autobuild var ret = BuildScript.Success; - foreach (var solution in builder.SolutionsToBuild) + foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild) { if (builder.Options.NugetRestore) { var nugetCommand = new CommandBuilder(builder.Actions). RunCommand(nuget). Argument("restore"). - QuoteArgument(solution.Path); + QuoteArgument(projectOrSolution.FullPath); ret &= BuildScript.Try(nugetCommand.Script); } var command = new CommandBuilder(builder.Actions); if (vsTools != null) - { command.CallBatFile(vsTools.Path); - } command.IndexCommand(builder.Odasa, MsBuild); - command.QuoteArgument(solution.Path); + command.QuoteArgument(projectOrSolution.FullPath); command.Argument("/p:UseSharedCompilation=false"); - string target = builder.Options.MsBuildTarget != null ? builder.Options.MsBuildTarget : "rebuild"; - string platform = builder.Options.MsBuildPlatform != null ? builder.Options.MsBuildPlatform : solution.DefaultPlatformName; - string configuration = builder.Options.MsBuildConfiguration != null ? builder.Options.MsBuildConfiguration : solution.DefaultConfigurationName; + string target = builder.Options.MsBuildTarget != null + ? builder.Options.MsBuildTarget + : "rebuild"; + string platform = builder.Options.MsBuildPlatform != null + ? builder.Options.MsBuildPlatform + : projectOrSolution is ISolution s1 ? s1.DefaultPlatformName : null; + string configuration = builder.Options.MsBuildConfiguration != null + ? builder.Options.MsBuildConfiguration + : projectOrSolution is ISolution s2 ? s2.DefaultConfigurationName : null; command.Argument("/t:" + target); - command.Argument(string.Format("/p:Platform=\"{0}\"", platform)); - command.Argument(string.Format("/p:Configuration=\"{0}\"", configuration)); + if (platform != null) + command.Argument(string.Format("/p:Platform=\"{0}\"", platform)); + if (configuration != null) + command.Argument(string.Format("/p:Configuration=\"{0}\"", configuration)); command.Argument("/p:MvcBuildViews=true"); command.Argument(builder.Options.MsBuildArguments); diff --git a/csharp/autobuilder/Semmle.Autobuild/Project.cs b/csharp/autobuilder/Semmle.Autobuild/Project.cs index e0a1ee8386d..9e9abeff82c 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Project.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Project.cs @@ -1,16 +1,18 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Xml; using Semmle.Util.Logging; namespace Semmle.Autobuild { /// - /// Representation of a .csproj (C#) or .vcxproj (C++) file. + /// Representation of a .proj file, a .csproj file (C#), or a .vcxproj file (C++). /// C# project files come in 2 flavours, .Net core and msbuild, but they /// have the same file extension. /// - public class Project + public class Project : ProjectOrSolution { /// /// Holds if this project is for .Net core. @@ -21,18 +23,28 @@ namespace Semmle.Autobuild public Version ToolsVersion { get; private set; } - readonly string filename; + readonly List includedProjects = new List(); + public override IEnumerable IncludedProjects => + includedProjects.Concat(includedProjects.SelectMany(s => s.IncludedProjects)); - public Project(Autobuilder builder, string filename) + public Project(Autobuilder builder, string path) : base(builder, path) { - this.filename = filename; ToolsVersion = new Version(); - if (!File.Exists(filename)) + if (!builder.Actions.FileExists(FullPath)) return; - var projFile = new XmlDocument(); - projFile.Load(filename); + XmlDocument projFile; + try + { + projFile = builder.Actions.LoadXml(FullPath); + } + catch (XmlException) + { + builder.Log(Severity.Info, $"Skipping project file {path} as it is not a valid XML document."); + return; + } + var root = projFile.DocumentElement; if (root.Name == "Project") @@ -40,30 +52,35 @@ namespace Semmle.Autobuild if (root.HasAttribute("Sdk")) { DotNetProject = true; + return; } - else + + var toolsVersion = root.GetAttribute("ToolsVersion"); + if (!string.IsNullOrEmpty(toolsVersion)) { - var toolsVersion = root.GetAttribute("ToolsVersion"); - if (string.IsNullOrEmpty(toolsVersion)) + try { - builder.Log(Severity.Warning, "Project {0} is missing a tools version", filename); + ToolsVersion = new Version(toolsVersion); + ValidToolsVersion = true; } - else + catch // Generic catch clause - Version constructor throws about 5 different exceptions. { - try - { - ToolsVersion = new Version(toolsVersion); - ValidToolsVersion = true; - } - catch // Generic catch clause - Version constructor throws about 5 different exceptions. - { - builder.Log(Severity.Warning, "Project {0} has invalid tools version {1}", filename, toolsVersion); - } + builder.Log(Severity.Warning, "Project {0} has invalid tools version {1}", path, toolsVersion); } } + + // The documentation on `.proj` files is very limited, but it appears that both + // `` and `` is valid + var mgr = new XmlNamespaceManager(projFile.NameTable); + mgr.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); + var projectFileIncludes = root.SelectNodes("//msbuild:Project/msbuild:ItemGroup/msbuild:ProjectFile/@Include", mgr).OfType(); + var projectFilesIncludes = root.SelectNodes("//msbuild:Project/msbuild:ItemGroup/msbuild:ProjectFiles/@Include", mgr).OfType(); + foreach (var include in projectFileIncludes.Concat(projectFilesIncludes)) + { + var includePath = builder.Actions.IsWindows() ? include.Value : include.Value.Replace("\\", "/"); + includedProjects.Add(new Project(builder, builder.Actions.PathCombine(builder.Actions.GetDirectoryName(this.FullPath), includePath))); + } } } - - public override string ToString() => filename; } } diff --git a/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs b/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs new file mode 100644 index 00000000000..4c0cbe08b0b --- /dev/null +++ b/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Semmle.Autobuild +{ + /// + /// A file that can be the target in an invocation of `msbuild` or `dotnet build`. + /// Either a solution file or a project file (`.proj`, `.csproj`, or `.vcxproj`). + /// + public interface IProjectOrSolution + { + /// + /// Gets the full path of this file. + /// + string FullPath { get; } + + /// + /// Gets a list of other projects included by this file. + /// + IEnumerable IncludedProjects { get; } + } + + public abstract class ProjectOrSolution : IProjectOrSolution + { + public string FullPath { get; private set; } + + protected ProjectOrSolution(Autobuilder builder, string path) + { + FullPath = builder.Actions.GetFullPath(path); + } + + public abstract IEnumerable IncludedProjects { get; } + + public override string ToString() => FullPath; + } + + public static class IProjectOrSolutionExtensions + { + /// + /// Holds if this file includes a project with code from language . + /// + public static bool HasLanguage(this IProjectOrSolution p, Language l) => + l.ProjectFileHasThisLanguage(p.FullPath) || + p.IncludedProjects.Any(p0 => l.ProjectFileHasThisLanguage(p0.FullPath)); + } +} diff --git a/csharp/autobuilder/Semmle.Autobuild/Solution.cs b/csharp/autobuilder/Semmle.Autobuild/Solution.cs index 66bbff777ac..312e7deeb54 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Solution.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Solution.cs @@ -10,15 +10,8 @@ namespace Semmle.Autobuild /// /// A solution file, extension .sln. /// - public interface ISolution + public interface ISolution : IProjectOrSolution { - /// - /// List of C# or C++ projects contained in the solution. - /// (There could be other project types as well - these are ignored.) - /// - - IEnumerable Projects { get; } - /// /// Solution configurations. /// @@ -34,16 +27,6 @@ namespace Semmle.Autobuild /// string DefaultPlatformName { get; } - /// - /// The path of the solution file. - /// - string Path { get; } - - /// - /// The number of C# or C++ projects. - /// - int ProjectCount { get; } - /// /// Gets the "best" tools version for this solution. /// If there are several versions, because the project files @@ -56,11 +39,12 @@ namespace Semmle.Autobuild /// /// A solution file on the filesystem, read using Microsoft.Build. /// - class Solution : ISolution + class Solution : ProjectOrSolution, ISolution { readonly SolutionFile solution; - public IEnumerable Projects { get; private set; } + readonly IEnumerable includedProjects; + public override IEnumerable IncludedProjects => includedProjects; public IEnumerable Configurations => solution == null ? Enumerable.Empty() : solution.SolutionConfigurations; @@ -71,18 +55,16 @@ namespace Semmle.Autobuild public string DefaultPlatformName => solution == null ? "" : solution.GetDefaultPlatformName(); - public Solution(Autobuilder builder, string path) + public Solution(Autobuilder builder, string path) : base(builder, path) { - Path = System.IO.Path.GetFullPath(path); try { - solution = SolutionFile.Parse(Path); + solution = SolutionFile.Parse(FullPath); - Projects = + includedProjects = solution.ProjectsInOrder. Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat). - Select(p => System.IO.Path.GetFullPath(FileUtils.ConvertToNative(p.AbsolutePath))). - Where(p => builder.Options.Language.ProjectFileHasThisLanguage(p)). + Select(p => builder.Actions.GetFullPath(FileUtils.ConvertToNative(p.AbsolutePath))). Select(p => new Project(builder, p)). ToArray(); } @@ -90,17 +72,11 @@ namespace Semmle.Autobuild { // We allow specifying projects as solutions in lgtm.yml, so model // that scenario as a solution with just that one project - Projects = Language.IsProjectFileForAnySupportedLanguage(Path) - ? new[] { new Project(builder, Path) } - : new Project[0]; + includedProjects = new[] { new Project(builder, path) }; } } - public string Path { get; private set; } - - public int ProjectCount => Projects.Count(); - - IEnumerable ToolsVersions => Projects.Where(p => p.ValidToolsVersion).Select(p => p.ToolsVersion); + IEnumerable ToolsVersions => includedProjects.Where(p => p.ValidToolsVersion).Select(p => p.ToolsVersion); public Version ToolsVersion => ToolsVersions.Any() ? ToolsVersions.Max() : new Version(); } From e4f68ae324a86c477a754fdd400c28f51daa4f6c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 22 Nov 2018 09:53:52 +0100 Subject: [PATCH 91/94] C#: Address review comments --- .../Semmle.Autobuild.Tests/BuildScripts.cs | 2 - .../Semmle.Autobuild/Autobuilder.cs | 51 ++++++++----------- .../Semmle.Autobuild/BuildActions.cs | 7 --- .../Semmle.Autobuild/BuildCommandAutoRule.cs | 2 +- .../Semmle.Autobuild/BuildScript.cs | 2 - .../Semmle.Autobuild/MsBuildRule.cs | 1 - .../autobuilder/Semmle.Autobuild/Project.cs | 2 +- .../Semmle.Autobuild/ProjectOrSolution.cs | 1 - 8 files changed, 23 insertions(+), 45 deletions(-) diff --git a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs index b11f31be6f8..e365abca65c 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs @@ -135,8 +135,6 @@ namespace Semmle.Extraction.Tests string IBuildActions.GetFullPath(string path) => path; - string IBuildActions.GetDirectoryName(string path) => System.IO.Path.GetDirectoryName(path); - void IBuildActions.WriteAllText(string filename, string contents) { } diff --git a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs index 38e8dd11b7e..b50c5d9797a 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs @@ -128,9 +128,10 @@ namespace Semmle.Autobuild projectsOrSolutionsToBuildLazy = new Lazy>(() => { + List ret; if (options.Solution.Any()) { - var ret = new List(); + ret = new List(); foreach (var solution in options.Solution) { if (actions.FileExists(solution)) @@ -141,53 +142,43 @@ namespace Semmle.Autobuild return ret; } - bool FindFiles(string extension, Func create, out IEnumerable files) + IEnumerable FindFiles(string extension, Func create) { - var allFiles = GetExtensions(extension). + var matchingFiles = GetExtensions(extension). Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)). Where(p => p.ProjectOrSolution.HasLanguage(this.Options.Language)). ToArray(); - if (allFiles.Length == 0) - { - files = null; - return false; - } + if (matchingFiles.Length == 0) + return null; if (options.AllSolutions) - { - files = allFiles.Select(p => p.ProjectOrSolution); - return true; - } + return matchingFiles.Select(p => p.ProjectOrSolution); - var firstIsClosest = allFiles.Length > 1 && allFiles[0].DistanceFromRoot < allFiles[1].DistanceFromRoot; - if (allFiles.Length == 1 || firstIsClosest) - { - files = allFiles.Select(p => p.ProjectOrSolution).Take(1); - return true; - } + var firstIsClosest = matchingFiles.Length > 1 && matchingFiles[0].DistanceFromRoot < matchingFiles[1].DistanceFromRoot; + if (matchingFiles.Length == 1 || firstIsClosest) + return matchingFiles.Select(p => p.ProjectOrSolution).Take(1); - var candidates = allFiles. - Where(f => f.DistanceFromRoot == allFiles[0].DistanceFromRoot). + var candidates = matchingFiles. + Where(f => f.DistanceFromRoot == matchingFiles[0].DistanceFromRoot). Select(f => f.ProjectOrSolution); Log(Severity.Info, $"Found multiple '{extension}' files, giving up: {string.Join(", ", candidates)}."); - files = new IProjectOrSolution[0]; - return true; + return new IProjectOrSolution[0]; } // First look for `.proj` files - if (FindFiles(".proj", f => new Project(this, f), out var ret1)) - return ret1.ToList(); + ret = FindFiles(".proj", f => new Project(this, f))?.ToList(); + if (ret != null) + return ret; // Then look for `.sln` files - if (FindFiles(".sln", f => new Solution(this, f), out var ret2)) - return ret2.ToList(); + ret = FindFiles(".sln", f => new Solution(this, f))?.ToList(); + if (ret != null) + return ret; // Finally look for language specific project files, e.g. `.csproj` files - if (FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f), out var ret3)) - return ret3.ToList(); - - return new List(); + ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f))?.ToList(); + return ret ?? new List(); }); SemmleDist = Actions.GetEnvironmentVariable("SEMMLE_DIST"); diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs b/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs index d0acedbcabd..433598c5c16 100644 --- a/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs +++ b/csharp/autobuilder/Semmle.Autobuild/BuildActions.cs @@ -102,11 +102,6 @@ namespace Semmle.Autobuild /// string GetFullPath(string path); - /// - /// Gets the directory of , Path.GetDirectoryName(). - /// - string GetDirectoryName(string path); - /// /// Writes contents to file, File.WriteAllText(). /// @@ -192,8 +187,6 @@ namespace Semmle.Autobuild string IBuildActions.GetFullPath(string path) => Path.GetFullPath(path); - string IBuildActions.GetDirectoryName(string path) => Path.GetDirectoryName(path); - public static readonly IBuildActions Instance = new SystemBuildActions(); } } diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs b/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs index 151fdd70327..9ec8a3e16eb 100644 --- a/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild/BuildCommandAutoRule.cs @@ -40,7 +40,7 @@ namespace Semmle.Autobuild chmod.RunCommand("/bin/chmod", $"u+x {scriptPath}"); var chmodScript = builder.Actions.IsWindows() ? BuildScript.Success : BuildScript.Try(chmod.Script); - var dir = builder.Actions.GetDirectoryName(scriptPath); + var dir = Path.GetDirectoryName(scriptPath); // A specific .NET Core version may be required return chmodScript & DotNetRule.WithDotNet(builder, dotNet => diff --git a/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs b/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs index d36e98a0db5..c268ae98030 100644 --- a/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs +++ b/csharp/autobuilder/Semmle.Autobuild/BuildScript.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; -using Semmle.Util; namespace Semmle.Autobuild { diff --git a/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs index 141504075cf..2b46d8d526e 100644 --- a/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild/MsBuildRule.cs @@ -1,5 +1,4 @@ using Semmle.Util.Logging; -using System.IO; using System.Linq; namespace Semmle.Autobuild diff --git a/csharp/autobuilder/Semmle.Autobuild/Project.cs b/csharp/autobuilder/Semmle.Autobuild/Project.cs index 9e9abeff82c..174ea7295ab 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Project.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Project.cs @@ -78,7 +78,7 @@ namespace Semmle.Autobuild foreach (var include in projectFileIncludes.Concat(projectFilesIncludes)) { var includePath = builder.Actions.IsWindows() ? include.Value : include.Value.Replace("\\", "/"); - includedProjects.Add(new Project(builder, builder.Actions.PathCombine(builder.Actions.GetDirectoryName(this.FullPath), includePath))); + includedProjects.Add(new Project(builder, builder.Actions.PathCombine(Path.GetDirectoryName(this.FullPath), includePath))); } } } diff --git a/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs b/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs index 4c0cbe08b0b..060852b8eaa 100644 --- a/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs +++ b/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.IO; using System.Linq; namespace Semmle.Autobuild From c3ccdfa7f9c2a569892002fd5be8639addd270cd Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 22 Nov 2018 11:25:13 +0100 Subject: [PATCH 92/94] C#: Guard against cyclic inclusions in project files --- .../Semmle.Autobuild.Tests/BuildScripts.cs | 22 +++++++++++++ .../autobuilder/Semmle.Autobuild/Project.cs | 31 +++++++++++-------- .../Semmle.Autobuild/ProjectOrSolution.cs | 16 +++++++--- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs index e365abca65c..4cd50926dba 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs @@ -1020,5 +1020,27 @@ namespace Semmle.Extraction.Tests var autobuilder = CreateAutoBuilder("csharp", false); TestAutobuilderScript(autobuilder, 0, 4); } + + [Fact] + public void TestCyclicDirsProj() + { + Actions.FileExists["dirs.proj"] = true; + Actions.GetEnvironmentVariable["TRAP_FOLDER"] = null; + Actions.GetEnvironmentVariable["SOURCE_ARCHIVE"] = null; + Actions.FileExists["csharp.log"] = false; + Actions.EnumerateFiles[@"C:\Project"] = "dirs.proj"; + Actions.EnumerateDirectories[@"C:\Project"] = ""; + + var dirsproj1 = new XmlDocument(); + dirsproj1.LoadXml(@" + + + +"); + Actions.LoadXml["dirs.proj"] = dirsproj1; + + var autobuilder = CreateAutoBuilder("csharp", false); + TestAutobuilderScript(autobuilder, 1, 0); + } } } diff --git a/csharp/autobuilder/Semmle.Autobuild/Project.cs b/csharp/autobuilder/Semmle.Autobuild/Project.cs index 174ea7295ab..87088d1edfb 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Project.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Project.cs @@ -23,13 +23,13 @@ namespace Semmle.Autobuild public Version ToolsVersion { get; private set; } - readonly List includedProjects = new List(); - public override IEnumerable IncludedProjects => - includedProjects.Concat(includedProjects.SelectMany(s => s.IncludedProjects)); + readonly Lazy> includedProjectsLazy; + public override IEnumerable IncludedProjects => includedProjectsLazy.Value; public Project(Autobuilder builder, string path) : base(builder, path) { ToolsVersion = new Version(); + includedProjectsLazy = new Lazy>(() => new List()); if (!builder.Actions.FileExists(FullPath)) return; @@ -69,17 +69,22 @@ namespace Semmle.Autobuild } } - // The documentation on `.proj` files is very limited, but it appears that both - // `` and `` is valid - var mgr = new XmlNamespaceManager(projFile.NameTable); - mgr.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); - var projectFileIncludes = root.SelectNodes("//msbuild:Project/msbuild:ItemGroup/msbuild:ProjectFile/@Include", mgr).OfType(); - var projectFilesIncludes = root.SelectNodes("//msbuild:Project/msbuild:ItemGroup/msbuild:ProjectFiles/@Include", mgr).OfType(); - foreach (var include in projectFileIncludes.Concat(projectFilesIncludes)) + includedProjectsLazy = new Lazy>(() => { - var includePath = builder.Actions.IsWindows() ? include.Value : include.Value.Replace("\\", "/"); - includedProjects.Add(new Project(builder, builder.Actions.PathCombine(Path.GetDirectoryName(this.FullPath), includePath))); - } + var ret = new List(); + // The documentation on `.proj` files is very limited, but it appears that both + // `` and `` is valid + var mgr = new XmlNamespaceManager(projFile.NameTable); + mgr.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); + var projectFileIncludes = root.SelectNodes("//msbuild:Project/msbuild:ItemGroup/msbuild:ProjectFile/@Include", mgr).OfType(); + var projectFilesIncludes = root.SelectNodes("//msbuild:Project/msbuild:ItemGroup/msbuild:ProjectFiles/@Include", mgr).OfType(); + foreach (var include in projectFileIncludes.Concat(projectFilesIncludes)) + { + var includePath = builder.Actions.IsWindows() ? include.Value : include.Value.Replace("\\", "/"); + ret.Add(new Project(builder, builder.Actions.PathCombine(Path.GetDirectoryName(this.FullPath), includePath))); + } + return ret; + }); } } } diff --git a/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs b/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs index 060852b8eaa..53025345b69 100644 --- a/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs +++ b/csharp/autobuilder/Semmle.Autobuild/ProjectOrSolution.cs @@ -15,7 +15,7 @@ namespace Semmle.Autobuild string FullPath { get; } /// - /// Gets a list of other projects included by this file. + /// Gets a list of other projects directly included by this file. /// IEnumerable IncludedProjects { get; } } @@ -39,8 +39,16 @@ namespace Semmle.Autobuild /// /// Holds if this file includes a project with code from language . /// - public static bool HasLanguage(this IProjectOrSolution p, Language l) => - l.ProjectFileHasThisLanguage(p.FullPath) || - p.IncludedProjects.Any(p0 => l.ProjectFileHasThisLanguage(p0.FullPath)); + public static bool HasLanguage(this IProjectOrSolution p, Language l) + { + bool HasLanguage(IProjectOrSolution p0, HashSet seen) + { + if (seen.Contains(p0.FullPath)) + return false; + seen.Add(p0.FullPath); // guard against cyclic includes + return l.ProjectFileHasThisLanguage(p0.FullPath) || p0.IncludedProjects.Any(p1 => HasLanguage(p1, seen)); + } + return HasLanguage(p, new HashSet()); + } } } From 1939773684aab2b619870bbfdac6dec997006ef3 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 22 Nov 2018 14:17:27 +0100 Subject: [PATCH 93/94] C#: Address review comments --- csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs index b50c5d9797a..02e3b672511 100644 --- a/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs +++ b/csharp/autobuilder/Semmle.Autobuild/Autobuilder.cs @@ -29,7 +29,7 @@ namespace Semmle.Autobuild public class Autobuilder { /// - /// Full file paths of files found in the project directory, as well + /// Full file paths of files found in the project directory, as well as /// their distance from the project root folder. The list is sorted /// by distance in ascending order. /// @@ -37,8 +37,8 @@ namespace Semmle.Autobuild readonly Lazy> pathsLazy; /// - /// Gets a list of paths matching a set of extensions - /// (including the "."), as well their distance from the project root folder. + /// Gets a list of paths matching a set of extensions (including the "."), + /// as well as their distance from the project root folder. /// The list is sorted by distance in ascending order. /// /// The extensions to find. @@ -47,8 +47,8 @@ namespace Semmle.Autobuild Paths.Where(p => extensions.Contains(Path.GetExtension(p.Item1))); /// - /// Gets all paths matching a particular filename, as well - /// their distance from the project root folder. The list is sorted + /// Gets all paths matching a particular filename, as well as + /// their distance from the project root folder. The list is sorted /// by distance in ascending order. /// /// The filename to find. From d24145831bf81f078d47e6cdc5b0ab062936dfb7 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 23 Nov 2018 14:21:30 +0100 Subject: [PATCH 94/94] Java: Add change note for #459. --- change-notes/1.19/analysis-java.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.19/analysis-java.md b/change-notes/1.19/analysis-java.md index 6458ff1d010..e9594966b6e 100644 --- a/change-notes/1.19/analysis-java.md +++ b/change-notes/1.19/analysis-java.md @@ -16,6 +16,7 @@ | **Query** | **Expected impact** | **Change** | |----------------------------|------------------------|------------------------------------------------------------------| | Array index out of bounds (`java/index-out-of-bounds`) | Fewer false positive results | False positives involving arrays with a length evenly divisible by 3 or some greater number and an index being increased with a similar stride length are no longer reported. | +| Confusing overloading of methods (`java/confusing-method-signature`) | Fewer false positive results | A bugfix in the inheritance relation ensures that spurious results on certain generic classes no longer occur. | | Query built from user-controlled sources (`java/sql-injection`) | More results | Sql injection sinks from the Spring JDBC, MyBatis, and Hibernate frameworks are now reported. | | Query built without neutralizing special characters (`java/concatenated-sql-query`) | More results | Sql injection sinks from the Spring JDBC, MyBatis, and Hibernate frameworks are now reported. | | Unreachable catch clause (`java/unreachable-catch-clause`) | Fewer false positive results | This rule now accounts for calls to generic methods that throw generic exceptions. |