From de05aee483c204aa6da50fe6213c44c229748348 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 18 Nov 2024 11:11:25 -0500 Subject: [PATCH 01/63] Adding model transition to using Throwing.qll. --- .../raw/internal/TranslatedCall.qll | 4 +- .../cpp/models/implementations/Memcpy.qll | 4 +- .../cpp/models/implementations/Memset.qll | 4 +- .../implementations/NoexceptFunction.qll | 4 +- .../cpp/models/implementations/Printf.qll | 12 +++- .../cpp/models/implementations/Strcat.qll | 4 +- .../cpp/models/implementations/Strcpy.qll | 4 +- .../StructuredExceptionHandling.qll | 23 ++++++- .../cpp/models/interfaces/NonThrowing.qll | 11 --- .../code/cpp/models/interfaces/Throwing.qll | 69 +++++++++++++++++-- 10 files changed, 112 insertions(+), 27 deletions(-) delete mode 100644 cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index daa6bdaafcf..a4c67886959 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(_) + expr.getTarget().(ThrowingFunction).mayRaiseException() } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(true) + expr.getTarget().(ThrowingFunction).alwaysRaisesException() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll index 0bf2dd31fe4..8c3ae368da9 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll @@ -9,7 +9,7 @@ import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.Taint -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant @@ -106,6 +106,8 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and index = this.getParamDest() } + + override TCxxException getExceptionType() { any() } } private string mempcpy() { result = ["mempcpy", "wmempcpy"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll index ab2e0af99f3..6a4ab8a133f 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll @@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction, SideEffectFunction, NonThrowingFunction @@ -74,6 +74,8 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias i = 0 and if this.hasGlobalName(bzero()) then result = 1 else result = 2 } + + override TCxxException getExceptionType() { any() } } private string bzero() { result = ["bzero", "explicit_bzero"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll index b0f76ee6538..ee05b2a68a0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll @@ -1,4 +1,4 @@ -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * A function that is annotated with a `noexcept` specifier (or the equivalent @@ -8,4 +8,6 @@ import semmle.code.cpp.models.interfaces.NonThrowing */ class NoexceptFunction extends NonThrowingFunction { NoexceptFunction() { this.isNoExcept() or this.isNoThrow() } + + override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 9c3bfb4f35e..7dbd38126bf 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard functions `printf`, `wprintf` and their glib variants. @@ -32,6 +32,8 @@ private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunct override predicate parameterEscapesOnlyViaReturn(int n) { none() } override predicate parameterIsAlwaysReturned(int n) { none() } + + override TCxxException getExceptionType() { any() } } /** @@ -50,6 +52,8 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } + + override TCxxException getExceptionType() { any() } } /** @@ -93,6 +97,8 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction { then result = 4 else result = super.getFirstFormatArgumentIndex() } + + override TCxxException getExceptionType() { any() } } /** @@ -165,6 +171,8 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, // We don't know how many parameters are passed to the function since it's varargs, but they also have read side effects. i = this.getFormatParameterIndex() and buffer = true } + + override TCxxException getExceptionType() { any() } } /** @@ -215,4 +223,6 @@ private class Syslog extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override predicate isOutputGlobal() { any() } + + override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll index 9b11ed0af15..df85c56148a 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll @@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard function `strcat` and its wide, sized, and Microsoft variants. @@ -94,6 +94,8 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid (i = 0 or i = 1) and buffer = true } + + override TCxxException getExceptionType() { any() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll index b7f06f0cebf..b09cbeb8dc6 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll @@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.interfaces.Throwing /** * The standard function `strcpy` and its wide, sized, and Microsoft variants. @@ -145,4 +145,6 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid i = this.getParamDest() and result = this.getParamSize() } + + override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index af8f3088f25..d5941488d0d 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -1,9 +1,26 @@ import semmle.code.cpp.models.interfaces.Throwing -class WindowsDriverFunction extends ThrowingFunction { - WindowsDriverFunction() { +/** + * The default behavior for Structured Exception Handling (SEH) is + * any function may (conditionally) raise an exception. + * NOTE: this can be overridden by for any specific function to make in + * unconditional or non-throwing. IR generation will enforce + * the most strict interpretation. + */ +class DefaultSehExceptionBehavior extends ThrowingFunction { + DefaultSehExceptionBehavior() { any() } + + override predicate raisesException(boolean unconditional) { unconditional = false } + + override TSehException getExceptionType() { any() } +} + +class WindowsDriverExceptionAnnotation extends ThrowingFunction { + WindowsDriverExceptionAnnotation() { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) } - final override predicate mayThrowException(boolean unconditional) { unconditional = true } + override predicate raisesException(boolean unconditional) { unconditional = true } + + override TSehException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll deleted file mode 100644 index 64901d39ad3..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Provides an abstract class for modeling functions that never throw. - */ - -import semmle.code.cpp.Function -import semmle.code.cpp.models.Models - -/** - * A function that is guaranteed to never throw. - */ -abstract class NonThrowingFunction extends Function { } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index 79b7523f1d9..72db8c9e96c 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -11,12 +11,71 @@ import semmle.code.cpp.models.Models import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs /** - * A class that models the exceptional behavior of a function. + * Represents a type of exception, + * either Structured Exception Handling (SEH) or C++ exceptions. */ -abstract class ThrowingFunction extends Function { +newtype TException = + /** Structured Exception Handling (SEH) exception */ + TSehException() or + /** C++ exception */ + TCxxException() + +/** + * Functions with information about how an exception is thrown or if one is thrown at all. + * If throwing details conflict for the same function, IR is assumed + * to use the most restricted interpretation, meaning taking options + * that stipulate no exception is raised, before the exception is always raised, + * before conditional exceptions. + * + * Annotations must specify if the exception is from SEH (structured exception handling) + * or ordinary c++ exceptions. + */ +abstract private class ExceptionAnnotation extends Function { /** - * Holds if this function may throw an exception during evaluation. - * If `unconditional` is `true` the function always throws an exception. + * Returns the type of exception this annotation is for, + * either a CPP exception or a STructured Exception Handling (SEH) exception. */ - abstract predicate mayThrowException(boolean unconditional); + abstract TException getExceptionType(); + + /** + * Holds if the exception type of this annotation is for a Structured Exception Handling (SEH) exception. + */ + final predicate isSeh() { this.getExceptionType() = TSehException() } + + /** + * Holds if the exception type of this annotation is for a CPP exception. + */ + final predicate isCxx() { this.getExceptionType() = TCxxException() } +} + +/** + * A Function that is known to not throw an exception. + */ +abstract class NonThrowingFunction extends ExceptionAnnotation { } + +/** + * A function this is known to raise an exception. + */ +abstract class ThrowingFunction extends ExceptionAnnotation { + ThrowingFunction() { any() } + + /** + * Holds if this function may raise an exception during evaluation. + * If `unconditional` is `false` the function may raise, and if `true` the function + * will always raise an exception. + * Do not specify `none()` if no exception is raised, instead use the + * `NonThrowingFunction` class instead. + */ + abstract predicate raisesException(boolean unconditional); + + /** + * Holds if this function will always raise an exception if called + */ + final predicate alwaysRaisesException() { this.raisesException(true) } + + /** + * Holds if this function may raise an exception if called but + * it is not guaranteed to do so. I.e., the function does not always raise an exception. + */ + final predicate mayRaiseException() { this.raisesException(false) } } From 4b83a451bd0547bba0d6bd41750d4739fd7dd5e0 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 18 Nov 2024 11:14:46 -0500 Subject: [PATCH 02/63] Change log --- cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md diff --git a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md new file mode 100644 index 00000000000..f3c33f40b51 --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Removed NonThrowing.qll. Throwing meta-data now part of Throwing.qll. Updated models and IR to use the new Throwing library and predicates. \ No newline at end of file From 792231c949154be6b003d86204df40478e23e600 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Mon, 18 Nov 2024 14:43:44 -0500 Subject: [PATCH 03/63] Removing SEH default case for function calls as the logic to handle SEH is not yet part of the IR generation to make this logic work. --- .../StructuredExceptionHandling.qll | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index d5941488d0d..485dc7137b8 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -1,20 +1,5 @@ import semmle.code.cpp.models.interfaces.Throwing -/** - * The default behavior for Structured Exception Handling (SEH) is - * any function may (conditionally) raise an exception. - * NOTE: this can be overridden by for any specific function to make in - * unconditional or non-throwing. IR generation will enforce - * the most strict interpretation. - */ -class DefaultSehExceptionBehavior extends ThrowingFunction { - DefaultSehExceptionBehavior() { any() } - - override predicate raisesException(boolean unconditional) { unconditional = false } - - override TSehException getExceptionType() { any() } -} - class WindowsDriverExceptionAnnotation extends ThrowingFunction { WindowsDriverExceptionAnnotation() { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) From 1c874d32217994a6faae1d2a24d07d19a3a52af2 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 10:04:11 -0500 Subject: [PATCH 04/63] Fixed usage raisesException --- .../cpp/ir/implementation/raw/internal/TranslatedCall.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index a4c67886959..5f1b2fbe3b4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).mayRaiseException() + expr.getTarget().(ThrowingFunction).raisesException(_) } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).alwaysRaisesException() + expr.getTarget().(ThrowingFunction).raisesException(true) } } From 26d590a616fba45b40fa3e5d47791b59c6d38d13 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 12:57:50 -0500 Subject: [PATCH 05/63] Putting back deleted file, and deprecating instead. Deprecating mayThrowException as well. --- .../code/cpp/models/interfaces/NonThrowing.qll | 13 +++++++++++++ .../semmle/code/cpp/models/interfaces/Throwing.qll | 7 +++++++ 2 files changed, 20 insertions(+) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll new file mode 100644 index 00000000000..9f2c28979b4 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll @@ -0,0 +1,13 @@ +/** + * Provides an abstract class for modeling functions that never throw. + */ + +import semmle.code.cpp.Function +import semmle.code.cpp.models.Models + +/** + * A function that is guaranteed to never throw. + * + * DEPRECATED: use `NonThrowingFunction` in `semmle.code.cpp.models.Models.Interfaces.Throwing` instead. + */ +abstract deprecated class NonThrowingFunction extends Function { } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index 72db8c9e96c..bd64051d141 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -68,6 +68,13 @@ abstract class ThrowingFunction extends ExceptionAnnotation { */ abstract predicate raisesException(boolean unconditional); + /** + * DEPRECATES: use/extend `raisesException` instead. + */ + deprecated predicate mayThrowException(boolean unconditional){ + this.raisesException(unconditional) + } + /** * Holds if this function will always raise an exception if called */ From 07847762e1f7dc87408c0e74dba32edcd5d0be56 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 13:17:10 -0500 Subject: [PATCH 06/63] bringing back mayThrowException to make it cleaner/easier for backwards compatibility. --- .../raw/internal/TranslatedCall.qll | 4 ++-- .../code/cpp/models/interfaces/Throwing.qll | 17 ++--------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 5f1b2fbe3b4..daa6bdaafcf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).raisesException(_) + expr.getTarget().(ThrowingFunction).mayThrowException(_) } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).raisesException(true) + expr.getTarget().(ThrowingFunction).mayThrowException(true) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index bd64051d141..db6bd689b4f 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -66,23 +66,10 @@ abstract class ThrowingFunction extends ExceptionAnnotation { * Do not specify `none()` if no exception is raised, instead use the * `NonThrowingFunction` class instead. */ - abstract predicate raisesException(boolean unconditional); - - /** - * DEPRECATES: use/extend `raisesException` instead. - */ - deprecated predicate mayThrowException(boolean unconditional){ - this.raisesException(unconditional) - } + abstract predicate mayThrowException(boolean unconditional); /** * Holds if this function will always raise an exception if called */ - final predicate alwaysRaisesException() { this.raisesException(true) } - - /** - * Holds if this function may raise an exception if called but - * it is not guaranteed to do so. I.e., the function does not always raise an exception. - */ - final predicate mayRaiseException() { this.raisesException(false) } + final predicate alwaysRaisesException() { this.mayThrowException(true) } } From a69daa0d2018844fae600a420e7417de4f8600b8 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 13:35:45 -0500 Subject: [PATCH 07/63] Missing change to 'mayThrowException' in StructuredExceptionHandling.qll --- .../cpp/models/implementations/StructuredExceptionHandling.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index 485dc7137b8..36a2f6cdbe4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -5,7 +5,7 @@ class WindowsDriverExceptionAnnotation extends ThrowingFunction { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) } - override predicate raisesException(boolean unconditional) { unconditional = true } + override predicate mayThrowException(boolean unconditional) { unconditional = true } override TSehException getExceptionType() { any() } } From 4e777561f06ad9f891de48ab648135ebc50cd361 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 19 Nov 2024 15:10:15 -0500 Subject: [PATCH 08/63] Changing terminology back to "throws" vs "rasis" for alwaysThrowsException to be consistent with other backward compatibility changes. --- cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index db6bd689b4f..d64ba61caa0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -71,5 +71,5 @@ abstract class ThrowingFunction extends ExceptionAnnotation { /** * Holds if this function will always raise an exception if called */ - final predicate alwaysRaisesException() { this.mayThrowException(true) } + final predicate alwaysThrowsException() { this.mayThrowException(true) } } From 69df07ed1208ca12a82e83c1c2da9f430dbd458a Mon Sep 17 00:00:00 2001 From: Ben Rodes Date: Wed, 20 Nov 2024 09:06:44 -0500 Subject: [PATCH 09/63] Update cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md Co-authored-by: Mathias Vorreiter Pedersen --- cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md index f3c33f40b51..114822e6c8f 100644 --- a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md +++ b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md @@ -1,4 +1,4 @@ --- -category: minorAnalysis +category: deprecated --- -* Removed NonThrowing.qll. Throwing meta-data now part of Throwing.qll. Updated models and IR to use the new Throwing library and predicates. \ No newline at end of file +* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonThrowing` class from `semmle.code.cpp.models.interfaces.Throwing` instead. \ No newline at end of file From 9b2590ec7a2c49771e12b45bdeec185c76767769 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 11:28:11 -0500 Subject: [PATCH 10/63] Updating PR per review comments. Moving more towards a simplified model. --- .../raw/internal/TranslatedCall.qll | 4 +- .../cpp/models/implementations/Memcpy.qll | 6 +- .../cpp/models/implementations/Memset.qll | 6 +- .../implementations/NoexceptFunction.qll | 6 +- .../cpp/models/implementations/Printf.qll | 14 +--- .../cpp/models/implementations/Strcat.qll | 6 +- .../cpp/models/implementations/Strcpy.qll | 6 +- .../StructuredExceptionHandling.qll | 6 +- .../cpp/models/interfaces/NonThrowing.qll | 10 ++- .../code/cpp/models/interfaces/Throwing.qll | 73 +++++-------------- 10 files changed, 41 insertions(+), 96 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index daa6bdaafcf..df92e73ed37 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(_) + expr.getTarget() instanceof AlwaysSehThrowingFunction } final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(true) + expr.getTarget() instanceof AlwaysSehThrowingFunction } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll index 8c3ae368da9..311847e8aec 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll @@ -9,14 +9,14 @@ import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.Taint -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant * `__builtin___memcpy_chk`. */ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction, - AliasFunction, NonThrowingFunction + AliasFunction, NonCppThrowingFunction { MemcpyFunction() { // memcpy(dest, src, num) @@ -106,8 +106,6 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and index = this.getParamDest() } - - override TCxxException getExceptionType() { any() } } private string mempcpy() { result = ["mempcpy", "wmempcpy"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll index 6a4ab8a133f..51234e50f94 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll @@ -8,10 +8,10 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction, - SideEffectFunction, NonThrowingFunction + SideEffectFunction, NonCppThrowingFunction { MemsetFunctionModel() { this.hasGlobalOrStdOrBslName("memset") @@ -74,8 +74,6 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias i = 0 and if this.hasGlobalName(bzero()) then result = 1 else result = 2 } - - override TCxxException getExceptionType() { any() } } private string bzero() { result = ["bzero", "explicit_bzero"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll index ee05b2a68a0..22f860bc593 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll @@ -1,4 +1,4 @@ -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * A function that is annotated with a `noexcept` specifier (or the equivalent @@ -6,8 +6,6 @@ import semmle.code.cpp.models.interfaces.Throwing * * Note: The `throw` specifier was deprecated in C++11 and removed in C++17. */ -class NoexceptFunction extends NonThrowingFunction { +class NoexceptFunction extends NonCppThrowingFunction { NoexceptFunction() { this.isNoExcept() or this.isNoThrow() } - - override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 7dbd38126bf..f28359c7f64 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -8,12 +8,12 @@ import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard functions `printf`, `wprintf` and their glib variants. */ -private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunction { +private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFunction { Printf() { this instanceof TopLevelFunction and ( @@ -32,8 +32,6 @@ private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunct override predicate parameterEscapesOnlyViaReturn(int n) { none() } override predicate parameterIsAlwaysReturned(int n) { none() } - - override TCxxException getExceptionType() { any() } } /** @@ -52,8 +50,6 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } - - override TCxxException getExceptionType() { any() } } /** @@ -97,8 +93,6 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction { then result = 4 else result = super.getFirstFormatArgumentIndex() } - - override TCxxException getExceptionType() { any() } } /** @@ -171,8 +165,6 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, // We don't know how many parameters are passed to the function since it's varargs, but they also have read side effects. i = this.getFormatParameterIndex() and buffer = true } - - override TCxxException getExceptionType() { any() } } /** @@ -223,6 +215,4 @@ private class Syslog extends FormattingFunction, NonThrowingFunction { override int getFormatParameterIndex() { result = 1 } override predicate isOutputGlobal() { any() } - - override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll index df85c56148a..966c7425dc4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll @@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard function `strcat` and its wide, sized, and Microsoft variants. @@ -15,7 +15,7 @@ import semmle.code.cpp.models.interfaces.Throwing * Does not include `strlcat`, which is covered by `StrlcatFunction` */ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction, - NonThrowingFunction + NonCppThrowingFunction { StrcatFunction() { this.hasGlobalOrStdOrBslName([ @@ -94,8 +94,6 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid (i = 0 or i = 1) and buffer = true } - - override TCxxException getExceptionType() { any() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll index b09cbeb8dc6..b7ed20f1bab 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll @@ -7,13 +7,13 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect -import semmle.code.cpp.models.interfaces.Throwing +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard function `strcpy` and its wide, sized, and Microsoft variants. */ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction, - NonThrowingFunction + NonCppThrowingFunction { StrcpyFunction() { this.hasGlobalOrStdOrBslName([ @@ -145,6 +145,4 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid i = this.getParamDest() and result = this.getParamSize() } - - override TCxxException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll index 36a2f6cdbe4..e561bfadee6 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll @@ -1,11 +1,7 @@ import semmle.code.cpp.models.interfaces.Throwing -class WindowsDriverExceptionAnnotation extends ThrowingFunction { +class WindowsDriverExceptionAnnotation extends AlwaysSehThrowingFunction { WindowsDriverExceptionAnnotation() { this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"]) } - - override predicate mayThrowException(boolean unconditional) { unconditional = true } - - override TSehException getExceptionType() { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll index 9f2c28979b4..5ddf754f745 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll @@ -5,9 +5,15 @@ import semmle.code.cpp.Function import semmle.code.cpp.models.Models +/** + * A function that is guaranteed to never throw a C++ exception + * (distinct from a structured exception handling, SEH, exception). + */ +abstract class NonCppThrowingFunction extends Function { } + /** * A function that is guaranteed to never throw. * - * DEPRECATED: use `NonThrowingFunction` in `semmle.code.cpp.models.Models.Interfaces.Throwing` instead. + * DEPRECATED: use `NonCppThrowingFunction` instead. */ -abstract deprecated class NonThrowingFunction extends Function { } +deprecated class NonThrowingFunction = NonCppThrowingFunction; diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index d64ba61caa0..f75d0a78592 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -11,65 +11,28 @@ import semmle.code.cpp.models.Models import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs /** - * Represents a type of exception, - * either Structured Exception Handling (SEH) or C++ exceptions. - */ -newtype TException = - /** Structured Exception Handling (SEH) exception */ - TSehException() or - /** C++ exception */ - TCxxException() - -/** - * Functions with information about how an exception is thrown or if one is thrown at all. - * If throwing details conflict for the same function, IR is assumed - * to use the most restricted interpretation, meaning taking options - * that stipulate no exception is raised, before the exception is always raised, - * before conditional exceptions. + * A function that is known to raise an exception. * - * Annotations must specify if the exception is from SEH (structured exception handling) - * or ordinary c++ exceptions. + * DEPRECATED: use `AlwaysSehThrowingFunction` instead if a function unconditionally throws. + * These are assumed the only case where functions throw/raise exceptions unconditionally. + * For functions that may throw, this will be the default behavior in the IR. */ -abstract private class ExceptionAnnotation extends Function { - /** - * Returns the type of exception this annotation is for, - * either a CPP exception or a STructured Exception Handling (SEH) exception. - */ - abstract TException getExceptionType(); - - /** - * Holds if the exception type of this annotation is for a Structured Exception Handling (SEH) exception. - */ - final predicate isSeh() { this.getExceptionType() = TSehException() } - - /** - * Holds if the exception type of this annotation is for a CPP exception. - */ - final predicate isCxx() { this.getExceptionType() = TCxxException() } -} - -/** - * A Function that is known to not throw an exception. - */ -abstract class NonThrowingFunction extends ExceptionAnnotation { } - -/** - * A function this is known to raise an exception. - */ -abstract class ThrowingFunction extends ExceptionAnnotation { +abstract deprecated class ThrowingFunction extends Function { ThrowingFunction() { any() } /** - * Holds if this function may raise an exception during evaluation. - * If `unconditional` is `false` the function may raise, and if `true` the function - * will always raise an exception. - * Do not specify `none()` if no exception is raised, instead use the - * `NonThrowingFunction` class instead. + * Holds if this function may throw an exception during evaluation. + * If `unconditional` is `true` the function always throws an exception. + * + * DPERECATED: for always throwing functions use `AlwaysSehThrowingFunction` instead. + * For functions that may throw, this will be the default behavior in the IR. */ - abstract predicate mayThrowException(boolean unconditional); - - /** - * Holds if this function will always raise an exception if called - */ - final predicate alwaysThrowsException() { this.mayThrowException(true) } + abstract deprecated predicate mayThrowException(boolean unconditional); } + +/** + * A function that is known to raise an exception unconditionally. + * The only cases known where this happens is for SEH + * (structured exception handling) exceptions. + */ +abstract class AlwaysSehThrowingFunction extends Function { } From 44126913cd8af92e731247f3d534b388aa0d3179 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:08:04 -0500 Subject: [PATCH 11/63] Delaying deprecation of ThrowingFunction. --- .../ir/implementation/raw/internal/TranslatedCall.qll | 4 ++-- .../semmle/code/cpp/models/interfaces/Throwing.qll | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index df92e73ed37..daa6bdaafcf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { } final override predicate mayThrowException() { - expr.getTarget() instanceof AlwaysSehThrowingFunction + expr.getTarget().(ThrowingFunction).mayThrowException(_) } final override predicate mustThrowException() { - expr.getTarget() instanceof AlwaysSehThrowingFunction + expr.getTarget().(ThrowingFunction).mayThrowException(true) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index f75d0a78592..044b30f7b70 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -12,22 +12,15 @@ import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs /** * A function that is known to raise an exception. - * - * DEPRECATED: use `AlwaysSehThrowingFunction` instead if a function unconditionally throws. - * These are assumed the only case where functions throw/raise exceptions unconditionally. - * For functions that may throw, this will be the default behavior in the IR. */ -abstract deprecated class ThrowingFunction extends Function { +abstract class ThrowingFunction extends Function { ThrowingFunction() { any() } /** * Holds if this function may throw an exception during evaluation. * If `unconditional` is `true` the function always throws an exception. - * - * DPERECATED: for always throwing functions use `AlwaysSehThrowingFunction` instead. - * For functions that may throw, this will be the default behavior in the IR. */ - abstract deprecated predicate mayThrowException(boolean unconditional); + abstract predicate mayThrowException(boolean unconditional); } /** From 7059fc3e31bc5b66b1ed971091960080ad422533 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:10:42 -0500 Subject: [PATCH 12/63] Adding intermediate solution towards deprecating ThrowingFunction --- .../cpp/ir/implementation/raw/internal/TranslatedCall.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index daa6bdaafcf..2ddc55f91f5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -364,10 +364,14 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { final override predicate mayThrowException() { expr.getTarget().(ThrowingFunction).mayThrowException(_) + or + expr.getTarget() instanceof AlwaysSehThrowingFunction } final override predicate mustThrowException() { expr.getTarget().(ThrowingFunction).mayThrowException(true) + or + expr.getTarget() instanceof AlwaysSehThrowingFunction } } From 248f1c4ebea29dd967898b3077ac3dccea105919 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:15:14 -0500 Subject: [PATCH 13/63] Updating change log --- cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md index 114822e6c8f..73b358a0e1f 100644 --- a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md +++ b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md @@ -1,4 +1,4 @@ --- category: deprecated --- -* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonThrowing` class from `semmle.code.cpp.models.interfaces.Throwing` instead. \ No newline at end of file +* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. \ No newline at end of file From 583651ba40ff84c834905ded056fb65adfe7d835 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:41:26 -0500 Subject: [PATCH 14/63] Missing NonCppThrowingFunction changes in Printf.qll --- .../lib/semmle/code/cpp/models/implementations/Printf.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index f28359c7f64..585091eff70 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -37,7 +37,7 @@ private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFu /** * The standard functions `fprintf`, `fwprintf` and their glib variants. */ -private class Fprintf extends FormattingFunction, NonThrowingFunction { +private class Fprintf extends FormattingFunction, NonCppThrowingFunction { Fprintf() { this instanceof TopLevelFunction and ( @@ -55,7 +55,7 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction { /** * The standard function `sprintf` and its Microsoft and glib variants. */ -private class Sprintf extends FormattingFunction, NonThrowingFunction { +private class Sprintf extends FormattingFunction, NonCppThrowingFunction { Sprintf() { this instanceof TopLevelFunction and ( @@ -98,7 +98,7 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction { /** * Implements `Snprintf`. */ -private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonThrowingFunction { +private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonCppThrowingFunction { SnprintfImpl() { this instanceof TopLevelFunction and ( @@ -205,7 +205,7 @@ private class StringCchPrintf extends FormattingFunction { /** * The standard function `syslog`. */ -private class Syslog extends FormattingFunction, NonThrowingFunction { +private class Syslog extends FormattingFunction, NonCppThrowingFunction { Syslog() { this instanceof TopLevelFunction and this.hasGlobalName("syslog") and From 66cf736b4c8f56e2b5787a3906513fd5801c0a0d Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:44:28 -0500 Subject: [PATCH 15/63] printf formatting. --- cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 585091eff70..d4b054ea0b5 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -98,7 +98,9 @@ private class Sprintf extends FormattingFunction, NonCppThrowingFunction { /** * Implements `Snprintf`. */ -private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonCppThrowingFunction { +private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, + NonCppThrowingFunction +{ SnprintfImpl() { this instanceof TopLevelFunction and ( From 37365c746ccf15848cc9abc77f96678d11b01ec4 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 21 Nov 2024 12:59:56 -0500 Subject: [PATCH 16/63] Updating to NonCppThrowingFunction use in IncorrectALlocationErrorHandling.ql --- .../Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql index 92daf31b057..d4d908f8474 100644 --- a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql +++ b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql @@ -45,7 +45,7 @@ predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) { * like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier. */ predicate functionMayThrow(Function f) { - not f instanceof NonThrowingFunction and + not f instanceof NonCppThrowingFunction and (not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) } From 24eb65692f616cb1b3f1f8f0b5bad6bd10071ceb Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 26 Nov 2024 15:57:18 +0100 Subject: [PATCH 17/63] Rust: add some performance diagnostics This outputs some duration counts for various parts of the extraction process in the database in the form of telemetry diagnostics. The diagnostics format was preferred to putting things in the relational database as that will scale better to code scanning and is more flexible as for the data we can put into it without passing through the dbscheme. Also, although it's not the case yet, it will be possible to output diagnostics even if creation of the database fails. --- Cargo.lock | 6 +- MODULE.bazel | 2 +- .../tree_sitter_extractors_deps/BUILD.bazel | 2 +- .../BUILD.cargo_metadata-0.18.1.bazel | 2 +- .../BUILD.ra_ap_proc_macro_api-0.0.232.bazel | 2 +- .../BUILD.ra_ap_project_model-0.0.232.bazel | 2 +- ...2.bazel => BUILD.serde_json-1.0.133.bazel} | 6 +- .../tree_sitter_extractors_deps/defs.bzl | 16 +- rust/extractor/Cargo.toml | 2 + rust/extractor/src/config.rs | 1 + rust/extractor/src/diagnostics.rs | 258 ++++++++++++++++++ rust/extractor/src/main.rs | 90 ++++-- rust/ql/integration-tests/conftest.py | 9 + .../hello-project/diagnostics.expected | 101 +++++++ .../hello-project/test_project.py | 4 +- .../diagnostics.cargo.expected | 97 +++++++ .../diagnostics.rust-project.expected | 93 +++++++ .../hello-workspace/test_workspace.py | 6 +- 18 files changed, 656 insertions(+), 43 deletions(-) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.serde_json-1.0.132.bazel => BUILD.serde_json-1.0.133.bazel} (97%) create mode 100644 rust/extractor/src/diagnostics.rs create mode 100644 rust/ql/integration-tests/hello-project/diagnostics.expected create mode 100644 rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected create mode 100644 rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected diff --git a/Cargo.lock b/Cargo.lock index 1d5b8824c84..b0af4387f2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -381,6 +381,7 @@ version = "0.1.0" dependencies = [ "anyhow", "argfile", + "chrono", "clap", "codeql-extractor", "figment", @@ -404,6 +405,7 @@ dependencies = [ "ra_ap_vfs", "rust-extractor-macros", "serde", + "serde_json", "serde_with", "stderrlog", "triomphe", @@ -2034,9 +2036,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", diff --git a/MODULE.bazel b/MODULE.bazel index 13c801520b0..311d0908832 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -68,7 +68,7 @@ use_repo(py_deps, "vendor__anyhow-1.0.44", "vendor__cc-1.0.70", "vendor__clap-2. # deps for ruby+rust # keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh` tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r") -use_repo(tree_sitter_extractors_deps, "vendor__anyhow-1.0.93", "vendor__argfile-0.2.1", "vendor__chrono-0.4.38", "vendor__clap-4.5.20", "vendor__encoding-0.2.33", "vendor__figment-0.10.19", "vendor__flate2-1.0.34", "vendor__glob-0.3.1", "vendor__globset-0.4.15", "vendor__itertools-0.10.5", "vendor__itertools-0.13.0", "vendor__lazy_static-1.5.0", "vendor__log-0.4.22", "vendor__num-traits-0.2.19", "vendor__num_cpus-1.16.0", "vendor__proc-macro2-1.0.89", "vendor__quote-1.0.37", "vendor__ra_ap_base_db-0.0.232", "vendor__ra_ap_cfg-0.0.232", "vendor__ra_ap_hir-0.0.232", "vendor__ra_ap_hir_def-0.0.232", "vendor__ra_ap_hir_expand-0.0.232", "vendor__ra_ap_ide_db-0.0.232", "vendor__ra_ap_intern-0.0.232", "vendor__ra_ap_load-cargo-0.0.232", "vendor__ra_ap_parser-0.0.232", "vendor__ra_ap_paths-0.0.232", "vendor__ra_ap_project_model-0.0.232", "vendor__ra_ap_span-0.0.232", "vendor__ra_ap_syntax-0.0.232", "vendor__ra_ap_vfs-0.0.232", "vendor__rand-0.8.5", "vendor__rayon-1.10.0", "vendor__regex-1.11.1", "vendor__serde-1.0.214", "vendor__serde_json-1.0.132", "vendor__serde_with-3.11.0", "vendor__stderrlog-0.6.0", "vendor__syn-2.0.87", "vendor__tracing-0.1.40", "vendor__tracing-subscriber-0.3.18", "vendor__tree-sitter-0.24.4", "vendor__tree-sitter-embedded-template-0.23.2", "vendor__tree-sitter-json-0.24.8", "vendor__tree-sitter-ql-0.23.1", "vendor__tree-sitter-ruby-0.23.1", "vendor__triomphe-0.1.14", "vendor__ungrammar-1.16.1") +use_repo(tree_sitter_extractors_deps, "vendor__anyhow-1.0.93", "vendor__argfile-0.2.1", "vendor__chrono-0.4.38", "vendor__clap-4.5.20", "vendor__encoding-0.2.33", "vendor__figment-0.10.19", "vendor__flate2-1.0.34", "vendor__glob-0.3.1", "vendor__globset-0.4.15", "vendor__itertools-0.10.5", "vendor__itertools-0.13.0", "vendor__lazy_static-1.5.0", "vendor__log-0.4.22", "vendor__num-traits-0.2.19", "vendor__num_cpus-1.16.0", "vendor__proc-macro2-1.0.89", "vendor__quote-1.0.37", "vendor__ra_ap_base_db-0.0.232", "vendor__ra_ap_cfg-0.0.232", "vendor__ra_ap_hir-0.0.232", "vendor__ra_ap_hir_def-0.0.232", "vendor__ra_ap_hir_expand-0.0.232", "vendor__ra_ap_ide_db-0.0.232", "vendor__ra_ap_intern-0.0.232", "vendor__ra_ap_load-cargo-0.0.232", "vendor__ra_ap_parser-0.0.232", "vendor__ra_ap_paths-0.0.232", "vendor__ra_ap_project_model-0.0.232", "vendor__ra_ap_span-0.0.232", "vendor__ra_ap_syntax-0.0.232", "vendor__ra_ap_vfs-0.0.232", "vendor__rand-0.8.5", "vendor__rayon-1.10.0", "vendor__regex-1.11.1", "vendor__serde-1.0.214", "vendor__serde_json-1.0.133", "vendor__serde_with-3.11.0", "vendor__stderrlog-0.6.0", "vendor__syn-2.0.87", "vendor__tracing-0.1.40", "vendor__tracing-subscriber-0.3.18", "vendor__tree-sitter-0.24.4", "vendor__tree-sitter-embedded-template-0.23.2", "vendor__tree-sitter-json-0.24.8", "vendor__tree-sitter-ql-0.23.1", "vendor__tree-sitter-ruby-0.23.1", "vendor__triomphe-0.1.14", "vendor__ungrammar-1.16.1") dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet") dotnet.toolchain(dotnet_version = "9.0.100") diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel index 844d385f8a4..6208d66c5d9 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel @@ -243,7 +243,7 @@ alias( alias( name = "serde_json", - actual = "@vendor__serde_json-1.0.132//:serde_json", + actual = "@vendor__serde_json-1.0.133//:serde_json", tags = ["manual"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel index e31c61cfac7..9ad331aa5f7 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cargo_metadata-0.18.1.bazel @@ -86,7 +86,7 @@ rust_library( "@vendor__cargo-platform-0.1.8//:cargo_platform", "@vendor__semver-1.0.23//:semver", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:serde_json", + "@vendor__serde_json-1.0.133//:serde_json", "@vendor__thiserror-1.0.69//:thiserror", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel index d1f5d480d71..fa3b71f570c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_proc_macro_api-0.0.232.bazel @@ -96,7 +96,7 @@ rust_library( "@vendor__ra_ap_tt-0.0.232//:ra_ap_tt", "@vendor__rustc-hash-1.1.0//:rustc_hash", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:serde_json", + "@vendor__serde_json-1.0.133//:serde_json", "@vendor__tracing-0.1.40//:tracing", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel index 6f6f3bb303a..5608e6dd6b0 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.ra_ap_project_model-0.0.232.bazel @@ -102,7 +102,7 @@ rust_library( "@vendor__rustc-hash-1.1.0//:rustc_hash", "@vendor__semver-1.0.23//:semver", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:serde_json", + "@vendor__serde_json-1.0.133//:serde_json", "@vendor__tracing-0.1.40//:tracing", "@vendor__triomphe-0.1.14//:triomphe", ], diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.132.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.133.bazel similarity index 97% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.132.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.133.bazel index ecbae32eeaf..710772e4f37 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.132.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.serde_json-1.0.133.bazel @@ -83,13 +83,13 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-none": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.0.132", + version = "1.0.133", deps = [ "@vendor__itoa-1.0.11//:itoa", "@vendor__memchr-2.7.4//:memchr", "@vendor__ryu-1.0.18//:ryu", "@vendor__serde-1.0.214//:serde", - "@vendor__serde_json-1.0.132//:build_script_build", + "@vendor__serde_json-1.0.133//:build_script_build", ], ) @@ -143,7 +143,7 @@ cargo_build_script( "noclippy", "norustfmt", ], - version = "1.0.132", + version = "1.0.133", visibility = ["//visibility:private"], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl index 1d0b825c235..927736b56b2 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl @@ -320,6 +320,7 @@ _NORMAL_DEPENDENCIES = { _COMMON_CONDITION: { "anyhow": Label("@vendor__anyhow-1.0.93//:anyhow"), "argfile": Label("@vendor__argfile-0.2.1//:argfile"), + "chrono": Label("@vendor__chrono-0.4.38//:chrono"), "clap": Label("@vendor__clap-4.5.20//:clap"), "figment": Label("@vendor__figment-0.10.19//:figment"), "glob": Label("@vendor__glob-0.3.1//:glob"), @@ -341,6 +342,7 @@ _NORMAL_DEPENDENCIES = { "ra_ap_syntax": Label("@vendor__ra_ap_syntax-0.0.232//:ra_ap_syntax"), "ra_ap_vfs": Label("@vendor__ra_ap_vfs-0.0.232//:ra_ap_vfs"), "serde": Label("@vendor__serde-1.0.214//:serde"), + "serde_json": Label("@vendor__serde_json-1.0.133//:serde_json"), "serde_with": Label("@vendor__serde_with-3.11.0//:serde_with"), "stderrlog": Label("@vendor__stderrlog-0.6.0//:stderrlog"), "triomphe": Label("@vendor__triomphe-0.1.14//:triomphe"), @@ -363,7 +365,7 @@ _NORMAL_DEPENDENCIES = { "rayon": Label("@vendor__rayon-1.10.0//:rayon"), "regex": Label("@vendor__regex-1.11.1//:regex"), "serde": Label("@vendor__serde-1.0.214//:serde"), - "serde_json": Label("@vendor__serde_json-1.0.132//:serde_json"), + "serde_json": Label("@vendor__serde_json-1.0.133//:serde_json"), "tracing": Label("@vendor__tracing-0.1.40//:tracing"), "tracing-subscriber": Label("@vendor__tracing-subscriber-0.3.18//:tracing_subscriber"), "tree-sitter": Label("@vendor__tree-sitter-0.24.4//:tree_sitter"), @@ -2508,12 +2510,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor__serde_json-1.0.132", - sha256 = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03", + name = "vendor__serde_json-1.0.133", + sha256 = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377", type = "tar.gz", - urls = ["https://static.crates.io/crates/serde_json/1.0.132/download"], - strip_prefix = "serde_json-1.0.132", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_json-1.0.132.bazel"), + urls = ["https://static.crates.io/crates/serde_json/1.0.133/download"], + strip_prefix = "serde_json-1.0.133", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.serde_json-1.0.133.bazel"), ) maybe( @@ -3341,7 +3343,7 @@ def crate_repositories(): struct(repo = "vendor__rayon-1.10.0", is_dev_dep = False), struct(repo = "vendor__regex-1.11.1", is_dev_dep = False), struct(repo = "vendor__serde-1.0.214", is_dev_dep = False), - struct(repo = "vendor__serde_json-1.0.132", is_dev_dep = False), + struct(repo = "vendor__serde_json-1.0.133", is_dev_dep = False), struct(repo = "vendor__serde_with-3.11.0", is_dev_dep = False), struct(repo = "vendor__stderrlog-0.6.0", is_dev_dep = False), struct(repo = "vendor__syn-2.0.87", is_dev_dep = False), diff --git a/rust/extractor/Cargo.toml b/rust/extractor/Cargo.toml index 8b58898d3cf..591df3480cd 100644 --- a/rust/extractor/Cargo.toml +++ b/rust/extractor/Cargo.toml @@ -33,3 +33,5 @@ codeql-extractor = { path = "../../shared/tree-sitter-extractor" } rust-extractor-macros = { path = "macros" } itertools = "0.13.0" glob = "0.3.1" +chrono = { version = "0.4.38", features = ["serde"] } +serde_json = "1.0.133" diff --git a/rust/extractor/src/config.rs b/rust/extractor/src/config.rs index 70c390b9949..0e92e82a58c 100644 --- a/rust/extractor/src/config.rs +++ b/rust/extractor/src/config.rs @@ -45,6 +45,7 @@ pub struct Config { pub scratch_dir: PathBuf, pub trap_dir: PathBuf, pub source_archive_dir: PathBuf, + pub diagnostic_dir: PathBuf, pub cargo_target_dir: Option, pub cargo_target: Option, pub cargo_features: Vec, diff --git a/rust/extractor/src/diagnostics.rs b/rust/extractor/src/diagnostics.rs new file mode 100644 index 00000000000..21b3619a207 --- /dev/null +++ b/rust/extractor/src/diagnostics.rs @@ -0,0 +1,258 @@ +use crate::config::Config; +use anyhow::Context; +use chrono::{DateTime, Utc}; +use log::{debug, info}; +use ra_ap_project_model::ProjectManifest; +use serde::Serialize; +use std::fmt::Display; +use std::fs::File; +use std::path::{Path, PathBuf}; +use std::time::Instant; + +#[derive(Default, Debug, Clone, Copy, Serialize)] +#[serde(rename_all = "camelCase")] +#[allow(dead_code)] +enum Severity { + #[default] + Note, + Warning, + Error, +} + +#[derive(Default, Debug, Clone, Copy, Serialize)] +#[serde(rename_all = "camelCase")] +struct Visibility { + status_page: bool, + cli_summary_table: bool, + telemetry: bool, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +#[allow(dead_code)] +enum Message { + TextMessage(String), + MarkdownMessage(String), +} + +impl Default for Message { + fn default() -> Self { + Message::TextMessage("".to_string()) + } +} + +#[derive(Default, Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct Source { + id: String, + name: String, + extractor_name: String, +} + +#[derive(Default, Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct Location { + file: PathBuf, + start_line: u32, + start_column: u32, + end_line: u32, + end_column: u32, +} + +#[derive(Default, Debug, Clone, Serialize)] +pub struct Diagnostics { + source: Source, + visibility: Visibility, + severity: Severity, + #[serde(flatten)] + message: Message, + timestamp: DateTime, + #[serde(skip_serializing_if = "Option::is_none")] + location: Option, + attributes: T, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +enum ExtractionStepTarget { + LoadManifest(PathBuf), + FetchFile(PathBuf), + Parse(PathBuf), + Extract(PathBuf), +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ExtractionStep { + #[serde(flatten)] + target: ExtractionStepTarget, + ms: u128, +} + +impl ExtractionStep { + fn new(start: Instant, target: ExtractionStepTarget) -> Self { + let ret = ExtractionStep { + target, + ms: start.elapsed().as_millis(), + }; + debug!("{ret:?}"); + ret + } + + pub fn load_manifest(start: Instant, target: &ProjectManifest) -> Self { + Self::new( + start, + ExtractionStepTarget::LoadManifest(PathBuf::from(target.manifest_path())), + ) + } + + pub fn parse(start: Instant, target: &Path) -> Self { + Self::new(start, ExtractionStepTarget::Parse(PathBuf::from(target))) + } + + pub fn extract(start: Instant, target: &Path) -> Self { + Self::new(start, ExtractionStepTarget::Extract(PathBuf::from(target))) + } + + pub fn fetch_file(start: Instant, target: &Path) -> Self { + Self::new( + start, + ExtractionStepTarget::FetchFile(PathBuf::from(target)), + ) + } +} + +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct HumanReadableDuration { + ms: u128, + pretty: String, +} + +impl HumanReadableDuration { + pub fn new(ms: u128) -> Self { + let seconds = ms / 1000; + let minutes = seconds / 60; + let hours = minutes / 60; + let pretty = format!( + "{hours}:{minutes:02}:{seconds:02}.{milliseconds:03}", + minutes = minutes % 60, + seconds = seconds % 60, + milliseconds = ms % 1000, + ); + Self { ms, pretty } + } +} + +impl From for HumanReadableDuration { + fn from(val: u128) -> Self { + HumanReadableDuration::new(val) + } +} + +impl Display for HumanReadableDuration { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}ms ({})", self.ms, self.pretty) + } +} + +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct ExtractionSummary { + number_of_manifests: usize, + number_of_files: usize, + total_load_duration: HumanReadableDuration, + total_fetch_file_duration: HumanReadableDuration, + total_parse_duration: HumanReadableDuration, + total_extract_duration: HumanReadableDuration, + total_duration: HumanReadableDuration, +} + +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct ExtractionAttributes { + steps: Vec, + summary: ExtractionSummary, +} + +type ExtractionDiagnostics = Diagnostics; + +fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { + let mut number_of_manifests = 0; + let mut number_of_files = 0; + let mut total_load_duration = 0; + let mut total_parse_duration = 0; + let mut total_extract_duration = 0; + let mut total_fetch_file_duration: u128 = 0; + for step in steps { + match &step.target { + ExtractionStepTarget::LoadManifest(_) => { + number_of_manifests += 1; + total_load_duration += step.ms; + } + ExtractionStepTarget::FetchFile(_) => { + number_of_files += 1; + total_fetch_file_duration += step.ms; + } + ExtractionStepTarget::Parse(_) => { + total_parse_duration += step.ms; + } + ExtractionStepTarget::Extract(_) => { + total_extract_duration += step.ms; + } + } + } + let ret = ExtractionSummary { + number_of_manifests, + number_of_files, + total_load_duration: total_load_duration.into(), + total_fetch_file_duration: total_fetch_file_duration.into(), + total_parse_duration: total_parse_duration.into(), + total_extract_duration: total_extract_duration.into(), + total_duration: start.elapsed().as_millis().into(), + }; + info!("total loadimg duration: {}", ret.total_load_duration); + info!( + "total file fetching duration: {}", + ret.total_fetch_file_duration + ); + info!("total parsing duration: {}", ret.total_parse_duration); + info!("total extracting duration: {}", ret.total_extract_duration); + info!("total duration: {}", ret.total_duration); + ret +} + +pub fn emit_extraction_diagnostics( + start: Instant, + config: &Config, + steps: Vec, +) -> anyhow::Result<()> { + let summary = summary(start, &steps); + let diagnostics = ExtractionDiagnostics { + source: Source { + id: "rust/extractor/telemetry".to_owned(), + name: "telemetry".to_string(), + extractor_name: "rust".to_string(), + }, + visibility: Visibility { + telemetry: true, + ..Default::default() + }, + timestamp: Utc::now(), + attributes: ExtractionAttributes { steps, summary }, + ..Default::default() + }; + + std::fs::create_dir_all(&config.diagnostic_dir).with_context(|| { + format!( + "creating diagnostics directory {}", + config.diagnostic_dir.display() + ) + })?; + let target = config.diagnostic_dir.join("extraction.jsonc"); + let mut output = File::create(&target) + .with_context(|| format!("creating diagnostics file {}", target.display()))?; + serde_json::to_writer_pretty(&mut output, &diagnostics) + .with_context(|| format!("writing to diagnostics file {}", target.display()))?; + Ok(()) +} diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index ecbdc965f8e..f00e94e9ba4 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -1,3 +1,4 @@ +use crate::diagnostics::{emit_extraction_diagnostics, ExtractionStep}; use crate::rust_analyzer::path_to_file_id; use anyhow::Context; use archive::Archiver; @@ -5,9 +6,10 @@ use log::info; use ra_ap_hir::Semantics; use ra_ap_ide_db::line_index::{LineCol, LineIndex}; use ra_ap_ide_db::RootDatabase; -use ra_ap_project_model::ProjectManifest; +use ra_ap_project_model::{CargoConfig, ProjectManifest}; use ra_ap_vfs::Vfs; use rust_analyzer::{ParseResult, RustAnalyzer}; +use std::time::Instant; use std::{ collections::HashMap, path::{Path, PathBuf}, @@ -15,6 +17,7 @@ use std::{ mod archive; mod config; +mod diagnostics; pub mod generated; mod qltest; mod rust_analyzer; @@ -24,18 +27,31 @@ pub mod trap; struct Extractor<'a> { archiver: &'a Archiver, traps: &'a trap::TrapFileProvider, + steps: Vec, } -impl Extractor<'_> { - fn extract(&self, rust_analyzer: &rust_analyzer::RustAnalyzer, file: &std::path::Path) { +impl<'a> Extractor<'a> { + pub fn new(archiver: &'a Archiver, traps: &'a trap::TrapFileProvider) -> Self { + Self { + archiver, + traps, + steps: Vec::new(), + } + } + + fn extract(&mut self, rust_analyzer: &rust_analyzer::RustAnalyzer, file: &std::path::Path) { self.archiver.archive(file); + let before_parse = Instant::now(); let ParseResult { ast, text, errors, semantics_info, } = rust_analyzer.parse(file); + self.steps.push(ExtractionStep::parse(before_parse, file)); + + let before_extract = Instant::now(); let line_index = LineIndex::new(text.as_ref()); let display_path = file.to_string_lossy(); let mut trap = self.traps.create("source", file); @@ -73,22 +89,63 @@ impl Extractor<'_> { err.to_string() ) }); + self.steps + .push(ExtractionStep::extract(before_extract, file)); } pub fn extract_with_semantics( - &self, + &mut self, file: &Path, semantics: &Semantics<'_, RootDatabase>, vfs: &Vfs, ) { self.extract(&RustAnalyzer::new(vfs, semantics), file); } - pub fn extract_without_semantics(&self, file: &Path, reason: &str) { + + pub fn extract_without_semantics(&mut self, file: &Path, reason: &str) { self.extract(&RustAnalyzer::WithoutSemantics { reason }, file); } + + pub fn load_manifest( + &mut self, + project: &ProjectManifest, + config: &CargoConfig, + ) -> Option<(RootDatabase, Vfs)> { + let before = Instant::now(); + let ret = RustAnalyzer::load_workspace(project, config); + self.steps + .push(ExtractionStep::load_manifest(before, project)); + ret + } + + pub fn fetch_file( + &mut self, + file: &Path, + semantics: &Semantics<'_, RootDatabase>, + vfs: &Vfs, + ) -> Result<(), String> { + let before = Instant::now(); + let Some(id) = path_to_file_id(file, vfs) else { + return Err("not included in files loaded from manifest".to_string()); + }; + if semantics.file_to_module_def(id).is_none() { + return Err("not included as a module".to_string()); + } + self.steps.push(ExtractionStep::fetch_file(before, file)); + Ok(()) + } + + pub fn emit_extraction_diagnostics( + self, + start: Instant, + cfg: &config::Config, + ) -> anyhow::Result<()> { + emit_extraction_diagnostics(start, cfg, self.steps) + } } fn main() -> anyhow::Result<()> { + let start = Instant::now(); let mut cfg = config::Config::extract().context("failed to load configuration")?; stderrlog::new() .module(module_path!()) @@ -103,10 +160,7 @@ fn main() -> anyhow::Result<()> { let archiver = archive::Archiver { root: cfg.source_archive_dir.clone(), }; - let extractor = Extractor { - archiver: &archiver, - traps: &traps, - }; + let mut extractor = Extractor::new(&archiver, &traps); let files: Vec = cfg .inputs .iter() @@ -132,21 +186,13 @@ fn main() -> anyhow::Result<()> { } let cargo_config = cfg.to_cargo_config(); for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) { - if let Some((ref db, ref vfs)) = RustAnalyzer::load_workspace(manifest, &cargo_config) { + if let Some((ref db, ref vfs)) = extractor.load_manifest(manifest, &cargo_config) { let semantics = Semantics::new(db); for file in files { - let Some(id) = path_to_file_id(file, vfs) else { - extractor.extract_without_semantics( - file, - "not included in files loaded from manifest", - ); - continue; + match extractor.fetch_file(file, &semantics, vfs) { + Ok(()) => extractor.extract_with_semantics(file, &semantics, vfs), + Err(reason) => extractor.extract_without_semantics(file, &reason), }; - if semantics.file_to_module_def(id).is_none() { - extractor.extract_without_semantics(file, "not included as a module"); - continue; - } - extractor.extract_with_semantics(file, &semantics, vfs); } } else { for file in files { @@ -155,5 +201,5 @@ fn main() -> anyhow::Result<()> { } } - Ok(()) + extractor.emit_extraction_diagnostics(start, &cfg) } diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 08b17f106f8..9967339f2d2 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -13,3 +13,12 @@ class _Manifests: @pytest.fixture def manifests(cwd): return _Manifests(cwd) + +@pytest.fixture +def rust_check_diagnostics(check_diagnostics): + check_diagnostics.replacements += [ + (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), + (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), + (r'Cargo.toml|rust-project.json', ""), + ] + return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected new file mode 100644 index 00000000000..165fd263990 --- /dev/null +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -0,0 +1,101 @@ +{ + "attributes": { + "steps": [ + { + "loadManifest": "/", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/directory_module/mod.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/directory_module/mod.rs" + }, + { + "extract": "/src/directory_module/mod.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/directory_module/nested_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/directory_module/nested_module.rs" + }, + { + "extract": "/src/directory_module/nested_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/directory_module/not_loaded.rs" + }, + { + "extract": "/src/directory_module/not_loaded.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/file_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/file_module.rs" + }, + { + "extract": "/src/file_module.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/src/main.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/src/main.rs" + }, + { + "extract": "/src/main.rs", + "ms": "REDACTED" + } + ], + "summary": { + "numberOfFiles": 4, + "numberOfManifests": 1, + "totalDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalExtractDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalFetchFileDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalLoadDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalParseDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + } + } + }, + "severity": "note", + "source": { + "extractorName": "rust", + "id": "rust/extractor/telemetry", + "name": "telemetry" + }, + "visibility": { + "cliSummaryTable": false, + "statusPage": false, + "telemetry": true + } +} diff --git a/rust/ql/integration-tests/hello-project/test_project.py b/rust/ql/integration-tests/hello-project/test_project.py index d03c4f67e26..2cbac0ffdb8 100644 --- a/rust/ql/integration-tests/hello-project/test_project.py +++ b/rust/ql/integration-tests/hello-project/test_project.py @@ -1,7 +1,7 @@ -def test_cargo(codeql, rust, manifests, check_source_archive): +def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("Cargo.toml") codeql.database.create() -def test_rust_project(codeql, rust, manifests, check_source_archive): +def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("rust-project.json") codeql.database.create() diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected new file mode 100644 index 00000000000..42e7859a4e8 --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -0,0 +1,97 @@ +{ + "attributes": { + "steps": [ + { + "loadManifest": "/lib/", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/a_module/mod.rs" + }, + { + "extract": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/lib.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/lib.rs" + }, + { + "extract": "/lib/src/lib.rs", + "ms": "REDACTED" + }, + { + "loadManifest": "/exe/", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/a_module.rs" + }, + { + "extract": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/main.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/main.rs" + }, + { + "extract": "/exe/src/main.rs", + "ms": "REDACTED" + } + ], + "summary": { + "numberOfFiles": 4, + "numberOfManifests": 2, + "totalDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalExtractDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalFetchFileDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalLoadDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalParseDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + } + } + }, + "severity": "note", + "source": { + "extractorName": "rust", + "id": "rust/extractor/telemetry", + "name": "telemetry" + }, + "visibility": { + "cliSummaryTable": false, + "statusPage": false, + "telemetry": true + } +} diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected new file mode 100644 index 00000000000..7df7b52cdee --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -0,0 +1,93 @@ +{ + "attributes": { + "steps": [ + { + "loadManifest": "/", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/a_module.rs" + }, + { + "extract": "/exe/src/a_module.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/exe/src/main.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/exe/src/main.rs" + }, + { + "extract": "/exe/src/main.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/a_module/mod.rs" + }, + { + "extract": "/lib/src/a_module/mod.rs", + "ms": "REDACTED" + }, + { + "fetchFile": "/lib/src/lib.rs", + "ms": "REDACTED" + }, + { + "ms": "REDACTED", + "parse": "/lib/src/lib.rs" + }, + { + "extract": "/lib/src/lib.rs", + "ms": "REDACTED" + } + ], + "summary": { + "numberOfFiles": 4, + "numberOfManifests": 1, + "totalDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalExtractDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalFetchFileDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalLoadDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + }, + "totalParseDuration": { + "ms": "REDACTED", + "pretty": "REDACTED" + } + } + }, + "severity": "note", + "source": { + "extractorName": "rust", + "id": "rust/extractor/telemetry", + "name": "telemetry" + }, + "visibility": { + "cliSummaryTable": false, + "statusPage": false, + "telemetry": true + } +} diff --git a/rust/ql/integration-tests/hello-workspace/test_workspace.py b/rust/ql/integration-tests/hello-workspace/test_workspace.py index f3503e7cefa..5c95031466f 100644 --- a/rust/ql/integration-tests/hello-workspace/test_workspace.py +++ b/rust/ql/integration-tests/hello-workspace/test_workspace.py @@ -3,10 +3,12 @@ import pytest # currently the DB-check fails on actions because of loading files multiple times and assiging multiple locations # see https://github.com/github/codeql-team/issues/3365 @pytest.mark.ql_test("DB-CHECK", xfail="maybe") -def test_cargo(codeql, rust, manifests, check_source_archive): +def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): + rust_check_diagnostics.expected_suffix = ".cargo.expected" manifests.select("Cargo.toml") codeql.database.create() -def test_rust_project(codeql, rust, manifests, check_source_archive): +def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): + rust_check_diagnostics.expected_suffix = ".rust-project.expected" manifests.select("rust-project.json") codeql.database.create() From 8abd3c4707b527cf70e05f29eea88cb4ca608a2b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 26 Nov 2024 16:48:49 +0100 Subject: [PATCH 18/63] Rust: Remove windows difference from diagnostics --- rust/ql/integration-tests/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 9967339f2d2..13cecd478d7 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -20,5 +20,6 @@ def rust_check_diagnostics(check_diagnostics): (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), (r'Cargo.toml|rust-project.json', ""), + (r'"//\?/', '"'), # remove windows `//?/` long path syntax ] return check_diagnostics From 556774edc7d68546ee41f7738f80f50db4502ce9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 26 Nov 2024 18:00:15 +0100 Subject: [PATCH 19/63] Rust: do not put extraction steps in the expected diagnostics --- rust/ql/integration-tests/conftest.py | 5 +- .../hello-project/diagnostics.expected | 62 ------------------- .../diagnostics.cargo.expected | 58 ----------------- .../diagnostics.rust-project.expected | 54 ---------------- 4 files changed, 3 insertions(+), 176 deletions(-) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 13cecd478d7..f05b1f5c98a 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -19,7 +19,8 @@ def rust_check_diagnostics(check_diagnostics): check_diagnostics.replacements += [ (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), - (r'Cargo.toml|rust-project.json', ""), - (r'"//\?/', '"'), # remove windows `//?/` long path syntax + ] + check_diagnostics.skip += [ + "attributes.steps", # the order of the steps is not stable ] return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index 165fd263990..1c46a0a9f99 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -1,67 +1,5 @@ { "attributes": { - "steps": [ - { - "loadManifest": "/", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/directory_module/mod.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/directory_module/mod.rs" - }, - { - "extract": "/src/directory_module/mod.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/directory_module/nested_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/directory_module/nested_module.rs" - }, - { - "extract": "/src/directory_module/nested_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/directory_module/not_loaded.rs" - }, - { - "extract": "/src/directory_module/not_loaded.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/file_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/file_module.rs" - }, - { - "extract": "/src/file_module.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/src/main.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/src/main.rs" - }, - { - "extract": "/src/main.rs", - "ms": "REDACTED" - } - ], "summary": { "numberOfFiles": 4, "numberOfManifests": 1, diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 42e7859a4e8..48ae4a51e04 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,63 +1,5 @@ { "attributes": { - "steps": [ - { - "loadManifest": "/lib/", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/a_module/mod.rs" - }, - { - "extract": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/lib.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/lib.rs" - }, - { - "extract": "/lib/src/lib.rs", - "ms": "REDACTED" - }, - { - "loadManifest": "/exe/", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/a_module.rs" - }, - { - "extract": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/main.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/main.rs" - }, - { - "extract": "/exe/src/main.rs", - "ms": "REDACTED" - } - ], "summary": { "numberOfFiles": 4, "numberOfManifests": 2, diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 7df7b52cdee..1c46a0a9f99 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,59 +1,5 @@ { "attributes": { - "steps": [ - { - "loadManifest": "/", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/a_module.rs" - }, - { - "extract": "/exe/src/a_module.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/exe/src/main.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/exe/src/main.rs" - }, - { - "extract": "/exe/src/main.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/a_module/mod.rs" - }, - { - "extract": "/lib/src/a_module/mod.rs", - "ms": "REDACTED" - }, - { - "fetchFile": "/lib/src/lib.rs", - "ms": "REDACTED" - }, - { - "ms": "REDACTED", - "parse": "/lib/src/lib.rs" - }, - { - "extract": "/lib/src/lib.rs", - "ms": "REDACTED" - } - ], "summary": { "numberOfFiles": 4, "numberOfManifests": 1, From 27738eaaccc54b1ef19e62a3cc6de23eb166cb03 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 27 Nov 2024 12:03:32 +0100 Subject: [PATCH 20/63] Rust: reorganize perf diagnostics --- rust/extractor/src/diagnostics.rs | 146 +++++++++--------- rust/extractor/src/main.rs | 6 +- rust/ql/integration-tests/conftest.py | 4 +- .../hello-project/diagnostics.expected | 20 +-- .../diagnostics.cargo.expected | 44 +++--- .../diagnostics.rust-project.expected | 44 +++--- 6 files changed, 136 insertions(+), 128 deletions(-) diff --git a/rust/extractor/src/diagnostics.rs b/rust/extractor/src/diagnostics.rs index 21b3619a207..d4b60211bbf 100644 --- a/rust/extractor/src/diagnostics.rs +++ b/rust/extractor/src/diagnostics.rs @@ -3,7 +3,9 @@ use anyhow::Context; use chrono::{DateTime, Utc}; use log::{debug, info}; use ra_ap_project_model::ProjectManifest; +use serde::ser::SerializeMap; use serde::Serialize; +use std::collections::HashMap; use std::fmt::Display; use std::fs::File; use std::path::{Path, PathBuf}; @@ -72,27 +74,29 @@ pub struct Diagnostics { attributes: T, } -#[derive(Debug, Clone, Serialize)] +#[derive(Default, Debug, Clone, Copy, Serialize, PartialEq, Eq, Hash)] #[serde(rename_all = "camelCase")] -enum ExtractionStepTarget { - LoadManifest(PathBuf), - FetchFile(PathBuf), - Parse(PathBuf), - Extract(PathBuf), +enum ExtractionStepKind { + #[default] + LoadManifest, + LoadSource, + Parse, + Extract, } #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct ExtractionStep { - #[serde(flatten)] - target: ExtractionStepTarget, + action: ExtractionStepKind, + file: PathBuf, ms: u128, } impl ExtractionStep { - fn new(start: Instant, target: ExtractionStepTarget) -> Self { + fn new(start: Instant, action: ExtractionStepKind, file: PathBuf) -> Self { let ret = ExtractionStep { - target, + action, + file, ms: start.elapsed().as_millis(), }; debug!("{ret:?}"); @@ -102,70 +106,84 @@ impl ExtractionStep { pub fn load_manifest(start: Instant, target: &ProjectManifest) -> Self { Self::new( start, - ExtractionStepTarget::LoadManifest(PathBuf::from(target.manifest_path())), + ExtractionStepKind::LoadManifest, + PathBuf::from(target.manifest_path()), ) } pub fn parse(start: Instant, target: &Path) -> Self { - Self::new(start, ExtractionStepTarget::Parse(PathBuf::from(target))) + Self::new(start, ExtractionStepKind::Parse, PathBuf::from(target)) } pub fn extract(start: Instant, target: &Path) -> Self { - Self::new(start, ExtractionStepTarget::Extract(PathBuf::from(target))) + Self::new(start, ExtractionStepKind::Extract, PathBuf::from(target)) } - pub fn fetch_file(start: Instant, target: &Path) -> Self { - Self::new( - start, - ExtractionStepTarget::FetchFile(PathBuf::from(target)), - ) + pub fn load_source(start: Instant, target: &Path) -> Self { + Self::new(start, ExtractionStepKind::LoadSource, PathBuf::from(target)) } } -#[derive(Debug, Default, Clone, Serialize)] -#[serde(rename_all = "camelCase")] -struct HumanReadableDuration { - ms: u128, - pretty: String, +#[derive(Debug, Default, Clone)] +struct HumanReadableDuration(u128); + +impl Serialize for HumanReadableDuration { + fn serialize(&self, serializer: S) -> Result { + let mut map = serializer.serialize_map(Some(2))?; + map.serialize_entry("ms", &self.0)?; + map.serialize_entry("pretty", &self.pretty())?; + map.end() + } } impl HumanReadableDuration { - pub fn new(ms: u128) -> Self { - let seconds = ms / 1000; - let minutes = seconds / 60; + pub fn add(&mut self, other: u128) { + self.0 += other; + } + + pub fn pretty(&self) -> String { + let milliseconds = self.0 % 1000; + let mut seconds = self.0 / 1000; + if seconds < 60 { + return format!("{seconds}.{milliseconds:03}s"); + } + let mut minutes = seconds / 60; + seconds %= 60; + if minutes < 60 { + return format!("{minutes}min{seconds:02}.{milliseconds:03}s"); + } let hours = minutes / 60; - let pretty = format!( - "{hours}:{minutes:02}:{seconds:02}.{milliseconds:03}", - minutes = minutes % 60, - seconds = seconds % 60, - milliseconds = ms % 1000, - ); - Self { ms, pretty } + minutes %= 60; + format!("{hours}h{minutes:02}min{seconds:02}.{milliseconds:03}s") } } impl From for HumanReadableDuration { fn from(val: u128) -> Self { - HumanReadableDuration::new(val) + HumanReadableDuration(val) } } impl Display for HumanReadableDuration { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}ms ({})", self.ms, self.pretty) + f.write_str(&self.pretty()) } } +#[derive(Debug, Default, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct DurationsSummary { + #[serde(flatten)] + durations: HashMap, + total: HumanReadableDuration, +} + #[derive(Debug, Default, Clone, Serialize)] #[serde(rename_all = "camelCase")] struct ExtractionSummary { number_of_manifests: usize, number_of_files: usize, - total_load_duration: HumanReadableDuration, - total_fetch_file_duration: HumanReadableDuration, - total_parse_duration: HumanReadableDuration, - total_extract_duration: HumanReadableDuration, - total_duration: HumanReadableDuration, + durations: DurationsSummary, } #[derive(Debug, Default, Clone, Serialize)] @@ -180,46 +198,32 @@ type ExtractionDiagnostics = Diagnostics; fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { let mut number_of_manifests = 0; let mut number_of_files = 0; - let mut total_load_duration = 0; - let mut total_parse_duration = 0; - let mut total_extract_duration = 0; - let mut total_fetch_file_duration: u128 = 0; + let mut durations = HashMap::new(); for step in steps { - match &step.target { - ExtractionStepTarget::LoadManifest(_) => { + match &step.action { + ExtractionStepKind::LoadManifest => { number_of_manifests += 1; - total_load_duration += step.ms; } - ExtractionStepTarget::FetchFile(_) => { + ExtractionStepKind::Parse => { number_of_files += 1; - total_fetch_file_duration += step.ms; - } - ExtractionStepTarget::Parse(_) => { - total_parse_duration += step.ms; - } - ExtractionStepTarget::Extract(_) => { - total_extract_duration += step.ms; } + _ => {} } + durations + .entry(step.action) + .or_insert(HumanReadableDuration(0)) + .add(step.ms); } - let ret = ExtractionSummary { + let total = start.elapsed().as_millis().into(); + for (key, value) in &durations { + info!("total duration ({key:?}): {value}"); + } + info!("total duration: {total}"); + ExtractionSummary { number_of_manifests, number_of_files, - total_load_duration: total_load_duration.into(), - total_fetch_file_duration: total_fetch_file_duration.into(), - total_parse_duration: total_parse_duration.into(), - total_extract_duration: total_extract_duration.into(), - total_duration: start.elapsed().as_millis().into(), - }; - info!("total loadimg duration: {}", ret.total_load_duration); - info!( - "total file fetching duration: {}", - ret.total_fetch_file_duration - ); - info!("total parsing duration: {}", ret.total_parse_duration); - info!("total extracting duration: {}", ret.total_extract_duration); - info!("total duration: {}", ret.total_duration); - ret + durations: DurationsSummary { durations, total }, + } } pub fn emit_extraction_diagnostics( diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index f00e94e9ba4..19239cf9dd4 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -118,7 +118,7 @@ impl<'a> Extractor<'a> { ret } - pub fn fetch_file( + pub fn load_source( &mut self, file: &Path, semantics: &Semantics<'_, RootDatabase>, @@ -131,7 +131,7 @@ impl<'a> Extractor<'a> { if semantics.file_to_module_def(id).is_none() { return Err("not included as a module".to_string()); } - self.steps.push(ExtractionStep::fetch_file(before, file)); + self.steps.push(ExtractionStep::load_source(before, file)); Ok(()) } @@ -189,7 +189,7 @@ fn main() -> anyhow::Result<()> { if let Some((ref db, ref vfs)) = extractor.load_manifest(manifest, &cargo_config) { let semantics = Semantics::new(db); for file in files { - match extractor.fetch_file(file, &semantics, vfs) { + match extractor.load_source(file, &semantics, vfs) { Ok(()) => extractor.extract_with_semantics(file, &semantics, vfs), Err(reason) => extractor.extract_without_semantics(file, &reason), }; diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index f05b1f5c98a..895650183c8 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -17,8 +17,8 @@ def manifests(cwd): @pytest.fixture def rust_check_diagnostics(check_diagnostics): check_diagnostics.replacements += [ - (r'"ms"\s*:\s*[0-9]+', '"ms": "REDACTED"'), - (r'"pretty"\s*:\s*"[0-9]+:[0-9]{2}:[0-9]{2}.[0-9]{3}"', '"pretty": "REDACTED"'), + (r'"ms"\s*:\s*[0-9]+', '"ms": "__REDACTED__"'), + (r'"pretty"\s*:\s*"[^"]*"', '"pretty": "__REDACTED__"'), ] check_diagnostics.skip += [ "attributes.steps", # the order of the steps is not stable diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index 1c46a0a9f99..c19e46a88cd 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -4,24 +4,24 @@ "numberOfFiles": 4, "numberOfManifests": 1, "totalDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalExtractDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalFetchFileDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalLoadDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, "totalParseDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } } }, diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 48ae4a51e04..052fe3e7839 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,28 +1,30 @@ { "attributes": { "summary": { + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + } + }, "numberOfFiles": 4, - "numberOfManifests": 2, - "totalDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalExtractDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalFetchFileDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalLoadDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalParseDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - } + "numberOfManifests": 2 } }, "severity": "note", diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 1c46a0a9f99..3c4fc9bf431 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,28 +1,30 @@ { "attributes": { "summary": { + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + } + }, "numberOfFiles": 4, - "numberOfManifests": 1, - "totalDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalExtractDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalFetchFileDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalLoadDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - }, - "totalParseDuration": { - "ms": "REDACTED", - "pretty": "REDACTED" - } + "numberOfManifests": 1 } }, "severity": "note", From 5251dc2058cb684b617cb0ba72f6531b133f3976 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 27 Nov 2024 10:20:31 +0100 Subject: [PATCH 21/63] Rust: use `check_diagnostics` improvements --- rust/ql/integration-tests/conftest.py | 10 +- .../hello-project/diagnostics.expected | 115 +++++++++++++++--- .../diagnostics.cargo.expected | 72 +++++++++++ .../diagnostics.rust-project.expected | 67 ++++++++++ 4 files changed, 242 insertions(+), 22 deletions(-) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 895650183c8..cbace615805 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -17,10 +17,12 @@ def manifests(cwd): @pytest.fixture def rust_check_diagnostics(check_diagnostics): check_diagnostics.replacements += [ - (r'"ms"\s*:\s*[0-9]+', '"ms": "__REDACTED__"'), - (r'"pretty"\s*:\s*"[^"]*"', '"pretty": "__REDACTED__"'), + ("Cargo.toml|rust-project.json", ""), ] - check_diagnostics.skip += [ - "attributes.steps", # the order of the steps is not stable + check_diagnostics.redact += [ + "attributes.summary.durations.*.ms", + "attributes.summary.durations.*.pretty", + "attributes.steps.ms", ] + check_diagnostics.sort = True # the order of the steps is not stable return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index c19e46a88cd..5f6821ffb10 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -1,28 +1,107 @@ { "attributes": { - "summary": { - "numberOfFiles": 4, - "numberOfManifests": 1, - "totalDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + "steps": [ + { + "action": "extract", + "file": "/src/directory_module/mod.rs", + "ms": "__REDACTED__" }, - "totalExtractDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/directory_module/nested_module.rs", + "ms": "__REDACTED__" }, - "totalFetchFileDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/directory_module/not_loaded.rs", + "ms": "__REDACTED__" }, - "totalLoadDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/file_module.rs", + "ms": "__REDACTED__" }, - "totalParseDuration": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" + { + "action": "extract", + "file": "/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/directory_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/directory_module/nested_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/file_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/directory_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/directory_module/nested_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/directory_module/not_loaded.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/file_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/src/main.rs", + "ms": "__REDACTED__" } + ], + "summary": { + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + }, + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" + } + }, + "numberOfFiles": 5, + "numberOfManifests": 1 } }, "severity": "note", diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 052fe3e7839..7d484623087 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,5 +1,77 @@ { "attributes": { + "steps": [ + { + "action": "extract", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/exe/", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/lib/", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + } + ], "summary": { "durations": { "extract": { diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 3c4fc9bf431..8ab17e9fe73 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,5 +1,72 @@ { "attributes": { + "steps": [ + { + "action": "extract", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "extract", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadManifest", + "file": "/", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "loadSource", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/a_module.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/exe/src/main.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/a_module/mod.rs", + "ms": "__REDACTED__" + }, + { + "action": "parse", + "file": "/lib/src/lib.rs", + "ms": "__REDACTED__" + } + ], "summary": { "durations": { "extract": { From 4e7115538bf8f63788c19694c1ea0b430b4fbe17 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 27 Nov 2024 14:55:46 +0100 Subject: [PATCH 22/63] Rust: move steps breakdown from JSON diagnostics to the DB --- rust/extractor/src/diagnostics.rs | 23 ++-- rust/extractor/src/main.rs | 24 +++- rust/extractor/src/trap.rs | 4 +- rust/prefix.dbscheme | 7 ++ rust/ql/integration-tests/conftest.py | 9 +- .../hello-project/diagnostics.expected | 117 +++--------------- .../hello-project/steps.cargo.expected | 15 +++ .../integration-tests/hello-project/steps.ql | 4 + .../hello-project/steps.rust-project.expected | 15 +++ .../hello-project/test_project.py | 5 + .../diagnostics.cargo.expected | 112 +++-------------- .../diagnostics.rust-project.expected | 107 +++------------- .../hello-workspace/steps.cargo.expected | 14 +++ .../hello-workspace/steps.ql | 4 + .../steps.rust-project.expected | 13 ++ .../hello-workspace/test_workspace.py | 6 +- .../codeql/rust/internal/ExtractorStep.qll | 46 +++++++ rust/ql/lib/rust.dbscheme | 7 ++ 18 files changed, 224 insertions(+), 308 deletions(-) create mode 100644 rust/ql/integration-tests/hello-project/steps.cargo.expected create mode 100644 rust/ql/integration-tests/hello-project/steps.ql create mode 100644 rust/ql/integration-tests/hello-project/steps.rust-project.expected create mode 100644 rust/ql/integration-tests/hello-workspace/steps.cargo.expected create mode 100644 rust/ql/integration-tests/hello-workspace/steps.ql create mode 100644 rust/ql/integration-tests/hello-workspace/steps.rust-project.expected create mode 100644 rust/ql/lib/codeql/rust/internal/ExtractorStep.qll diff --git a/rust/extractor/src/diagnostics.rs b/rust/extractor/src/diagnostics.rs index d4b60211bbf..92743a923d4 100644 --- a/rust/extractor/src/diagnostics.rs +++ b/rust/extractor/src/diagnostics.rs @@ -76,7 +76,7 @@ pub struct Diagnostics { #[derive(Default, Debug, Clone, Copy, Serialize, PartialEq, Eq, Hash)] #[serde(rename_all = "camelCase")] -enum ExtractionStepKind { +pub enum ExtractionStepKind { #[default] LoadManifest, LoadSource, @@ -87,9 +87,9 @@ enum ExtractionStepKind { #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct ExtractionStep { - action: ExtractionStepKind, - file: PathBuf, - ms: u128, + pub action: ExtractionStepKind, + pub file: PathBuf, + pub ms: u128, } impl ExtractionStep { @@ -186,14 +186,7 @@ struct ExtractionSummary { durations: DurationsSummary, } -#[derive(Debug, Default, Clone, Serialize)] -#[serde(rename_all = "camelCase")] -struct ExtractionAttributes { - steps: Vec, - summary: ExtractionSummary, -} - -type ExtractionDiagnostics = Diagnostics; +type ExtractionDiagnostics = Diagnostics; fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { let mut number_of_manifests = 0; @@ -229,9 +222,9 @@ fn summary(start: Instant, steps: &[ExtractionStep]) -> ExtractionSummary { pub fn emit_extraction_diagnostics( start: Instant, config: &Config, - steps: Vec, + steps: &[ExtractionStep], ) -> anyhow::Result<()> { - let summary = summary(start, &steps); + let summary = summary(start, steps); let diagnostics = ExtractionDiagnostics { source: Source { id: "rust/extractor/telemetry".to_owned(), @@ -243,7 +236,7 @@ pub fn emit_extraction_diagnostics( ..Default::default() }, timestamp: Utc::now(), - attributes: ExtractionAttributes { steps, summary }, + attributes: summary, ..Default::default() }; diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index 19239cf9dd4..a3258f16d09 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -2,7 +2,7 @@ use crate::diagnostics::{emit_extraction_diagnostics, ExtractionStep}; use crate::rust_analyzer::path_to_file_id; use anyhow::Context; use archive::Archiver; -use log::info; +use log::{info, warn}; use ra_ap_hir::Semantics; use ra_ap_ide_db::line_index::{LineCol, LineIndex}; use ra_ap_ide_db::RootDatabase; @@ -140,7 +140,27 @@ impl<'a> Extractor<'a> { start: Instant, cfg: &config::Config, ) -> anyhow::Result<()> { - emit_extraction_diagnostics(start, cfg, self.steps) + emit_extraction_diagnostics(start, cfg, &self.steps)?; + let mut trap = self.traps.create("diagnostics", "extraction"); + for step in self.steps { + let file_label = trap.emit_file(&step.file); + let step_label = trap.writer.fresh_id(); + let ms = usize::try_from(step.ms).unwrap_or_else(|_e| { + warn!("extraction step duration overflowed ({step:?})"); + i32::MAX as usize + }); + trap.writer.add_tuple( + "extractor_steps", + vec![ + step_label.into(), + format!("{:?}", step.action).into(), + file_label.into(), + ms.into(), + ], + ); + } + trap.commit()?; + Ok(()) } } diff --git a/rust/extractor/src/trap.rs b/rust/extractor/src/trap.rs index 58f56fb2b1e..c993fa046a7 100644 --- a/rust/extractor/src/trap.rs +++ b/rust/extractor/src/trap.rs @@ -243,8 +243,8 @@ impl TrapFileProvider { }) } - pub fn create(&self, category: &str, key: &Path) -> TrapFile { - let path = file_paths::path_for(&self.trap_dir.join(category), key, "trap"); + pub fn create(&self, category: &str, key: impl AsRef) -> TrapFile { + let path = file_paths::path_for(&self.trap_dir.join(category), key.as_ref(), "trap"); debug!("creating trap file {}", path.display()); let mut writer = trap::Writer::new(); extractor::populate_empty_location(&mut writer); diff --git a/rust/prefix.dbscheme b/rust/prefix.dbscheme index 4810e11069d..5ccbd3438d1 100644 --- a/rust/prefix.dbscheme +++ b/rust/prefix.dbscheme @@ -3,3 +3,10 @@ locatable_locations( int id: @locatable ref, int location: @location_default ref ); + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int file: @file ref, + int duration_ms: int ref +) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index cbace615805..79c899c97fc 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -16,13 +16,8 @@ def manifests(cwd): @pytest.fixture def rust_check_diagnostics(check_diagnostics): - check_diagnostics.replacements += [ - ("Cargo.toml|rust-project.json", ""), - ] check_diagnostics.redact += [ - "attributes.summary.durations.*.ms", - "attributes.summary.durations.*.pretty", - "attributes.steps.ms", + "attributes.durations.*.ms", + "attributes.durations.*.pretty", ] - check_diagnostics.sort = True # the order of the steps is not stable return check_diagnostics diff --git a/rust/ql/integration-tests/hello-project/diagnostics.expected b/rust/ql/integration-tests/hello-project/diagnostics.expected index 5f6821ffb10..f938b5b8ab5 100644 --- a/rust/ql/integration-tests/hello-project/diagnostics.expected +++ b/rust/ql/integration-tests/hello-project/diagnostics.expected @@ -1,108 +1,29 @@ { "attributes": { - "steps": [ - { - "action": "extract", - "file": "/src/directory_module/mod.rs", - "ms": "__REDACTED__" + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/directory_module/nested_module.rs", - "ms": "__REDACTED__" + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/directory_module/not_loaded.rs", - "ms": "__REDACTED__" + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/file_module.rs", - "ms": "__REDACTED__" + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadManifest", - "file": "/", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/directory_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/directory_module/nested_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/file_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/directory_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/directory_module/nested_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/directory_module/not_loaded.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/file_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/src/main.rs", - "ms": "__REDACTED__" + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } - ], - "summary": { - "durations": { - "extract": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadManifest": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadSource": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "parse": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "total": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - } - }, - "numberOfFiles": 5, - "numberOfManifests": 1 - } + }, + "numberOfFiles": 5, + "numberOfManifests": 1 }, "severity": "note", "source": { diff --git a/rust/ql/integration-tests/hello-project/steps.cargo.expected b/rust/ql/integration-tests/hello-project/steps.cargo.expected new file mode 100644 index 00000000000..61987aa564b --- /dev/null +++ b/rust/ql/integration-tests/hello-project/steps.cargo.expected @@ -0,0 +1,15 @@ +| Cargo.toml:0:0:0:0 | LoadManifest(Cargo.toml) | +| src/directory_module/mod.rs:0:0:0:0 | Extract(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | LoadSource(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | Parse(src/directory_module/mod.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Extract(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | LoadSource(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Parse(src/directory_module/nested_module.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Extract(src/directory_module/not_loaded.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Parse(src/directory_module/not_loaded.rs) | +| src/file_module.rs:0:0:0:0 | Extract(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | LoadSource(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | Parse(src/file_module.rs) | +| src/main.rs:0:0:0:0 | Extract(src/main.rs) | +| src/main.rs:0:0:0:0 | LoadSource(src/main.rs) | +| src/main.rs:0:0:0:0 | Parse(src/main.rs) | diff --git a/rust/ql/integration-tests/hello-project/steps.ql b/rust/ql/integration-tests/hello-project/steps.ql new file mode 100644 index 00000000000..eb8f9a05adb --- /dev/null +++ b/rust/ql/integration-tests/hello-project/steps.ql @@ -0,0 +1,4 @@ +import codeql.rust.internal.ExtractorStep + +from ExtractorStep step +select step diff --git a/rust/ql/integration-tests/hello-project/steps.rust-project.expected b/rust/ql/integration-tests/hello-project/steps.rust-project.expected new file mode 100644 index 00000000000..d1d2e9ddee3 --- /dev/null +++ b/rust/ql/integration-tests/hello-project/steps.rust-project.expected @@ -0,0 +1,15 @@ +| rust-project.json:0:0:0:0 | LoadManifest(rust-project.json) | +| src/directory_module/mod.rs:0:0:0:0 | Extract(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | LoadSource(src/directory_module/mod.rs) | +| src/directory_module/mod.rs:0:0:0:0 | Parse(src/directory_module/mod.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Extract(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | LoadSource(src/directory_module/nested_module.rs) | +| src/directory_module/nested_module.rs:0:0:0:0 | Parse(src/directory_module/nested_module.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Extract(src/directory_module/not_loaded.rs) | +| src/directory_module/not_loaded.rs:0:0:0:0 | Parse(src/directory_module/not_loaded.rs) | +| src/file_module.rs:0:0:0:0 | Extract(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | LoadSource(src/file_module.rs) | +| src/file_module.rs:0:0:0:0 | Parse(src/file_module.rs) | +| src/main.rs:0:0:0:0 | Extract(src/main.rs) | +| src/main.rs:0:0:0:0 | LoadSource(src/main.rs) | +| src/main.rs:0:0:0:0 | Parse(src/main.rs) | diff --git a/rust/ql/integration-tests/hello-project/test_project.py b/rust/ql/integration-tests/hello-project/test_project.py index 2cbac0ffdb8..64988bef7a9 100644 --- a/rust/ql/integration-tests/hello-project/test_project.py +++ b/rust/ql/integration-tests/hello-project/test_project.py @@ -1,7 +1,12 @@ +import pytest + + +@pytest.mark.ql_test("steps.ql", expected=".cargo.expected") def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("Cargo.toml") codeql.database.create() +@pytest.mark.ql_test("steps.ql", expected=".rust-project.expected") def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): manifests.select("rust-project.json") codeql.database.create() diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected index 7d484623087..7d44256db5a 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.cargo.expected @@ -1,103 +1,29 @@ { "attributes": { - "steps": [ - { - "action": "extract", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "loadManifest", - "file": "/exe/", - "ms": "__REDACTED__" - }, - { - "action": "loadManifest", - "file": "/lib/", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } - ], - "summary": { - "durations": { - "extract": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadManifest": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadSource": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "parse": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "total": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - } - }, - "numberOfFiles": 4, - "numberOfManifests": 2 - } + }, + "numberOfFiles": 4, + "numberOfManifests": 2 }, "severity": "note", "source": { diff --git a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected index 8ab17e9fe73..4c5dbc75d84 100644 --- a/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/diagnostics.rust-project.expected @@ -1,98 +1,29 @@ { "attributes": { - "steps": [ - { - "action": "extract", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" + "durations": { + "extract": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" + "loadManifest": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" + "loadSource": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "extract", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "parse": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" }, - { - "action": "loadManifest", - "file": "/", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "loadSource", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/a_module.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/exe/src/main.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/a_module/mod.rs", - "ms": "__REDACTED__" - }, - { - "action": "parse", - "file": "/lib/src/lib.rs", - "ms": "__REDACTED__" + "total": { + "ms": "__REDACTED__", + "pretty": "__REDACTED__" } - ], - "summary": { - "durations": { - "extract": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadManifest": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "loadSource": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "parse": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - }, - "total": { - "ms": "__REDACTED__", - "pretty": "__REDACTED__" - } - }, - "numberOfFiles": 4, - "numberOfManifests": 1 - } + }, + "numberOfFiles": 4, + "numberOfManifests": 1 }, "severity": "note", "source": { diff --git a/rust/ql/integration-tests/hello-workspace/steps.cargo.expected b/rust/ql/integration-tests/hello-workspace/steps.cargo.expected new file mode 100644 index 00000000000..138bd77b690 --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/steps.cargo.expected @@ -0,0 +1,14 @@ +| exe/Cargo.toml:0:0:0:0 | LoadManifest(exe/Cargo.toml) | +| exe/src/a_module.rs:0:0:0:0 | Extract(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | LoadSource(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | Parse(exe/src/a_module.rs) | +| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) | +| lib/Cargo.toml:0:0:0:0 | LoadManifest(lib/Cargo.toml) | +| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | LoadSource(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | Parse(lib/src/a_module/mod.rs) | +| lib/src/lib.rs:0:0:0:0 | Extract(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | LoadSource(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | Parse(lib/src/lib.rs) | diff --git a/rust/ql/integration-tests/hello-workspace/steps.ql b/rust/ql/integration-tests/hello-workspace/steps.ql new file mode 100644 index 00000000000..eb8f9a05adb --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/steps.ql @@ -0,0 +1,4 @@ +import codeql.rust.internal.ExtractorStep + +from ExtractorStep step +select step diff --git a/rust/ql/integration-tests/hello-workspace/steps.rust-project.expected b/rust/ql/integration-tests/hello-workspace/steps.rust-project.expected new file mode 100644 index 00000000000..09620925ce9 --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/steps.rust-project.expected @@ -0,0 +1,13 @@ +| exe/src/a_module.rs:0:0:0:0 | Extract(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | LoadSource(exe/src/a_module.rs) | +| exe/src/a_module.rs:0:0:0:0 | Parse(exe/src/a_module.rs) | +| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) | +| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | LoadSource(lib/src/a_module/mod.rs) | +| lib/src/a_module/mod.rs:0:0:0:0 | Parse(lib/src/a_module/mod.rs) | +| lib/src/lib.rs:0:0:0:0 | Extract(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | LoadSource(lib/src/lib.rs) | +| lib/src/lib.rs:0:0:0:0 | Parse(lib/src/lib.rs) | +| rust-project.json:0:0:0:0 | LoadManifest(rust-project.json) | diff --git a/rust/ql/integration-tests/hello-workspace/test_workspace.py b/rust/ql/integration-tests/hello-workspace/test_workspace.py index 5c95031466f..3dd49991aaa 100644 --- a/rust/ql/integration-tests/hello-workspace/test_workspace.py +++ b/rust/ql/integration-tests/hello-workspace/test_workspace.py @@ -1,13 +1,13 @@ import pytest -# currently the DB-check fails on actions because of loading files multiple times and assiging multiple locations -# see https://github.com/github/codeql-team/issues/3365 -@pytest.mark.ql_test("DB-CHECK", xfail="maybe") + +@pytest.mark.ql_test("steps.ql", expected=".cargo.expected") def test_cargo(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): rust_check_diagnostics.expected_suffix = ".cargo.expected" manifests.select("Cargo.toml") codeql.database.create() +@pytest.mark.ql_test("steps.ql", expected=".rust-project.expected") def test_rust_project(codeql, rust, manifests, check_source_archive, rust_check_diagnostics): rust_check_diagnostics.expected_suffix = ".rust-project.expected" manifests.select("rust-project.json") diff --git a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll new file mode 100644 index 00000000000..55505be1d59 --- /dev/null +++ b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll @@ -0,0 +1,46 @@ +import codeql.files.FileSystem + +/** + * An extractor step, usable for debugging and diagnostics reasons. + * + * INTERNAL: Do not use. + */ +class ExtractorStep extends @extractor_step { + /** + * The string representation of this extractor step. + */ + string toString() { + exists(File file, string action | + extractor_steps(this, action, file, _) and + result = action + "(" + file.getAbsolutePath() + ")" + ) + } + + /** + * The action this extractor step carried out. + */ + string getAction() { extractor_steps(this, result, _, _) } + + /** + * The file the extractor step was carried out on. + */ + File getFile() { extractor_steps(this, _, result, _) } + + /** + * The duration of the extractor step in milliseconds. + */ + int getDurationMs() { extractor_steps(this, _, _, result) } + + /** + * Provides location information for this step. + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getFile().getAbsolutePath() = filepath and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 + } +} diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 46085a55abf..26a22063d6d 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -116,6 +116,13 @@ locatable_locations( int location: @location_default ref ); +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int file: @file ref, + int duration_ms: int ref +) + // from schema From 50c917d2eb9fe8f53464b7aea841db3bbc2e55a1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 28 Nov 2024 12:02:57 +0100 Subject: [PATCH 23/63] Rust: restrict extracted files queries --- rust/ql/lib/codeql/files/FileSystem.qll | 16 ++++++++++++++-- .../lib/codeql/rust/internal/ExtractorStep.qll | 8 ++++---- .../ql/src/queries/diagnostics/ExtractedFiles.ql | 2 +- .../src/queries/diagnostics/ExtractionErrors.ql | 2 +- rust/ql/src/queries/summary/SummaryStats.ql | 7 +++++-- rust/ql/test/extractor-tests/File/File.expected | 7 ++++--- rust/ql/test/extractor-tests/File/File.ql | 8 +++++--- .../diagnostics/ExtractedFiles.expected | 1 - .../diagnostics/LinesOfUserCodeInFiles.expected | 1 + .../diagnostics/SummaryStats.expected | 4 ++-- 10 files changed, 37 insertions(+), 19 deletions(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index 7136dcc3b5a..c83680f7ec6 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -6,6 +6,7 @@ private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode private import codeql.rust.elements.Comment private import codeql.rust.Diagnostics +private import codeql.rust.internal.ExtractorStep private module Input implements InputSig { abstract class ContainerBase extends @container { @@ -36,7 +37,9 @@ class Folder = Impl::Folder; /** A file. */ class File extends Container, Impl::File { /** Holds if this file was extracted from ordinary source code. */ - predicate fromSource() { any() } + predicate fromSource() { + exists(ExtractorStep s | s.getAction() = "Extract" and s.getFile() = this) + } /** * Gets the number of lines containing code in this file. This value @@ -58,11 +61,20 @@ class File extends Container, Impl::File { } } +/** + * A source file that was extracted. + * + * TODO: rename `SourceFile` from the generated AST to give that name to this class. + */ +class ExtractedFile extends File { + ExtractedFile() { this.fromSource() } +} + /** * A successfully extracted file, that is, a file that was extracted and * contains no extraction errors or warnings. */ -class SuccessfullyExtractedFile extends File { +class SuccessfullyExtractedFile extends ExtractedFile { SuccessfullyExtractedFile() { not exists(Diagnostic d | d.getLocation().getFile() = this and diff --git a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll index 55505be1d59..50e6ebafebf 100644 --- a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll +++ b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll @@ -7,7 +7,7 @@ import codeql.files.FileSystem */ class ExtractorStep extends @extractor_step { /** - * The string representation of this extractor step. + * Gets the string representation of this extractor step. */ string toString() { exists(File file, string action | @@ -17,17 +17,17 @@ class ExtractorStep extends @extractor_step { } /** - * The action this extractor step carried out. + * Gets the action this extractor step carried out. */ string getAction() { extractor_steps(this, result, _, _) } /** - * The file the extractor step was carried out on. + * Gets the file the extractor step was carried out on. */ File getFile() { extractor_steps(this, _, result, _) } /** - * The duration of the extractor step in milliseconds. + * Gets the duration of the extractor step in milliseconds. */ int getDurationMs() { extractor_steps(this, _, _, result) } diff --git a/rust/ql/src/queries/diagnostics/ExtractedFiles.ql b/rust/ql/src/queries/diagnostics/ExtractedFiles.ql index ce5aa699e67..112fb2949dc 100644 --- a/rust/ql/src/queries/diagnostics/ExtractedFiles.ql +++ b/rust/ql/src/queries/diagnostics/ExtractedFiles.ql @@ -8,6 +8,6 @@ import rust -from File f +from ExtractedFile f where exists(f.getRelativePath()) select f, "File successfully extracted." diff --git a/rust/ql/src/queries/diagnostics/ExtractionErrors.ql b/rust/ql/src/queries/diagnostics/ExtractionErrors.ql index 68be66f8ca9..bd5ec3426fb 100644 --- a/rust/ql/src/queries/diagnostics/ExtractionErrors.ql +++ b/rust/ql/src/queries/diagnostics/ExtractionErrors.ql @@ -11,7 +11,7 @@ import codeql.files.FileSystem /** Gets the SARIF severity to associate with an error. */ int getSeverity() { result = 2 } -from ExtractionError error, File f +from ExtractionError error, ExtractedFile f where f = error.getLocation().getFile() and exists(f.getRelativePath()) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 09ee83fc5e6..ffe7cbf1a8f 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -21,10 +21,13 @@ where or key = "Extraction warnings" and value = count(ExtractionWarning w) or - key = "Files extracted - total" and value = count(File f | exists(f.getRelativePath())) + key = "Files extracted - total" and value = count(ExtractedFile f | exists(f.getRelativePath())) or key = "Files extracted - with errors" and - value = count(File f | exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile) + value = + count(ExtractedFile f | + exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile + ) or key = "Files extracted - without errors" and value = count(SuccessfullyExtractedFile f | exists(f.getRelativePath())) diff --git a/rust/ql/test/extractor-tests/File/File.expected b/rust/ql/test/extractor-tests/File/File.expected index 924ed370b35..77fee3c3c42 100644 --- a/rust/ql/test/extractor-tests/File/File.expected +++ b/rust/ql/test/extractor-tests/File/File.expected @@ -1,3 +1,4 @@ -| a_file.rs:0:0:0:0 | a_file.rs | -| another_file.rs:0:0:0:0 | another_file.rs | -| lib.rs:0:0:0:0 | lib.rs | +| Cargo.toml:0:0:0:0 | Cargo.toml | fromSource: no | +| a_file.rs:0:0:0:0 | a_file.rs | fromSource: yes | +| another_file.rs:0:0:0:0 | another_file.rs | fromSource: yes | +| lib.rs:0:0:0:0 | lib.rs | fromSource: yes | diff --git a/rust/ql/test/extractor-tests/File/File.ql b/rust/ql/test/extractor-tests/File/File.ql index fcb2b274e78..316099193d1 100644 --- a/rust/ql/test/extractor-tests/File/File.ql +++ b/rust/ql/test/extractor-tests/File/File.ql @@ -1,5 +1,7 @@ import rust -from File f -where exists(f.getRelativePath()) -select f +from File f, string fromSource +where + exists(f.getRelativePath()) and + if f.fromSource() then fromSource = "fromSource: yes" else fromSource = "fromSource: no" +select f, fromSource diff --git a/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected b/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected index bc8dc8cccf1..c5ebb707230 100644 --- a/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected @@ -5,4 +5,3 @@ | main.rs:0:0:0:0 | main.rs | File successfully extracted. | | my_macro.rs:0:0:0:0 | my_macro.rs | File successfully extracted. | | my_struct.rs:0:0:0:0 | my_struct.rs | File successfully extracted. | -| options.yml:0:0:0:0 | options.yml | File successfully extracted. | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index 0a58a05feed..f53c931e56e 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -5,4 +5,5 @@ | lib.rs:0:0:0:0 | lib.rs | 5 | | does_not_compile.rs:0:0:0:0 | does_not_compile.rs | 3 | | error.rs:0:0:0:0 | error.rs | 3 | +| Cargo.toml:0:0:0:0 | Cargo.toml | 0 | | options.yml:0:0:0:0 | options.yml | 0 | diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index 74e1e461c6f..16e895cdeef 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -2,9 +2,9 @@ | Elements unextracted | 0 | | Extraction errors | 0 | | Extraction warnings | 7 | -| Files extracted - total | 8 | +| Files extracted - total | 7 | | Files extracted - with errors | 3 | -| Files extracted - without errors | 5 | +| Files extracted - without errors | 4 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 0 | From a9817a028127c649a88ad3b30a1b76e77edf8117 Mon Sep 17 00:00:00 2001 From: Taus Date: Thu, 28 Nov 2024 12:32:00 +0000 Subject: [PATCH 24/63] Python: Add guide describing how to extend the parser --- python/extractor/extending-the-parser.md | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 python/extractor/extending-the-parser.md diff --git a/python/extractor/extending-the-parser.md b/python/extractor/extending-the-parser.md new file mode 100644 index 00000000000..55bdd6c2a0d --- /dev/null +++ b/python/extractor/extending-the-parser.md @@ -0,0 +1,94 @@ +# How to update the Python parser + +## Step 1: Add an extractor test + +Extractor parser tests live in the `tests/parser` directory. There are two different kinds of tests + +- Tests that compare the behavior of the old (Python-based) and new (`tree-sitter`-based) parsers, and verify that they yield the same output on the given source files, and +- Tests that compare the output of the parser (old or new) against a fixed `.expected` file. + +What kind of test is run is determined based on the file name. +If it ends in either `_new.py` or `_old.py`, then the test is run against an `.expected` file. If not, it is used to compare old against new. + +In most cases when adding new features, you'll only be interested in modifying the new parser (the old one is mostly there for legacy reasons). +Thus, you will almost certainly want to create a test that ends in `_new.py`. + +It's a good habit to start by adding the parser test, as this makes it more easy to test when various bits of the parser have been added/modified successfully. + +The rest of this document will only concern itself with the process of extending the _new_ parser. + +To actually _run_ the tests, the easiest way is to use `pytest`. +In the main `extractor` directory (i.e. where this file is located) run + +```sh +pytest tests/test_parser.py +``` + +and wait for the tests to complete. It is normal and expected that the test seemingly freezes on the first run. +This is simply because the `tsg-python` Rust binary is being built in the background. + +Once you have added a new test (or modified an old one) and start making modifications to the parser itself, it quickly becomes tedious to run _all_ the parser tests. +To run just a single test using `pytest`, use the `::` syntax to specify specific tests. +For instance, if you want to just run the tests associated with the file `types_new.py`, you would write + +```sh +pytest tests/test_parser.py::ParserTest::test_types_new +``` + +## Step 2: Extend the `tree-sitter-python` grammar + +The new parser is based on `tree-sitter`, so the first task is to extend the existing `tree-sitter-python` grammar. +This grammar can be found in the `grammar.js` file in the `tsg-python/tsp` subdirectory of the extractor directory. + +Note that whenever changes are made to `grammar.js`, you must regenerate the parser files by running + +```sh +tree-sitter generate +``` + +inside the `tsp` directory. +You'll need to install the `tree-sitter` CLI in order to run this command. +One way to install it is to use `cargo`: + +```sh +cargo install tree-sitter-cli +``` + +(This presupposes you have `cargo` available, but you'll need this anyway when compiling `tsg-python`.) + +Once the parser files have been regenerated, they'll get picked up automatically when `tsg-python` is rebuilt. + +> Pro-tip: When you're done with your parser changes, and go to commit these to a branch, put the autogenerated files in their own commit. +> This makes it easier to review the changes, and if you need to go back and regenerate the files again, it's easy to modify just that commit. + +Once you have extended `grammar.js` and regenerated the parser files, you should be able to check that the grammar changes are sufficient by rerunning the parser test using `pytest`. If it fails while producing an AST that doesn't make sense, then you're probably on the right track. If it fails _without_ producing an AST, then something went wrong with the actual `tree-sitter` parse. To check if this is the case, you can run + +```sh +tree-sitter parse path/to/test.py +``` + +and see what kind of errors are emitted (possibly as `ERROR` or `MISSING` nodes in the AST that is output). + +## Step 3: Extend `python.tsg` + +Once the grammar has been extended, we need to also tell `tsg-python` how to turn the `tree-sitter-python` AST into something that better matches the AST structure that we use in the Python extractor. + +For an introduction to the language of `tree-sitter-graph` (and in particular how we use it in the Python extractor), see the `README.md` file in the `tsg-python` directory. + +## Step 4: Extend the set of known AST nodes + +If you added new node types, or added fields to known node types, then you'll need to update a few files in the Python extractor before it is able to reconstruct the output from `tsg-python`. + +New AST nodes should be added in two places: `master.py` and `semmle/python/ast.py`. The former of these is used to automatically generate the Python dbscheme and `AstGenerated.qll`. The latter is what the parser actually uses as its internal representation of the AST. + +## Step 5: Rebuild the autogenerated AST and database scheme + +If you made changes to `master.py`, you'll need to regenerate a couple of files. This can be done from within the `extractor` directory using the `make dbscheme` and `make ast` commands. Note that for the latter, you need a copy of the CodeQL CLI present, as it is used to autoformat the `AstGenerated.qll` file. + +## Step 6: Add dbscheme upgrade and downgrade scripts + +If you ended up making changes to the database scheme inw step 5, then you'll need to add an appropriate pair of up- and downgrade scripts to handle any changes between the different versions of the dbscheme. + +This can be a bit fiddly, but luckily there are [tools](https://github.com/github/codeql/blob/main/misc/scripts/prepare-db-upgrade.sh) that can help set up some of the necessary files for you. + +See also the [guide](https://github.com/github/codeql/blob/main/docs/prepare-db-upgrade.md) for preparing database upgrades. From 7e0e5a3f4efd2468be1108e63c6ef4a5662ef249 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 29 Nov 2024 12:01:50 +0100 Subject: [PATCH 25/63] Rust: move `rust_sysroot_src` to its own session fixture --- rust/ql/integration-tests/conftest.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rust/ql/integration-tests/conftest.py b/rust/ql/integration-tests/conftest.py index 11eefe7e265..a1fbcf4e18d 100644 --- a/rust/ql/integration-tests/conftest.py +++ b/rust/ql/integration-tests/conftest.py @@ -4,18 +4,24 @@ import commands import pathlib +@pytest.fixture def cargo(cwd): assert (cwd / "Cargo.toml").exists() (cwd / "rust-project.json").unlink(missing_ok=True) +@pytest.fixture(scope="session") +def rust_sysroot_src() -> str: + rust_sysroot = pathlib.Path(commands.run("rustc --print sysroot", _capture=True)) + ret = rust_sysroot.joinpath("lib", "rustlib", "src", "rust", "library") + assert ret.exists() + return str(ret) @pytest.fixture -def rust_project(cwd): +def rust_project(cwd, rust_sysroot_src): project_file = cwd / "rust-project.json" assert project_file.exists() - rust_sysroot = pathlib.Path(commands.run("rustc --print sysroot", _capture=True)) project = json.loads(project_file.read_text()) - project["sysroot_src"] = str(rust_sysroot.joinpath("lib", "rustlib", "src", "rust", "library")) + project["sysroot_src"] = rust_sysroot_src project_file.write_text(json.dumps(project, indent=4)) (cwd / "Cargo.toml").unlink(missing_ok=True) From 14c0bbf531a78f5429610c364e5f52130e4bd78f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:34:47 +0000 Subject: [PATCH 26/63] Rust: Add another test case, fix an annotation. --- .../security/CWE-696/BadCTorInitialization.expected | 4 ++-- rust/ql/test/query-tests/security/CWE-696/test.rs | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 508a359b0c0..b52516ce9a3 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -8,7 +8,7 @@ | test.rs:69:9:69:24 | ...::stdin(...) | test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | Call to ...::stdin(...) in a function with the ctor attribute. | | test.rs:90:5:90:35 | ...::sleep(...) | test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | Call to ...::sleep(...) in a function with the ctor attribute. | | test.rs:97:5:97:23 | ...::exit(...) | test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | Call to ...::exit(...) in a function with the ctor attribute. | -| test.rs:166:5:166:15 | ...::stdout(...) | test.rs:164:1:164:7 | Attr | test.rs:166:5:166:15 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | +| test.rs:171:5:171:15 | ...::stdout(...) | test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | edges | test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | | test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | @@ -19,4 +19,4 @@ edges | test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | | test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | | test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | -| test.rs:164:1:164:7 | Attr | test.rs:166:5:166:15 | ...::stdout(...) | +| test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ...::stdout(...) | diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs index 87f544be85c..69eb68e868a 100644 --- a/rust/ql/test/query-tests/security/CWE-696/test.rs +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -137,12 +137,12 @@ fn call_target3_2() { } } -#[ctor] // $ MISSING: Source=source3_2 +#[ctor] fn harmless3_2() { call_target3_2(); } -#[ctor] +#[ctor] // $ MISSING: Source=source3_3 fn bad3_3() { call_target3_1(); call_target3_2(); @@ -153,6 +153,11 @@ fn bad3_4() { bad3_3(); } +fn harmless3_5() { + call_target3_1(); + call_target3_2(); +} + // --- macros --- macro_rules! macro4_1 { From 4d0c53d493fe2cc359add1b0f8474b5d2c1f9950 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:30:19 +0000 Subject: [PATCH 27/63] Rust: Add support for transitive results via calls in the ctor query. --- .../security/CWE-696/BadCtorInitialization.ql | 11 +++--- .../CWE-696/BadCTorInitialization.expected | 34 +++++++++++++++++++ .../test/query-tests/security/CWE-696/test.rs | 6 ++-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 22ea6514e02..32f0e9731cc 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -41,15 +41,18 @@ class PathElement = AstNode; query predicate edges(PathElement pred, PathElement succ) { // starting edge - exists(CtorAttr ctor, Function f, StdCall call | + exists(CtorAttr ctor, Function f, CallExprBase call | f.getAnAttr() = ctor and call.getEnclosingCallable() = f and pred = ctor and // source - succ = call // sink + succ = call // flow or sink node ) - // or + or // transitive edge - // TODO + exists(Function f | + pred.(CallExprBase).getStaticTarget() = f and + succ.(CallExprBase).getEnclosingCallable() = f + ) } from CtorAttr ctor, StdCall call diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index b52516ce9a3..c85aabe1fb9 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -8,15 +8,49 @@ | test.rs:69:9:69:24 | ...::stdin(...) | test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | Call to ...::stdin(...) in a function with the ctor attribute. | | test.rs:90:5:90:35 | ...::sleep(...) | test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | Call to ...::sleep(...) in a function with the ctor attribute. | | test.rs:97:5:97:23 | ...::exit(...) | test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | Call to ...::exit(...) in a function with the ctor attribute. | +| test.rs:126:9:126:16 | stderr(...) | test.rs:129:1:129:7 | Attr | test.rs:126:9:126:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | +| test.rs:126:9:126:16 | stderr(...) | test.rs:145:1:145:7 | Attr | test.rs:126:9:126:16 | stderr(...) | Call to stderr(...) in a function with the ctor attribute. | +| test.rs:126:9:126:44 | ... .write_all(...) | test.rs:129:1:129:7 | Attr | test.rs:126:9:126:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | +| test.rs:126:9:126:44 | ... .write_all(...) | test.rs:145:1:145:7 | Attr | test.rs:126:9:126:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | | test.rs:171:5:171:15 | ...::stdout(...) | test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | edges | test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | +| test.rs:29:1:29:13 | Attr | test.rs:31:9:31:49 | ... .write(...) | | test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | +| test.rs:34:1:34:13 | Attr | test.rs:36:9:36:49 | ... .write(...) | | test.rs:40:1:40:13 | Attr | test.rs:43:9:43:25 | ...::stdout(...) | +| test.rs:40:1:40:13 | Attr | test.rs:43:9:43:49 | ... .write(...) | | test.rs:51:1:51:7 | Attr | test.rs:53:9:53:16 | stdout(...) | +| test.rs:51:1:51:7 | Attr | test.rs:53:9:53:40 | ... .write(...) | | test.rs:56:1:56:7 | Attr | test.rs:58:9:58:16 | stderr(...) | +| test.rs:56:1:56:7 | Attr | test.rs:58:9:58:44 | ... .write_all(...) | | test.rs:61:1:61:7 | Attr | test.rs:63:14:63:28 | ...::_print(...) | +| test.rs:66:1:66:7 | Attr | test.rs:68:20:68:32 | ...::new(...) | | test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | +| test.rs:66:1:66:7 | Attr | test.rs:69:9:69:45 | ... .read_line(...) | +| test.rs:74:1:74:7 | Attr | test.rs:76:17:76:45 | ...::create(...) | +| test.rs:74:1:74:7 | Attr | test.rs:76:17:76:54 | ... .unwrap(...) | +| test.rs:79:1:79:7 | Attr | test.rs:81:14:81:38 | ...::now(...) | | test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | | test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | +| test.rs:100:1:100:13 | Attr | test.rs:102:5:102:46 | ... .write_nl(...) | +| test.rs:100:1:100:13 | Attr | test.rs:102:5:102:46 | ...::new(...) | +| test.rs:100:1:100:13 | Attr | test.rs:102:31:102:45 | ... .write_fmt(...) | +| test.rs:105:1:105:13 | Attr | test.rs:107:5:107:23 | panic_cold_explicit(...) | +| test.rs:113:1:113:13 | Attr | test.rs:115:18:115:37 | ...::new::<...>(...) | +| test.rs:113:1:113:13 | Attr | test.rs:116:15:116:27 | alloc(...) | +| test.rs:113:1:113:13 | Attr | test.rs:118:9:118:21 | ... .is_null(...) | +| test.rs:113:1:113:13 | Attr | test.rs:119:9:119:28 | dealloc(...) | +| test.rs:129:1:129:7 | Attr | test.rs:131:5:131:20 | call_target3_1(...) | +| test.rs:131:5:131:20 | call_target3_1(...) | test.rs:126:9:126:16 | stderr(...) | +| test.rs:131:5:131:20 | call_target3_1(...) | test.rs:126:9:126:44 | ... .write_all(...) | +| test.rs:140:1:140:7 | Attr | test.rs:142:5:142:20 | call_target3_2(...) | +| test.rs:145:1:145:7 | Attr | test.rs:147:5:147:20 | call_target3_1(...) | +| test.rs:145:1:145:7 | Attr | test.rs:148:5:148:20 | call_target3_2(...) | +| test.rs:147:5:147:20 | call_target3_1(...) | test.rs:126:9:126:16 | stderr(...) | +| test.rs:147:5:147:20 | call_target3_1(...) | test.rs:126:9:126:44 | ... .write_all(...) | +| test.rs:151:1:151:7 | Attr | test.rs:153:5:153:12 | bad3_3(...) | +| test.rs:157:5:157:20 | call_target3_1(...) | test.rs:126:9:126:16 | stderr(...) | +| test.rs:157:5:157:20 | call_target3_1(...) | test.rs:126:9:126:44 | ... .write_all(...) | +| test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ... .write(...) | | test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ...::stdout(...) | diff --git a/rust/ql/test/query-tests/security/CWE-696/test.rs b/rust/ql/test/query-tests/security/CWE-696/test.rs index 69eb68e868a..5cd7f451f2c 100644 --- a/rust/ql/test/query-tests/security/CWE-696/test.rs +++ b/rust/ql/test/query-tests/security/CWE-696/test.rs @@ -123,10 +123,10 @@ unsafe fn harmless2_11() { // --- transitive cases --- fn call_target3_1() { - _ = stderr().write_all(b"Hello, world!"); // $ MISSING: Alert=source3_1 Alert=source3_3 Alert=source3_4 + _ = stderr().write_all(b"Hello, world!"); // $ Alert=source3_1 Alert=source3_3 MISSING: Alert=source3_4 } -#[ctor] // $ MISSING: Source=source3_1 +#[ctor] // $ Source=source3_1 fn bad3_1() { call_target3_1(); } @@ -142,7 +142,7 @@ fn harmless3_2() { call_target3_2(); } -#[ctor] // $ MISSING: Source=source3_3 +#[ctor] // $ Source=source3_3 fn bad3_3() { call_target3_1(); call_target3_2(); From 3e0e374783bb0a78d2c721c0a88586fe3986d0da Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:32:35 +0000 Subject: [PATCH 28/63] Rust: Remove unnecessary edges. --- .../queries/security/CWE-696/BadCtorInitialization.ql | 9 +++++---- .../security/CWE-696/BadCTorInitialization.expected | 2 -- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 32f0e9731cc..da65c16159b 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -40,16 +40,17 @@ class StdCall extends Expr { class PathElement = AstNode; query predicate edges(PathElement pred, PathElement succ) { - // starting edge + // starting edge (`#[ctor]` / `#[dtor]` attribute to call) exists(CtorAttr ctor, Function f, CallExprBase call | f.getAnAttr() = ctor and call.getEnclosingCallable() = f and - pred = ctor and // source - succ = call // flow or sink node + pred = ctor and + succ = call ) or - // transitive edge + // transitive edge (call to call) exists(Function f | + edges(_, pred) and pred.(CallExprBase).getStaticTarget() = f and succ.(CallExprBase).getEnclosingCallable() = f ) diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index c85aabe1fb9..8805f214b65 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -50,7 +50,5 @@ edges | test.rs:147:5:147:20 | call_target3_1(...) | test.rs:126:9:126:16 | stderr(...) | | test.rs:147:5:147:20 | call_target3_1(...) | test.rs:126:9:126:44 | ... .write_all(...) | | test.rs:151:1:151:7 | Attr | test.rs:153:5:153:12 | bad3_3(...) | -| test.rs:157:5:157:20 | call_target3_1(...) | test.rs:126:9:126:16 | stderr(...) | -| test.rs:157:5:157:20 | call_target3_1(...) | test.rs:126:9:126:44 | ... .write_all(...) | | test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ... .write(...) | | test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ...::stdout(...) | From 4f08fdd23241d5f214dd3560ec85d048ae32dbc2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:56:32 +0000 Subject: [PATCH 29/63] Rust: Make the two cases read more similarly. --- .../ql/src/queries/security/CWE-696/BadCtorInitialization.ql | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index da65c16159b..cb1c1f31a8b 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -41,11 +41,10 @@ class PathElement = AstNode; query predicate edges(PathElement pred, PathElement succ) { // starting edge (`#[ctor]` / `#[dtor]` attribute to call) - exists(CtorAttr ctor, Function f, CallExprBase call | + exists(CtorAttr ctor, Function f | f.getAnAttr() = ctor and - call.getEnclosingCallable() = f and pred = ctor and - succ = call + succ.(CallExprBase).getEnclosingCallable() = f ) or // transitive edge (call to call) From 1e656a49b08b5ec43b8f999e4c32d75e5695f7f7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:21:34 +0000 Subject: [PATCH 30/63] Rust: Rewrite the query to (1) include functions and (2) minimize output. --- .../security/CWE-696/BadCtorInitialization.ql | 51 +++++++++----- .../CWE-696/BadCTorInitialization.expected | 66 ++++++++----------- 2 files changed, 61 insertions(+), 56 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index cb1c1f31a8b..e8f9c28b387 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -14,7 +14,7 @@ import rust /** - * A `#[ctor]` or `#[dtor]` attribute. + * A `#[ctor]` or `#[dtor]` attribute, that is, a source for this query. */ class CtorAttr extends Attr { string whichAttr; @@ -28,7 +28,7 @@ class CtorAttr extends Attr { } /** - * A call into the Rust standard library. + * A call into the Rust standard library, that is, a sink for this query. */ class StdCall extends Expr { StdCall() { @@ -39,23 +39,38 @@ class StdCall extends Expr { class PathElement = AstNode; -query predicate edges(PathElement pred, PathElement succ) { - // starting edge (`#[ctor]` / `#[dtor]` attribute to call) - exists(CtorAttr ctor, Function f | - f.getAnAttr() = ctor and - pred = ctor and - succ.(CallExprBase).getEnclosingCallable() = f - ) +/** + * A candidate edge for the query that is reachable from + * a source. + */ +predicate edgesFwd(PathElement pred, PathElement succ) { + // attribute (source) -> callable + pred.(CtorAttr) = succ.(Callable).getAnAttr() or - // transitive edge (call to call) - exists(Function f | - edges(_, pred) and - pred.(CallExprBase).getStaticTarget() = f and - succ.(CallExprBase).getEnclosingCallable() = f + // [forwards reachable] callable -> enclosed call + edgesFwd(_, pred) and + pred = succ.(CallExprBase).getEnclosingCallable() + or + // [forwards reachable] call -> target callable + edgesFwd(_, pred) and + pred.(CallExprBase).getStaticTarget() = succ +} + +/** + * An edge for the query that is reachable from a source and backwards + * reachable from a sink (adding the backwards reachability constraint + * reduces the amount of output data produced). + */ +query predicate edges(PathElement pred, PathElement succ) { + edgesFwd(pred, succ) and + ( + succ instanceof StdCall // sink + or + edges(succ, _) // backwards reachable from a sink ) } -from CtorAttr ctor, StdCall call -where edges*(ctor, call) -select call, ctor, call, - "Call to " + call.toString() + " in a function with the " + ctor.getWhichAttr() + " attribute." +from CtorAttr source, StdCall sink +where edges*(source, sink) +select sink, source, sink, + "Call to " + sink.toString() + " in a function with the " + source.getWhichAttr() + " attribute." diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 8805f214b65..311e1828f53 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -14,41 +14,31 @@ | test.rs:126:9:126:44 | ... .write_all(...) | test.rs:145:1:145:7 | Attr | test.rs:126:9:126:44 | ... .write_all(...) | Call to ... .write_all(...) in a function with the ctor attribute. | | test.rs:171:5:171:15 | ...::stdout(...) | test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ...::stdout(...) | Call to ...::stdout(...) in a function with the ctor attribute. | edges -| test.rs:29:1:29:13 | Attr | test.rs:31:9:31:25 | ...::stdout(...) | -| test.rs:29:1:29:13 | Attr | test.rs:31:9:31:49 | ... .write(...) | -| test.rs:34:1:34:13 | Attr | test.rs:36:9:36:25 | ...::stdout(...) | -| test.rs:34:1:34:13 | Attr | test.rs:36:9:36:49 | ... .write(...) | -| test.rs:40:1:40:13 | Attr | test.rs:43:9:43:25 | ...::stdout(...) | -| test.rs:40:1:40:13 | Attr | test.rs:43:9:43:49 | ... .write(...) | -| test.rs:51:1:51:7 | Attr | test.rs:53:9:53:16 | stdout(...) | -| test.rs:51:1:51:7 | Attr | test.rs:53:9:53:40 | ... .write(...) | -| test.rs:56:1:56:7 | Attr | test.rs:58:9:58:16 | stderr(...) | -| test.rs:56:1:56:7 | Attr | test.rs:58:9:58:44 | ... .write_all(...) | -| test.rs:61:1:61:7 | Attr | test.rs:63:14:63:28 | ...::_print(...) | -| test.rs:66:1:66:7 | Attr | test.rs:68:20:68:32 | ...::new(...) | -| test.rs:66:1:66:7 | Attr | test.rs:69:9:69:24 | ...::stdin(...) | -| test.rs:66:1:66:7 | Attr | test.rs:69:9:69:45 | ... .read_line(...) | -| test.rs:74:1:74:7 | Attr | test.rs:76:17:76:45 | ...::create(...) | -| test.rs:74:1:74:7 | Attr | test.rs:76:17:76:54 | ... .unwrap(...) | -| test.rs:79:1:79:7 | Attr | test.rs:81:14:81:38 | ...::now(...) | -| test.rs:88:1:88:7 | Attr | test.rs:90:5:90:35 | ...::sleep(...) | -| test.rs:95:1:95:7 | Attr | test.rs:97:5:97:23 | ...::exit(...) | -| test.rs:100:1:100:13 | Attr | test.rs:102:5:102:46 | ... .write_nl(...) | -| test.rs:100:1:100:13 | Attr | test.rs:102:5:102:46 | ...::new(...) | -| test.rs:100:1:100:13 | Attr | test.rs:102:31:102:45 | ... .write_fmt(...) | -| test.rs:105:1:105:13 | Attr | test.rs:107:5:107:23 | panic_cold_explicit(...) | -| test.rs:113:1:113:13 | Attr | test.rs:115:18:115:37 | ...::new::<...>(...) | -| test.rs:113:1:113:13 | Attr | test.rs:116:15:116:27 | alloc(...) | -| test.rs:113:1:113:13 | Attr | test.rs:118:9:118:21 | ... .is_null(...) | -| test.rs:113:1:113:13 | Attr | test.rs:119:9:119:28 | dealloc(...) | -| test.rs:129:1:129:7 | Attr | test.rs:131:5:131:20 | call_target3_1(...) | -| test.rs:131:5:131:20 | call_target3_1(...) | test.rs:126:9:126:16 | stderr(...) | -| test.rs:131:5:131:20 | call_target3_1(...) | test.rs:126:9:126:44 | ... .write_all(...) | -| test.rs:140:1:140:7 | Attr | test.rs:142:5:142:20 | call_target3_2(...) | -| test.rs:145:1:145:7 | Attr | test.rs:147:5:147:20 | call_target3_1(...) | -| test.rs:145:1:145:7 | Attr | test.rs:148:5:148:20 | call_target3_2(...) | -| test.rs:147:5:147:20 | call_target3_1(...) | test.rs:126:9:126:16 | stderr(...) | -| test.rs:147:5:147:20 | call_target3_1(...) | test.rs:126:9:126:44 | ... .write_all(...) | -| test.rs:151:1:151:7 | Attr | test.rs:153:5:153:12 | bad3_3(...) | -| test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ... .write(...) | -| test.rs:169:1:169:7 | Attr | test.rs:171:5:171:15 | ...::stdout(...) | +| test.rs:29:1:29:13 | Attr | test.rs:29:1:32:1 | fn bad1_1 | +| test.rs:29:1:32:1 | fn bad1_1 | test.rs:31:9:31:25 | ...::stdout(...) | +| test.rs:34:1:34:13 | Attr | test.rs:34:1:37:1 | fn bad1_2 | +| test.rs:34:1:37:1 | fn bad1_2 | test.rs:36:9:36:25 | ...::stdout(...) | +| test.rs:39:1:44:1 | fn bad1_3 | test.rs:43:9:43:25 | ...::stdout(...) | +| test.rs:40:1:40:13 | Attr | test.rs:39:1:44:1 | fn bad1_3 | +| test.rs:51:1:51:7 | Attr | test.rs:51:1:54:1 | fn bad2_1 | +| test.rs:51:1:54:1 | fn bad2_1 | test.rs:53:9:53:16 | stdout(...) | +| test.rs:56:1:56:7 | Attr | test.rs:56:1:59:1 | fn bad2_2 | +| test.rs:56:1:59:1 | fn bad2_2 | test.rs:58:9:58:16 | stderr(...) | +| test.rs:61:1:61:7 | Attr | test.rs:61:1:64:1 | fn bad2_3 | +| test.rs:61:1:64:1 | fn bad2_3 | test.rs:63:14:63:28 | ...::_print(...) | +| test.rs:66:1:66:7 | Attr | test.rs:66:1:70:1 | fn bad2_4 | +| test.rs:66:1:70:1 | fn bad2_4 | test.rs:69:9:69:24 | ...::stdin(...) | +| test.rs:88:1:88:7 | Attr | test.rs:88:1:91:1 | fn bad2_7 | +| test.rs:88:1:91:1 | fn bad2_7 | test.rs:90:5:90:35 | ...::sleep(...) | +| test.rs:95:1:95:7 | Attr | test.rs:95:1:98:1 | fn bad2_8 | +| test.rs:95:1:98:1 | fn bad2_8 | test.rs:97:5:97:23 | ...::exit(...) | +| test.rs:125:1:127:1 | fn call_target3_1 | test.rs:126:9:126:16 | stderr(...) | +| test.rs:125:1:127:1 | fn call_target3_1 | test.rs:126:9:126:44 | ... .write_all(...) | +| test.rs:129:1:129:7 | Attr | test.rs:129:1:132:1 | fn bad3_1 | +| test.rs:129:1:132:1 | fn bad3_1 | test.rs:131:5:131:20 | call_target3_1(...) | +| test.rs:131:5:131:20 | call_target3_1(...) | test.rs:125:1:127:1 | fn call_target3_1 | +| test.rs:145:1:145:7 | Attr | test.rs:145:1:149:1 | fn bad3_3 | +| test.rs:145:1:149:1 | fn bad3_3 | test.rs:147:5:147:20 | call_target3_1(...) | +| test.rs:147:5:147:20 | call_target3_1(...) | test.rs:125:1:127:1 | fn call_target3_1 | +| test.rs:169:1:169:7 | Attr | test.rs:169:1:172:1 | fn bad4_1 | +| test.rs:169:1:172:1 | fn bad4_1 | test.rs:171:5:171:15 | ...::stdout(...) | From ed22f49cddde7a36039c508e1d0a186ea754cd54 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:58:06 +0000 Subject: [PATCH 31/63] Rust: Make ql-for-ql happy. --- .../queries/security/CWE-696/BadCtorInitialization.ql | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index e8f9c28b387..1d1ffe529b1 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -40,8 +40,8 @@ class StdCall extends Expr { class PathElement = AstNode; /** - * A candidate edge for the query that is reachable from - * a source. + * Holds if (`pred`, `succ`) represents a candidate edge for the query that is + * reachable from a source. */ predicate edgesFwd(PathElement pred, PathElement succ) { // attribute (source) -> callable @@ -57,9 +57,9 @@ predicate edgesFwd(PathElement pred, PathElement succ) { } /** - * An edge for the query that is reachable from a source and backwards - * reachable from a sink (adding the backwards reachability constraint - * reduces the amount of output data produced). + * Holds if (`pred`, `succ`) represents an edge for the query that is reachable + * from a source and backwards reachable from a sink (adding the backwards + * reachability constraint reduces the amount of output data produced). */ query predicate edges(PathElement pred, PathElement succ) { edgesFwd(pred, succ) and From 0865397e29b9c1dc374a8fb11faebe4c8bd7b6c4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:05:42 +0000 Subject: [PATCH 32/63] Rust: Address nit. --- rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index 1d1ffe529b1..c7a3e0d1cda 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -71,6 +71,6 @@ query predicate edges(PathElement pred, PathElement succ) { } from CtorAttr source, StdCall sink -where edges*(source, sink) +where edges+(source, sink) select sink, source, sink, "Call to " + sink.toString() + " in a function with the " + source.getWhichAttr() + " attribute." From b57a37479b25648a0cdd3925e10a9ed85f779fc7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 2 Dec 2024 15:15:46 +0100 Subject: [PATCH 33/63] Rust: make `File` usable in `codegen` --- misc/codegen/generators/dbschemegen.py | 3 +- misc/codegen/generators/qlgen.py | 35 ++++++++++---- misc/codegen/generators/rustgen.py | 16 ++++--- misc/codegen/generators/rusttestgen.py | 2 + misc/codegen/lib/ql.py | 6 +-- misc/codegen/lib/schema.py | 28 ++++++++--- misc/codegen/lib/schemadefs.py | 7 +-- misc/codegen/loaders/schemaloader.py | 6 ++- misc/codegen/templates/ql_class.mustache | 2 +- misc/codegen/templates/ql_db.mustache | 4 ++ misc/codegen/test/test_ql.py | 15 ------ misc/codegen/test/test_qlgen.py | 4 +- rust/extractor/src/generated/.generated.list | 2 +- rust/extractor/src/generated/top.rs | 40 ++++++++++++++++ rust/extractor/src/main.rs | 21 ++++----- rust/extractor/src/translate/base.rs | 5 +- rust/extractor/src/trap.rs | 14 +++--- rust/prefix.dbscheme | 7 --- rust/ql/.generated.list | 13 ++++-- rust/ql/.gitattributes | 3 ++ .../integration-tests/hello-project/steps.ql | 2 +- .../hello-project/summary.expected | 2 +- .../hello-workspace/steps.ql | 2 +- ...ummary.expected => summary.cargo.expected} | 2 +- .../summary.rust-project.expected | 17 +++++++ .../hello-workspace/test_workspace.py | 2 + rust/ql/lib/codeql/files/FileSystem.qll | 2 +- rust/ql/lib/codeql/rust/elements.qll | 1 + .../rust/elements/internal/ExtractorStep.qll | 13 ++++++ .../internal/ExtractorStepConstructor.qll | 14 ++++++ .../elements/internal/ExtractorStepImpl.qll | 32 +++++++++++++ .../internal/generated/ExtractorStep.qll | 45 ++++++++++++++++++ .../internal/generated/ParentChild.qll | 18 ++++++++ .../rust/elements/internal/generated/Raw.qll | 24 ++++++++++ .../elements/internal/generated/Synth.qll | 20 ++++++++ .../internal/generated/SynthConstructors.qll | 1 + .../codeql/rust/internal/ExtractorStep.qll | 46 ------------------- rust/ql/lib/rust.dbscheme | 19 ++++---- rust/schema/prelude.py | 9 ++++ swift/ql/.generated.list | 2 +- 40 files changed, 364 insertions(+), 142 deletions(-) rename rust/ql/integration-tests/hello-workspace/{summary.expected => summary.cargo.expected} (94%) create mode 100644 rust/ql/integration-tests/hello-workspace/summary.rust-project.expected create mode 100644 rust/ql/lib/codeql/rust/elements/internal/ExtractorStep.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/ExtractorStepConstructor.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/ExtractorStepImpl.qll create mode 100644 rust/ql/lib/codeql/rust/elements/internal/generated/ExtractorStep.qll delete mode 100644 rust/ql/lib/codeql/rust/internal/ExtractorStep.qll diff --git a/misc/codegen/generators/dbschemegen.py b/misc/codegen/generators/dbschemegen.py index 2c3cd5598d5..e2cc4220dc7 100755 --- a/misc/codegen/generators/dbschemegen.py +++ b/misc/codegen/generators/dbschemegen.py @@ -110,7 +110,8 @@ def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], a def get_declarations(data: schema.Schema): add_or_none_except = data.root_class.name if data.null else None - declarations = [d for cls in data.classes.values() for d in cls_to_dbscheme(cls, data.classes, add_or_none_except)] + declarations = [d for cls in data.classes.values() if not cls.imported for d in cls_to_dbscheme(cls, + data.classes, add_or_none_except)] if data.null: property_classes = { prop.type for cls in data.classes.values() for prop in cls.properties diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index e42c9d01552..feb2250bf3b 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -104,8 +104,17 @@ def _get_doc(cls: schema.Class, prop: schema.Property, plural=None): return f"{prop_name} of this {class_name}" -def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dict[str, schema.Class], +def _type_is_hideable(t: str, lookup: typing.Dict[str, schema.ClassBase]) -> bool: + if t in lookup: + match lookup[t]: + case schema.Class() as cls: + return "ql_hideable" in cls.pragmas + return False + + +def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dict[str, schema.ClassBase], prev_child: str = "") -> ql.Property: + args = dict( type=prop.type if not prop.is_predicate else "predicate", qltest_skip="qltest_skip" in prop.pragmas, @@ -115,7 +124,8 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic is_unordered=prop.is_unordered, description=prop.description, synth=bool(cls.synth) or prop.synth, - type_is_hideable="ql_hideable" in lookup[prop.type].pragmas if prop.type in lookup else False, + type_is_hideable=_type_is_hideable(prop.type, lookup), + type_is_codegen_class=prop.type in lookup and not lookup[prop.type].imported, internal="ql_internal" in prop.pragmas, ) ql_name = prop.pragmas.get("ql_name", prop.name) @@ -154,7 +164,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic return ql.Property(**args) -def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> ql.Class: +def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.ClassBase]) -> ql.Class: if "ql_name" in cls.pragmas: raise Error("ql_name is not supported yet for classes, only for properties") prev_child = "" @@ -391,14 +401,15 @@ def generate(opts, renderer): data = schemaloader.load_file(input) - classes = {name: get_ql_class(cls, data.classes) for name, cls in data.classes.items()} + classes = {name: get_ql_class(cls, data.classes) for name, cls in data.classes.items() if not cls.imported} if not classes: raise NoClasses root = next(iter(classes.values())) if root.has_children: raise RootElementHasChildren(root) - imports = {} + pre_imports = {n: cls.module for n, cls in data.classes.items() if cls.imported} + imports = dict(pre_imports) imports_impl = {} classes_used_by = {} cfg_classes = [] @@ -410,7 +421,7 @@ def generate(opts, renderer): force=opts.force) as renderer: db_classes = [cls for name, cls in classes.items() if not data.classes[name].synth] - renderer.render(ql.DbClasses(db_classes), out / "Raw.qll") + renderer.render(ql.DbClasses(classes=db_classes, imports=sorted(set(pre_imports.values()))), out / "Raw.qll") classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name)) for c in classes_by_dir_and_name: @@ -439,6 +450,8 @@ def generate(opts, renderer): renderer.render(cfg_classes_val, cfg_qll) for c in data.classes.values(): + if c.imported: + continue path = _get_path(c) path_impl = _get_path_impl(c) stub_file = stub_out / path_impl @@ -457,7 +470,7 @@ def generate(opts, renderer): renderer.render(class_public, class_public_file) # for example path/to/elements -> path/to/elements.qll - renderer.render(ql.ImportList([i for name, i in imports.items() if not classes[name].internal]), + renderer.render(ql.ImportList([i for name, i in imports.items() if name not in classes or not classes[name].internal]), include_file) elements_module = get_import(include_file, opts.root_dir) @@ -465,12 +478,15 @@ def generate(opts, renderer): renderer.render( ql.GetParentImplementation( classes=list(classes.values()), - imports=[elements_module] + [i for name, i in imports.items() if classes[name].internal], + imports=[elements_module] + [i for name, + i in imports.items() if name in classes and classes[name].internal], ), out / 'ParentChild.qll') if test_out: for c in data.classes.values(): + if c.imported: + continue if should_skip_qltest(c, data.classes): continue test_with_name = c.pragmas.get("qltest_test_with") @@ -500,7 +516,8 @@ def generate(opts, renderer): constructor_imports = [] synth_constructor_imports = [] stubs = {} - for cls in sorted(data.classes.values(), key=lambda cls: (cls.group, cls.name)): + for cls in sorted((cls for cls in data.classes.values() if not cls.imported), + key=lambda cls: (cls.group, cls.name)): synth_type = get_ql_synth_class(cls) if synth_type.is_final: final_synth_types.append(synth_type) diff --git a/misc/codegen/generators/rustgen.py b/misc/codegen/generators/rustgen.py index f4c977c0fdb..b47e5cc4bd9 100644 --- a/misc/codegen/generators/rustgen.py +++ b/misc/codegen/generators/rustgen.py @@ -49,7 +49,7 @@ def _get_field(cls: schema.Class, p: schema.Property) -> rust.Field: def _get_properties( - cls: schema.Class, lookup: dict[str, schema.Class], + cls: schema.Class, lookup: dict[str, schema.ClassBase], ) -> typing.Iterable[tuple[schema.Class, schema.Property]]: for b in cls.bases: yield from _get_properties(lookup[b], lookup) @@ -58,12 +58,14 @@ def _get_properties( def _get_ancestors( - cls: schema.Class, lookup: dict[str, schema.Class] + cls: schema.Class, lookup: dict[str, schema.ClassBase] ) -> typing.Iterable[schema.Class]: for b in cls.bases: base = lookup[b] - yield base - yield from _get_ancestors(base, lookup) + if not base.imported: + base = typing.cast(schema.Class, base) + yield base + yield from _get_ancestors(base, lookup) class Processor: @@ -71,7 +73,7 @@ class Processor: self._classmap = data.classes def _get_class(self, name: str) -> rust.Class: - cls = self._classmap[name] + cls = typing.cast(schema.Class, self._classmap[name]) properties = [ (c, p) for c, p in _get_properties(cls, self._classmap) @@ -101,8 +103,10 @@ class Processor: def get_classes(self): ret = {"": []} for k, cls in self._classmap.items(): - if not cls.synth: + if not cls.imported and not cls.synth: ret.setdefault(cls.group, []).append(self._get_class(cls.name)) + elif cls.imported: + ret[""].append(rust.Class(name=cls.name)) return ret diff --git a/misc/codegen/generators/rusttestgen.py b/misc/codegen/generators/rusttestgen.py index d360db27a65..e7a23fedacd 100644 --- a/misc/codegen/generators/rusttestgen.py +++ b/misc/codegen/generators/rusttestgen.py @@ -56,6 +56,8 @@ def generate(opts, renderer): registry=opts.ql_test_output / ".generated_tests.list", force=opts.force) as renderer: for cls in schema.classes.values(): + if cls.imported: + continue if (qlgen.should_skip_qltest(cls, schema.classes) or "rust_skip_doc_test" in cls.pragmas): continue diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py index 1182c7f5dc1..b9362a556ef 100644 --- a/misc/codegen/lib/ql.py +++ b/misc/codegen/lib/ql.py @@ -44,6 +44,7 @@ class Property: doc_plural: Optional[str] = None synth: bool = False type_is_hideable: bool = False + type_is_codegen_class: bool = False internal: bool = False cfg: bool = False @@ -66,10 +67,6 @@ class Property: article = "An" if self.singular[0] in "AEIO" else "A" return f"get{article}{self.singular}" - @property - def type_is_class(self): - return bool(self.type) and self.type[0].isupper() - @property def is_repeated(self): return bool(self.plural) @@ -191,6 +188,7 @@ class DbClasses: template: ClassVar = 'ql_db' classes: List[Class] = field(default_factory=list) + imports: List[str] = field(default_factory=list) @dataclass diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index 23f1aea2ba4..5178e61d384 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -3,7 +3,7 @@ import abc import typing from collections.abc import Iterable from dataclasses import dataclass, field -from typing import List, Set, Union, Dict, Optional +from typing import List, Set, Union, Dict, Optional, FrozenSet from enum import Enum, auto import functools @@ -87,8 +87,22 @@ class SynthInfo: @dataclass -class Class: +class ClassBase: + imported: typing.ClassVar[bool] name: str + + +@dataclass +class ImportedClass(ClassBase): + imported: typing.ClassVar[bool] = True + + module: str + + +@dataclass +class Class(ClassBase): + imported: typing.ClassVar[bool] = False + bases: List[str] = field(default_factory=list) derived: Set[str] = field(default_factory=set) properties: List[Property] = field(default_factory=list) @@ -133,7 +147,7 @@ class Class: @dataclass class Schema: - classes: Dict[str, Class] = field(default_factory=dict) + classes: Dict[str, ClassBase] = field(default_factory=dict) includes: List[str] = field(default_factory=list) null: Optional[str] = None @@ -155,7 +169,7 @@ class Schema: predicate_marker = object() -TypeRef = Union[type, str] +TypeRef = type | str | ImportedClass def get_type_name(arg: TypeRef) -> str: @@ -164,6 +178,8 @@ def get_type_name(arg: TypeRef) -> str: return arg.__name__ case str(): return arg + case ImportedClass(): + return arg.name case _: raise Error(f"Not a schema type or string ({arg})") @@ -172,9 +188,9 @@ def _make_property(arg: object) -> Property: match arg: case _ if arg is predicate_marker: return PredicateProperty() - case str() | type(): + case (str() | type() | ImportedClass()) as arg: return SingleProperty(type=get_type_name(arg)) - case Property(): + case Property() as arg: return arg case _: raise Error(f"Illegal property specifier {arg}") diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index 8651240c1a3..c81b2f2e215 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -8,8 +8,6 @@ from misc.codegen.lib import schema as _schema import inspect as _inspect from dataclasses import dataclass as _dataclass -from misc.codegen.lib.schema import Property - _set = set @@ -69,6 +67,9 @@ def include(source: str): _inspect.currentframe().f_back.f_locals.setdefault("includes", []).append(source) +imported = _schema.ImportedClass + + @_dataclass class _Namespace: """ simple namespacing mechanism """ @@ -264,7 +265,7 @@ class _PropertyModifierList(_schema.PropertyModifier): def __or__(self, other: _schema.PropertyModifier): return _PropertyModifierList(self._mods + (other,)) - def modify(self, prop: Property): + def modify(self, prop: _schema.Property): for m in self._mods: m.modify(prop) diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py index dd1edee1de0..3b5f20cbbed 100644 --- a/misc/codegen/loaders/schemaloader.py +++ b/misc/codegen/loaders/schemaloader.py @@ -132,6 +132,7 @@ def _check_test_with(classes: typing.Dict[str, schema.Class]): def load(m: types.ModuleType) -> schema.Schema: includes = set() classes = {} + imported_classes = {} known = {"int", "string", "boolean"} known.update(n for n in m.__dict__ if not n.startswith("__")) import misc.codegen.lib.schemadefs as defs @@ -146,6 +147,9 @@ def load(m: types.ModuleType) -> schema.Schema: continue if isinstance(data, types.ModuleType): continue + if isinstance(data, schema.ImportedClass): + imported_classes[name] = data + continue cls = _get_class(data) if classes and not cls.bases: raise schema.Error( @@ -162,7 +166,7 @@ def load(m: types.ModuleType) -> schema.Schema: _fill_hideable_information(classes) _check_test_with(classes) - return schema.Schema(includes=includes, classes=_toposort_classes_by_group(classes), null=null) + return schema.Schema(includes=includes, classes=imported_classes | _toposort_classes_by_group(classes), null=null) def load_file(path: pathlib.Path) -> schema.Schema: diff --git a/misc/codegen/templates/ql_class.mustache b/misc/codegen/templates/ql_class.mustache index da6524d6d37..d39238ff9ba 100644 --- a/misc/codegen/templates/ql_class.mustache +++ b/misc/codegen/templates/ql_class.mustache @@ -113,7 +113,7 @@ module Generated { */ {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { {{^synth}} - {{^is_predicate}}result = {{/is_predicate}}{{#type_is_class}}Synth::convert{{type}}FromRaw({{/type_is_class}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}){{#type_is_class}}){{/type_is_class}} + {{^is_predicate}}result = {{/is_predicate}}{{#type_is_codegen_class}}Synth::convert{{type}}FromRaw({{/type_is_codegen_class}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}){{#type_is_codegen_class}}){{/type_is_codegen_class}} {{/synth}} {{#synth}} none() diff --git a/misc/codegen/templates/ql_db.mustache b/misc/codegen/templates/ql_db.mustache index 8326bb3adb7..e63e0aae903 100644 --- a/misc/codegen/templates/ql_db.mustache +++ b/misc/codegen/templates/ql_db.mustache @@ -3,6 +3,10 @@ * This module holds thin fully generated class definitions around DB entities. */ module Raw { + {{#imports}} + private import {{.}} + {{/imports}} + {{#classes}} /** * INTERNAL: Do not use. diff --git a/misc/codegen/test/test_ql.py b/misc/codegen/test/test_ql.py index eef840ddad6..e326e65a9e4 100644 --- a/misc/codegen/test/test_ql.py +++ b/misc/codegen/test/test_ql.py @@ -12,21 +12,6 @@ def test_property_has_first_table_param_marked(): assert [p.param for p in prop.tableparams] == tableparams -@pytest.mark.parametrize("type,expected", [ - ("Foo", True), - ("Bar", True), - ("foo", False), - ("bar", False), - (None, False), -]) -def test_property_is_a_class(type, expected): - tableparams = ["a", "result", "b"] - expected_tableparams = ["a", "result" if expected else "result", "b"] - prop = ql.Property("Prop", type, tableparams=tableparams) - assert prop.type_is_class is expected - assert [p.param for p in prop.tableparams] == expected_tableparams - - indefinite_getters = [ ("Argument", "getAnArgument"), ("Element", "getAnElement"), diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index 684d3d6a1a1..431f25d5aae 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -448,7 +448,8 @@ def test_single_class_property(generate_classes, is_child, prev_child): ql.Property(singular="Foo", type="Bar", tablename="my_objects", tableparams=[ "this", "result"], - prev_child=prev_child, doc="foo of this my object"), + prev_child=prev_child, doc="foo of this my object", + type_is_codegen_class=True), ], )), "Bar.qll": (a_ql_class_public(name="Bar"), a_ql_stub(name="Bar"), a_ql_class(name="Bar", final=True, imports=[stub_import_prefix + "Bar"])), @@ -1006,6 +1007,7 @@ def test_hideable_property(generate_classes): final=True, properties=[ ql.Property(singular="X", type="MyObject", tablename="others", type_is_hideable=True, + type_is_codegen_class=True, tableparams=["this", "result"], doc="x of this other"), ])), } diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index ec1f2815442..149169eecf0 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs 272ecf2f56f35211d2449dbf55b1907d8414a8e4cceded03fd12f6f599852c73 272ecf2f56f35211d2449dbf55b1907d8414a8e4cceded03fd12f6f599852c73 +top.rs 0213b8cffeaf38c561be6362078994a150e532f580f0b7a9373252155f595005 0213b8cffeaf38c561be6362078994a150e532f580f0b7a9373252155f595005 diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index 73048514fda..fd6dbadc289 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -4,6 +4,15 @@ use crate::trap; +#[derive(Debug)] +pub struct File { + _unused: () +} + +impl trap::TrapClass for File { + fn class_name() -> &'static str { "File" } +} + #[derive(Debug)] pub struct Element { _unused: () @@ -13,6 +22,37 @@ impl trap::TrapClass for Element { fn class_name() -> &'static str { "Element" } } +#[derive(Debug)] +pub struct ExtractorStep { + pub id: trap::TrapId, + pub action: String, + pub file: trap::Label, + pub duration_ms: usize, +} + +impl trap::TrapEntry for ExtractorStep { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("extractor_steps", vec![id.into(), self.action.into(), self.file.into(), self.duration_ms.into()]); + } +} + +impl trap::TrapClass for ExtractorStep { + fn class_name() -> &'static str { "ExtractorStep" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme ExtractorStep is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct Locatable { _unused: () diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index a3258f16d09..86aeb09f6a4 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -1,5 +1,6 @@ use crate::diagnostics::{emit_extraction_diagnostics, ExtractionStep}; use crate::rust_analyzer::path_to_file_id; +use crate::trap::TrapId; use anyhow::Context; use archive::Archiver; use log::{info, warn}; @@ -143,21 +144,17 @@ impl<'a> Extractor<'a> { emit_extraction_diagnostics(start, cfg, &self.steps)?; let mut trap = self.traps.create("diagnostics", "extraction"); for step in self.steps { - let file_label = trap.emit_file(&step.file); - let step_label = trap.writer.fresh_id(); - let ms = usize::try_from(step.ms).unwrap_or_else(|_e| { + let file = trap.emit_file(&step.file); + let duration_ms = usize::try_from(step.ms).unwrap_or_else(|_e| { warn!("extraction step duration overflowed ({step:?})"); i32::MAX as usize }); - trap.writer.add_tuple( - "extractor_steps", - vec![ - step_label.into(), - format!("{:?}", step.action).into(), - file_label.into(), - ms.into(), - ], - ); + trap.emit(generated::ExtractorStep { + id: TrapId::Star, + action: format!("{:?}", step.action), + file, + duration_ms, + }); } trap.commit()?; Ok(()) diff --git a/rust/extractor/src/translate/base.rs b/rust/extractor/src/translate/base.rs index 003c86919b6..396816c6a0c 100644 --- a/rust/extractor/src/translate/base.rs +++ b/rust/extractor/src/translate/base.rs @@ -4,7 +4,6 @@ use crate::generated::{self}; use crate::rust_analyzer::FileSemanticInformation; use crate::trap::{DiagnosticSeverity, TrapFile, TrapId}; use crate::trap::{Label, TrapClass}; -use codeql_extractor::trap::{self}; use itertools::Either; use log::Level; use ra_ap_base_db::salsa::InternKey; @@ -65,7 +64,7 @@ macro_rules! emit_detached { pub struct Translator<'a> { pub trap: TrapFile, path: &'a str, - label: trap::Label, + label: Label, line_index: LineIndex, file_id: Option, pub semantics: Option<&'a Semantics<'a, RootDatabase>>, @@ -75,7 +74,7 @@ impl<'a> Translator<'a> { pub fn new( trap: TrapFile, path: &'a str, - label: trap::Label, + label: Label, line_index: LineIndex, semantic_info: Option<&FileSemanticInformation<'a>>, ) -> Translator<'a> { diff --git a/rust/extractor/src/trap.rs b/rust/extractor/src/trap.rs index c993fa046a7..6c8e9b2c3c8 100644 --- a/rust/extractor/src/trap.rs +++ b/rust/extractor/src/trap.rs @@ -1,5 +1,5 @@ -use crate::config; use crate::config::Compression; +use crate::{config, generated}; use codeql_extractor::{extractor, file_paths, trap}; use log::debug; use ra_ap_ide_db::line_index::LineCol; @@ -138,7 +138,7 @@ pub enum DiagnosticSeverity { impl TrapFile { pub fn emit_location_label( &mut self, - file_label: UntypedLabel, + file_label: Label, start: LineCol, end: LineCol, ) -> UntypedLabel { @@ -149,7 +149,7 @@ impl TrapFile { extractor::location_label( &mut self.writer, trap::Location { - file_label, + file_label: file_label.as_untyped(), start_line, start_column, end_line, @@ -159,7 +159,7 @@ impl TrapFile { } pub fn emit_location( &mut self, - file_label: UntypedLabel, + file_label: Label, entity_label: Label, start: LineCol, end: LineCol, @@ -192,8 +192,10 @@ impl TrapFile { ], ); } - pub fn emit_file(&mut self, absolute_path: &Path) -> trap::Label { - extractor::populate_file(&mut self.writer, absolute_path) + pub fn emit_file(&mut self, absolute_path: &Path) -> Label { + let untyped = extractor::populate_file(&mut self.writer, absolute_path); + // SAFETY: populate_file emits `@file` typed labels + unsafe { Label::from_untyped(untyped) } } pub fn label(&mut self, id: TrapId) -> Label { diff --git a/rust/prefix.dbscheme b/rust/prefix.dbscheme index 5ccbd3438d1..4810e11069d 100644 --- a/rust/prefix.dbscheme +++ b/rust/prefix.dbscheme @@ -3,10 +3,3 @@ locatable_locations( int id: @locatable ref, int location: @location_default ref ); - -extractor_steps( - unique int id: @extractor_step, - string action: string ref, - int file: @file ref, - int duration_ms: int ref -) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index b0c71e3ef01..95e3cd9d349 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -222,6 +222,8 @@ lib/codeql/rust/elements/internal/ExternCrateImpl.qll ade4df9d3f87daf6534b8e79ff lib/codeql/rust/elements/internal/ExternItemImpl.qll 577c8ac387c47746e3b45f943374c7ab641e8ad119e8591c31f219a5f08d3a29 bba88b974d1c03c78e0caf3d8f4118426d2aa8bd6ffd6f59a3da8ff1524a173f lib/codeql/rust/elements/internal/ExternItemListConstructor.qll 9e4f6a036707c848c0553119272fd2b11c1740dd9910a626a9a0cf68a55b249b efde86b18bd419154fb5b6d28790a14ea989b317d84b5c1ddbdfb29c6924fd86 lib/codeql/rust/elements/internal/ExternItemListImpl.qll e89d0cf938f6e137ba1ce7907a923b1ab2be7be2fdd642c3b7a722f11b9199f8 85906d3ce89e5abc301cc96ea5104d53e90af3f5f22f8d54ec437687096e39d8 +lib/codeql/rust/elements/internal/ExtractorStep.qll 1c65668007ea71d05333e44132eccc01dc2a2b4908fb37d0a73995119d3ed5f0 8cbe1eeb35bc2bc95c1b7765070d1ff58aae03fd28dc94896b091858eea40efe +lib/codeql/rust/elements/internal/ExtractorStepConstructor.qll 00c527a3139ad399ea1efd0ebe4656372d70f6c4e79136bc497a6cb84becae8e 93817f3dddeaf2c0964ab31c2df451dcee0aeba7cb6520803d8ce42cefcb3703 lib/codeql/rust/elements/internal/FieldExprConstructor.qll b3be2c4ccaf2c8a1283f3d5349d7f4f49f87b35e310ef33491023c5ab6f3abc5 645d0d4073b032f6b7284fc36a10a6ec85596fb95c68f30c09504f2c5a6f789f lib/codeql/rust/elements/internal/FieldListImpl.qll 02a09d1d146030c68cead4614f4eef75854f19e55ed1eda60b34c4858a8d4a88 9b9f5e77546434c771d2f785119577ec46569a18473daa4169fb84a097369493 lib/codeql/rust/elements/internal/FnPtrTypeConstructor.qll 494c53ee599039c02145f91394d8dfe7635b32d03f9fcde5efcc99ced437fec8 992462b1b6b9e64b6201f3c6c232ca524f126efcb562c9f0c176677bb559f33c @@ -449,6 +451,7 @@ lib/codeql/rust/elements/internal/generated/ExternBlock.qll c292d804a1f8d2cf6a44 lib/codeql/rust/elements/internal/generated/ExternCrate.qll 35fea4e810a896c1656adb4682c4c3bc20283768073e26ae064189ce310433c8 fc504dff79ba758d89b10cd5049539fbc766ee9862ff495066cea26abf0b5e0b lib/codeql/rust/elements/internal/generated/ExternItem.qll 749b064ad60f32197d5b85e25929afe18e56e12f567b73e21e43e2fdf4c447e3 e2c2d423876675cf2dae399ca442aef7b2860319da9bfadeff29f2c6946f8de7 lib/codeql/rust/elements/internal/generated/ExternItemList.qll 6bc97fdae6c411cab5c501129c1d6c2321c1011cccb119515d75d07dc55c253b 6b5aa808025c0a4270cac540c07ba6faede1b3c70b8db5fd89ec5d46df9041b2 +lib/codeql/rust/elements/internal/generated/ExtractorStep.qll b83ce7f18009bdd36374260652c2a8a5cd5a9b5404a1c147bbec49ad251e43f3 e6e55595300126f9c5a6fd7bde5321b2a0026b491326114d16fcc2395a1fc483 lib/codeql/rust/elements/internal/generated/FieldExpr.qll 3e506b5cb93793ec30f56bb637a600db869fcba6181b068516a671d55c362739 7bbf953696d763ad6b210f378f487ba85b875fa115b22c0c0508599a63633502 lib/codeql/rust/elements/internal/generated/FieldList.qll 43c13c6e3c9ba75a7a4cb870fc4f18752001584d48b9df0734055a6ebb789331 7c51b0b13eb02f1286d3365e53a976ba2655c4dbd8e735bc11c8b205c829e1ee lib/codeql/rust/elements/internal/generated/FnPtrType.qll 748d766dbefd19a7d644734c57885eeede66897029bbfe1b87919517f43bfde2 5a7d80acc00e56594ed85026a8ea4923104d2e98c2e42db8c5bcd32ddd164e48 @@ -512,7 +515,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60 lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6 lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273 -lib/codeql/rust/elements/internal/generated/ParentChild.qll db7a782f11a14305acc666c865118475e2d324d2bf5d4110b157e1d488b62b75 3b5d31528d0baa0ceee139097e93461d18503797a1507288dc43428f378500e2 +lib/codeql/rust/elements/internal/generated/ParentChild.qll 92402f931bffc872446b7e6d0cc8fd41ff4dc72d0708f9db9b50ac48322d4bc9 2ecc512859db4cf98c680cf948f6dcb89334f999ec58b8d34a0ffd5c385dcef4 lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll 4c1c8e840ed57880e574142b081b11d7a7428a009f10e3aa8f4645e211f6b2e0 989668cf0f1bdee7557e2f97c01e41d2a56848227fed41477833f5fc1e1d35f6 lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140 @@ -525,7 +528,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b -lib/codeql/rust/elements/internal/generated/Raw.qll 7de290d66bd594f4c5b5a296502792e803e9f1084bb2616d9774196e33b16c87 28150fdd3cff3bb49b407f0c2119602be13e78cbb1f8fd749edd31f5d9772f7a +lib/codeql/rust/elements/internal/generated/Raw.qll c302331305186bdf4cfe2aa08395778be84d4959bb535353e1bc9979094e3de2 f40d71d96218cd6dc9b544dfe4aa2d6d035d21ca414ba1cf456741c90076e3db lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40 lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1 lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0 @@ -551,8 +554,8 @@ lib/codeql/rust/elements/internal/generated/Static.qll 5fbd6879858cf356d4bdaa6da lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b lib/codeql/rust/elements/internal/generated/StmtList.qll a667193e32341e17400867c6e359878c4e645ef9f5f4d97676afc0283a33a026 a320ed678ee359302e2fc1b70a9476705cd616fcfa44a499d32f0c7715627f73 lib/codeql/rust/elements/internal/generated/Struct.qll 4d57f0db12dc7ad3e31e750a24172ef1505406b4dab16386af0674bd18bf8f4b 1a73c83df926b996f629316f74c61ea775be04532ab61b56af904223354f033e -lib/codeql/rust/elements/internal/generated/Synth.qll 65873a7fa44e223edc5e76cc768591a036eb2550960a6b6882476f43a01aefba 3e08e2bdfba53ae26d8f48f2d240b92b44c603f03105518c37a963e0cbe63e3f -lib/codeql/rust/elements/internal/generated/SynthConstructors.qll e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f +lib/codeql/rust/elements/internal/generated/Synth.qll 678edaf70ea0fc2680e53c8cdde0114228be6d8935845f86ccec48274e32d82d 963abedc8cfa60b63db61f250e7da26fc886148408d5340ed500bad3e6dfd7b0 +lib/codeql/rust/elements/internal/generated/SynthConstructors.qll f33931fbdee7e1ca8b5e52af771ea725fef72a2e37fffb628f5270e79d3571a1 f33931fbdee7e1ca8b5e52af771ea725fef72a2e37fffb628f5270e79d3571a1 lib/codeql/rust/elements/internal/generated/Token.qll 77a91a25ca5669703cf3a4353b591cef4d72caa6b0b9db07bb9e005d69c848d1 2fdffc4882ed3a6ca9ac6d1fb5f1ac5a471ca703e2ffdc642885fa558d6e373b lib/codeql/rust/elements/internal/generated/TokenTree.qll 8577c2b097c1be2f0f7daa5acfcf146f78674a424d99563e08a84dd3e6d91b46 d2f30764e84dbfc0a6a5d3d8a5f935cd432413688cb32da9c94e420fbc10665c lib/codeql/rust/elements/internal/generated/Trait.qll 8fa41b50fa0f68333534f2b66bb4ec8e103ff09ac8fa5c2cc64bc04beafec205 ce1c9aa6d0e2f05d28aab8e1165c3b9fb8e24681ade0cf6a9df2e8617abeae7e @@ -586,7 +589,7 @@ lib/codeql/rust/elements/internal/generated/WhileExpr.qll 7edf1f23fbf953a2baabcd lib/codeql/rust/elements/internal/generated/WildcardPat.qll d74b70b57a0a66bfae017a329352a5b27a6b9e73dd5521d627f680e810c6c59e 4b913b548ba27ff3c82fcd32cf996ff329cb57d176d3bebd0fcef394486ea499 lib/codeql/rust/elements/internal/generated/YeetExpr.qll cac328200872a35337b4bcb15c851afb4743f82c080f9738d295571eb01d7392 94af734eea08129b587fed849b643e7572800e8330c0b57d727d41abda47930b lib/codeql/rust/elements/internal/generated/YieldExpr.qll 37e5f0c1e373a22bbc53d8b7f2c0e1f476e5be5080b8437c5e964f4e83fad79a 4a9a68643401637bf48e5c2b2f74a6bf0ddcb4ff76f6bffb61d436b685621e85 -lib/codeql/rust/elements.qll ced76fbeebc6e2e972ecaed65ef97851f90a215cf330f28a0f31a253f1c03442 ced76fbeebc6e2e972ecaed65ef97851f90a215cf330f28a0f31a253f1c03442 +lib/codeql/rust/elements.qll 34cd7db7d8c3cfeac77f23d07418df951158feea426df6ad7d80ebebbcb4e3f2 34cd7db7d8c3cfeac77f23d07418df951158feea426df6ad7d80ebebbcb4e3f2 test/extractor-tests/generated/Abi/Abi.ql 7f6e7dc4af86eca3ebdc79b10373988cd0871bd78b51997d3cffd969105e5fdd 2f936b6ca005c6157c755121584410c03e4a3949c23bee302fbe05ee10ce118f test/extractor-tests/generated/Abi/Abi_getAbiString.ql a496762fcec5a0887b87023bbf93e9b650f02e20113e25c44d6e4281ae8f5335 14109c7ce11ba25e3cd6e7f1b3fcb4cb00622f2a4eac91bfe43145c5f366bc52 test/extractor-tests/generated/ArgList/ArgList.ql e412927756e72165d0e7c5c9bd3fca89d08197bbf760db8fb7683c64bb2229bc 043dba8506946fbb87753e22c387987d7eded6ddb963aa067f9e60ef9024d684 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index c75ea349c0d..cca884a1426 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -224,6 +224,8 @@ /lib/codeql/rust/elements/internal/ExternItemImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ExternItemListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ExternItemListImpl.qll linguist-generated +/lib/codeql/rust/elements/internal/ExtractorStep.qll linguist-generated +/lib/codeql/rust/elements/internal/ExtractorStepConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/FieldExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/FieldListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/FnPtrTypeConstructor.qll linguist-generated @@ -451,6 +453,7 @@ /lib/codeql/rust/elements/internal/generated/ExternCrate.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ExternItem.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ExternItemList.qll linguist-generated +/lib/codeql/rust/elements/internal/generated/ExtractorStep.qll linguist-generated /lib/codeql/rust/elements/internal/generated/FieldExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/FieldList.qll linguist-generated /lib/codeql/rust/elements/internal/generated/FnPtrType.qll linguist-generated diff --git a/rust/ql/integration-tests/hello-project/steps.ql b/rust/ql/integration-tests/hello-project/steps.ql index eb8f9a05adb..17358a1c100 100644 --- a/rust/ql/integration-tests/hello-project/steps.ql +++ b/rust/ql/integration-tests/hello-project/steps.ql @@ -1,4 +1,4 @@ -import codeql.rust.internal.ExtractorStep +import codeql.rust.elements.internal.ExtractorStep from ExtractorStep step select step diff --git a/rust/ql/integration-tests/hello-project/summary.expected b/rust/ql/integration-tests/hello-project/summary.expected index 09e03490eb1..44c14e790fe 100644 --- a/rust/ql/integration-tests/hello-project/summary.expected +++ b/rust/ql/integration-tests/hello-project/summary.expected @@ -1,4 +1,4 @@ -| Elements extracted | 50 | +| Elements extracted | 65 | | Elements unextracted | 0 | | Extraction errors | 0 | | Extraction warnings | 1 | diff --git a/rust/ql/integration-tests/hello-workspace/steps.ql b/rust/ql/integration-tests/hello-workspace/steps.ql index eb8f9a05adb..17358a1c100 100644 --- a/rust/ql/integration-tests/hello-workspace/steps.ql +++ b/rust/ql/integration-tests/hello-workspace/steps.ql @@ -1,4 +1,4 @@ -import codeql.rust.internal.ExtractorStep +import codeql.rust.elements.internal.ExtractorStep from ExtractorStep step select step diff --git a/rust/ql/integration-tests/hello-workspace/summary.expected b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected similarity index 94% rename from rust/ql/integration-tests/hello-workspace/summary.expected rename to rust/ql/integration-tests/hello-workspace/summary.cargo.expected index 4e800e60bd0..ec1abea6252 100644 --- a/rust/ql/integration-tests/hello-workspace/summary.expected +++ b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected @@ -1,4 +1,4 @@ -| Elements extracted | 72 | +| Elements extracted | 86 | | Elements unextracted | 0 | | Extraction errors | 0 | | Extraction warnings | 0 | diff --git a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected new file mode 100644 index 00000000000..5ca38e5a90c --- /dev/null +++ b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected @@ -0,0 +1,17 @@ +| Elements extracted | 85 | +| Elements unextracted | 0 | +| Extraction errors | 0 | +| Extraction warnings | 0 | +| Files extracted - total | 4 | +| Files extracted - with errors | 0 | +| Files extracted - without errors | 4 | +| Inconsistencies - AST | 0 | +| Inconsistencies - CFG | 0 | +| Inconsistencies - data flow | 0 | +| Lines of code extracted | 9 | +| Lines of user code extracted | 9 | +| Macro calls - resolved | 2 | +| Macro calls - total | 2 | +| Macro calls - unresolved | 0 | +| Taint sources - active | 0 | +| Taint sources - total | 0 | diff --git a/rust/ql/integration-tests/hello-workspace/test_workspace.py b/rust/ql/integration-tests/hello-workspace/test_workspace.py index 7f9e3700c3a..fe8dbc69141 100644 --- a/rust/ql/integration-tests/hello-workspace/test_workspace.py +++ b/rust/ql/integration-tests/hello-workspace/test_workspace.py @@ -2,11 +2,13 @@ import pytest @pytest.mark.ql_test("steps.ql", expected=".cargo.expected") +@pytest.mark.ql_test("summary.qlref", expected=".cargo.expected") def test_cargo(codeql, rust, cargo, check_source_archive, rust_check_diagnostics): rust_check_diagnostics.expected_suffix = ".cargo.expected" codeql.database.create() @pytest.mark.ql_test("steps.ql", expected=".rust-project.expected") +@pytest.mark.ql_test("summary.qlref", expected=".rust-project.expected") def test_rust_project(codeql, rust, rust_project, check_source_archive, rust_check_diagnostics): rust_check_diagnostics.expected_suffix = ".rust-project.expected" codeql.database.create() diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index c83680f7ec6..b13793b3600 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -6,7 +6,7 @@ private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode private import codeql.rust.elements.Comment private import codeql.rust.Diagnostics -private import codeql.rust.internal.ExtractorStep +private import codeql.rust.elements.internal.ExtractorStep private module Input implements InputSig { abstract class ContainerBase extends @container { diff --git a/rust/ql/lib/codeql/rust/elements.qll b/rust/ql/lib/codeql/rust/elements.qll index e37dde90d61..7954e0e2b14 100644 --- a/rust/ql/lib/codeql/rust/elements.qll +++ b/rust/ql/lib/codeql/rust/elements.qll @@ -3,6 +3,7 @@ * This module exports all modules providing `Element` subclasses. */ +import codeql.files.FileSystem import codeql.rust.elements.Abi import codeql.rust.elements.Addressable import codeql.rust.elements.ArgList diff --git a/rust/ql/lib/codeql/rust/elements/internal/ExtractorStep.qll b/rust/ql/lib/codeql/rust/elements/internal/ExtractorStep.qll new file mode 100644 index 00000000000..64a4931ef43 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/ExtractorStep.qll @@ -0,0 +1,13 @@ +// generated by codegen, do not edit +/** + * This module provides the class `ExtractorStep`. + */ + +private import ExtractorStepImpl +import codeql.rust.elements.Element +import codeql.files.FileSystem + +/** + * INTERNAL: Do not use. + */ +final class ExtractorStep = Impl::ExtractorStep; diff --git a/rust/ql/lib/codeql/rust/elements/internal/ExtractorStepConstructor.qll b/rust/ql/lib/codeql/rust/elements/internal/ExtractorStepConstructor.qll new file mode 100644 index 00000000000..76050bf99f8 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/ExtractorStepConstructor.qll @@ -0,0 +1,14 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module defines the hook used internally to tweak the characteristic predicate of + * `ExtractorStep` synthesized instances. + * INTERNAL: Do not use. + */ + +private import codeql.rust.elements.internal.generated.Raw + +/** + * The characteristic predicate of `ExtractorStep` synthesized instances. + * INTERNAL: Do not use. + */ +predicate constructExtractorStep(Raw::ExtractorStep id) { any() } diff --git a/rust/ql/lib/codeql/rust/elements/internal/ExtractorStepImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ExtractorStepImpl.qll new file mode 100644 index 00000000000..95c677e845e --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/ExtractorStepImpl.qll @@ -0,0 +1,32 @@ +/** + * This module provides a hand-modifiable wrapper around the generated class `ExtractorStep`. + * + * INTERNAL: Do not use. + */ + +private import codeql.rust.elements.internal.generated.ExtractorStep + +/** + * INTERNAL: This module contains the customizable definition of `ExtractorStep` and should not + * be referenced directly. + */ +module Impl { + class ExtractorStep extends Generated::ExtractorStep { + override string toString() { + result = this.getAction() + "(" + this.getFile().getAbsolutePath() + ")" + } + + /** + * Provides location information for this step. + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getFile().getAbsolutePath() = filepath and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 + } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ExtractorStep.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ExtractorStep.qll new file mode 100644 index 00000000000..c2d7838865b --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ExtractorStep.qll @@ -0,0 +1,45 @@ +// generated by codegen, do not edit +/** + * This module provides the generated definition of `ExtractorStep`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.elements.internal.generated.Synth +private import codeql.rust.elements.internal.generated.Raw +import codeql.rust.elements.internal.ElementImpl::Impl as ElementImpl +import codeql.files.FileSystem + +/** + * INTERNAL: This module contains the fully generated definition of `ExtractorStep` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::ExtractorStep` class directly. + * Use the subclass `ExtractorStep`, where the following predicates are available. + */ + class ExtractorStep extends Synth::TExtractorStep, ElementImpl::Element { + override string getAPrimaryQlClass() { result = "ExtractorStep" } + + /** + * Gets the action of this extractor step. + */ + string getAction() { + result = Synth::convertExtractorStepToRaw(this).(Raw::ExtractorStep).getAction() + } + + /** + * Gets the file of this extractor step. + */ + File getFile() { + result = Synth::convertExtractorStepToRaw(this).(Raw::ExtractorStep).getFile() + } + + /** + * Gets the duration ms of this extractor step. + */ + int getDurationMs() { + result = Synth::convertExtractorStepToRaw(this).(Raw::ExtractorStep).getDurationMs() + } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 6709629e8b4..0ba866f8ee2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -4,12 +4,28 @@ */ import codeql.rust.elements +import codeql.rust.elements.internal.ExtractorStep private module Impl { private Element getImmediateChildOfElement(Element e, int index, string partialPredicateCall) { none() } + private Element getImmediateChildOfExtractorStep( + ExtractorStep e, int index, string partialPredicateCall + ) { + exists(int b, int bElement, int n | + b = 0 and + bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and + n = bElement and + ( + none() + or + result = getImmediateChildOfElement(e, index - b, partialPredicateCall) + ) + ) + } + private Element getImmediateChildOfLocatable(Locatable e, int index, string partialPredicateCall) { exists(int b, int bElement, int n | b = 0 and @@ -3600,6 +3616,8 @@ private module Impl { // * none() simplifies generation, as we can append `or ...` without a special case for the first item none() or + result = getImmediateChildOfExtractorStep(e, index, partialAccessor) + or result = getImmediateChildOfFormat(e, index, partialAccessor) or result = getImmediateChildOfFormatArgument(e, index, partialAccessor) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 1c85daa22cf..96db2c99cf6 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -3,6 +3,8 @@ * This module holds thin fully generated class definitions around DB entities. */ module Raw { + private import codeql.files.FileSystem + /** * INTERNAL: Do not use. */ @@ -10,6 +12,28 @@ module Raw { string toString() { none() } } + /** + * INTERNAL: Do not use. + */ + class ExtractorStep extends @extractor_step, Element { + override string toString() { result = "ExtractorStep" } + + /** + * Gets the action of this extractor step. + */ + string getAction() { extractor_steps(this, result, _, _) } + + /** + * Gets the file of this extractor step. + */ + File getFile() { extractor_steps(this, _, result, _) } + + /** + * Gets the duration ms of this extractor step. + */ + int getDurationMs() { extractor_steps(this, _, _, result) } + } + /** * INTERNAL: Do not use. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll index 0b4fa39cd84..5284c0b8fde 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll @@ -134,6 +134,10 @@ module Synth { * INTERNAL: Do not use. */ TExternItemList(Raw::ExternItemList id) { constructExternItemList(id) } or + /** + * INTERNAL: Do not use. + */ + TExtractorStep(Raw::ExtractorStep id) { constructExtractorStep(id) } or /** * INTERNAL: Do not use. */ @@ -926,6 +930,12 @@ module Synth { */ TExternItemList convertExternItemListFromRaw(Raw::Element e) { result = TExternItemList(e) } + /** + * INTERNAL: Do not use. + * Converts a raw element to a synthesized `TExtractorStep`, if possible. + */ + TExtractorStep convertExtractorStepFromRaw(Raw::Element e) { result = TExtractorStep(e) } + /** * INTERNAL: Do not use. * Converts a raw element to a synthesized `TFieldExpr`, if possible. @@ -1803,6 +1813,8 @@ module Synth { * Converts a raw DB element to a synthesized `TElement`, if possible. */ TElement convertElementFromRaw(Raw::Element e) { + result = convertExtractorStepFromRaw(e) + or result = convertLocatableFromRaw(e) or result = convertUnextractedFromRaw(e) @@ -2312,6 +2324,12 @@ module Synth { */ Raw::Element convertExternItemListToRaw(TExternItemList e) { e = TExternItemList(result) } + /** + * INTERNAL: Do not use. + * Converts a synthesized `TExtractorStep` to a raw DB element, if possible. + */ + Raw::Element convertExtractorStepToRaw(TExtractorStep e) { e = TExtractorStep(result) } + /** * INTERNAL: Do not use. * Converts a synthesized `TFieldExpr` to a raw DB element, if possible. @@ -3187,6 +3205,8 @@ module Synth { * Converts a synthesized `TElement` to a raw DB element, if possible. */ Raw::Element convertElementToRaw(TElement e) { + result = convertExtractorStepToRaw(e) + or result = convertLocatableToRaw(e) or result = convertUnextractedToRaw(e) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/SynthConstructors.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/SynthConstructors.qll index 9b68c858c6a..8f7c2c61570 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/SynthConstructors.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/SynthConstructors.qll @@ -33,6 +33,7 @@ import codeql.rust.elements.internal.ExprStmtConstructor import codeql.rust.elements.internal.ExternBlockConstructor import codeql.rust.elements.internal.ExternCrateConstructor import codeql.rust.elements.internal.ExternItemListConstructor +import codeql.rust.elements.internal.ExtractorStepConstructor import codeql.rust.elements.internal.FieldExprConstructor import codeql.rust.elements.internal.FnPtrTypeConstructor import codeql.rust.elements.internal.ForExprConstructor diff --git a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll deleted file mode 100644 index 50e6ebafebf..00000000000 --- a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll +++ /dev/null @@ -1,46 +0,0 @@ -import codeql.files.FileSystem - -/** - * An extractor step, usable for debugging and diagnostics reasons. - * - * INTERNAL: Do not use. - */ -class ExtractorStep extends @extractor_step { - /** - * Gets the string representation of this extractor step. - */ - string toString() { - exists(File file, string action | - extractor_steps(this, action, file, _) and - result = action + "(" + file.getAbsolutePath() + ")" - ) - } - - /** - * Gets the action this extractor step carried out. - */ - string getAction() { extractor_steps(this, result, _, _) } - - /** - * Gets the file the extractor step was carried out on. - */ - File getFile() { extractor_steps(this, _, result, _) } - - /** - * Gets the duration of the extractor step in milliseconds. - */ - int getDurationMs() { extractor_steps(this, _, _, result) } - - /** - * Provides location information for this step. - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getFile().getAbsolutePath() = filepath and - startline = 0 and - startcolumn = 0 and - endline = 0 and - endcolumn = 0 - } -} diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index f0f2a65aea5..9709ae9bf54 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -116,20 +116,21 @@ locatable_locations( int location: @location_default ref ); + +// from schema + +@element = + @extractor_step +| @locatable +| @unextracted +; + extractor_steps( unique int id: @extractor_step, string action: string ref, int file: @file ref, int duration_ms: int ref -) - - -// from schema - -@element = - @locatable -| @unextracted -; +); @locatable = @ast_node diff --git a/rust/schema/prelude.py b/rust/schema/prelude.py index ffd65959b5a..5b050872609 100644 --- a/rust/schema/prelude.py +++ b/rust/schema/prelude.py @@ -3,6 +3,7 @@ from misc.codegen.lib.schemadefs import * include("../shared/tree-sitter-extractor/src/generator/prefix.dbscheme") include("prefix.dbscheme") +File = imported("File", "codeql.files.FileSystem") @qltest.skip class Element: @@ -93,3 +94,11 @@ class Resolvable(AstNode): """ resolved_path: optional[string] | rust.detach | ql.internal resolved_crate_origin: optional[string] | rust.detach | ql.internal + + +@qltest.skip +@ql.internal +class ExtractorStep(Element): + action: string + file: File + duration_ms: int diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index da39f2f2fe7..60120579321 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -712,7 +712,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll d9feaa2a71acff3184ca389045b lib/codeql/swift/generated/ParentChild.qll d1814f2bad4c2ba9242ce49fe6fb8564ac99fc1fd3a7d12aa55e5c6dd7bb529b 1a2075b731d07a5e3c6a69d001796c8de925069d839671a294c9cba6c3db724a lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll dc17b49a90a18a8f7607adf2433bc8f0c194fa3e803aa3822f809d4d4fbd6793 be48ea9f8ae17354c8508aaed24337a9e57ce01f288fece3dcecd99776cabcec lib/codeql/swift/generated/PureSynthConstructors.qll bc31a6c4d142fa3fbdcae69d5ba6f1cec00eb9ad92b46c8d7b91ebfa7ef6c1f4 bc31a6c4d142fa3fbdcae69d5ba6f1cec00eb9ad92b46c8d7b91ebfa7ef6c1f4 -lib/codeql/swift/generated/Raw.qll 118b43fedd4265b5aa15c33ef01a2f5a5db6e5597f95bef1078a01c3ff8da983 075aec2c8b232f0361ebf63f07ae9b66163f3975e6023583fb0fa2e40b979a33 +lib/codeql/swift/generated/Raw.qll a47950495630c10c00afee734d779e5e3e7f8e3e65ae3f04b9a1254e3e73921e 075aec2c8b232f0361ebf63f07ae9b66163f3975e6023583fb0fa2e40b979a33 lib/codeql/swift/generated/Synth.qll 31e318c6e156848c85a2a2664695b48b5e93c57c9bb22fa29d027069907b3ab0 8655ffcf772f55284b93f1d7f8e1b3d497a9744d5f2e0c17bc322c1fdf8bdba8 lib/codeql/swift/generated/SynthConstructors.qll 3e53c7853096020219c01dae85681fe80b34938d198a0ff359a209dda41c5ed7 3e53c7853096020219c01dae85681fe80b34938d198a0ff359a209dda41c5ed7 lib/codeql/swift/generated/UnknownFile.qll 247ddf2ebb49ce5ed4bf7bf91a969ddff37de6c78d43d8affccaf7eb586e06f2 452b29f0465ef45e978ef8b647b75e5a2a1e53f2a568fc003bc8f52f73b3fa4d From 4bd5cc458bbf3961449a876bb5eea358005e2ad7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 2 Dec 2024 16:07:00 +0100 Subject: [PATCH 34/63] Rust: accept test changes --- rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index 16e895cdeef..9372843039c 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -1,4 +1,4 @@ -| Elements extracted | 382 | +| Elements extracted | 404 | | Elements unextracted | 0 | | Extraction errors | 0 | | Extraction warnings | 7 | From 2c0baff76afc05fd0f62d3c969a21d0bfefe10ed Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:13:03 +0100 Subject: [PATCH 35/63] Java: Delete deprecated data flow api. --- .../semmle/code/java/dataflow/DataFlow.qll | 2 +- .../semmle/code/java/dataflow/DataFlow2.qll | 10 - .../semmle/code/java/dataflow/DataFlow3.qll | 10 - .../semmle/code/java/dataflow/DataFlow4.qll | 10 - .../semmle/code/java/dataflow/DataFlow5.qll | 10 - .../semmle/code/java/dataflow/DataFlow6.qll | 10 - .../code/java/dataflow/TaintTracking.qll | 4 +- .../code/java/dataflow/TaintTracking2.qll | 7 - .../code/java/dataflow/TaintTracking3.qll | 7 - .../java/dataflow/internal/DataFlowImpl1.qll | 361 ------------------ .../java/dataflow/internal/DataFlowImpl2.qll | 361 ------------------ .../java/dataflow/internal/DataFlowImpl3.qll | 361 ------------------ .../java/dataflow/internal/DataFlowImpl4.qll | 361 ------------------ .../java/dataflow/internal/DataFlowImpl5.qll | 361 ------------------ .../java/dataflow/internal/DataFlowImpl6.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 6 - .../tainttracking2/TaintTrackingImpl.qll | 168 -------- .../tainttracking2/TaintTrackingParameter.qll | 5 - .../tainttracking3/TaintTrackingImpl.qll | 168 -------- .../tainttracking3/TaintTrackingParameter.qll | 5 - 21 files changed, 2 insertions(+), 2754 deletions(-) delete mode 100644 java/ql/lib/semmle/code/java/dataflow/DataFlow2.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/DataFlow3.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/DataFlow4.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/DataFlow5.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/DataFlow6.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/TaintTracking2.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/TaintTracking3.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingParameter.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingParameter.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingParameter.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll index 66a7a847c33..ab48577c02e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll @@ -9,5 +9,5 @@ module DataFlow { private import semmle.code.java.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.java.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow2.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow2.qll deleted file mode 100644 index 92003314778..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow2.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow2 { - import semmle.code.java.dataflow.internal.DataFlowImpl2 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow3.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow3.qll deleted file mode 100644 index c8d614e0879..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow3.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow3 { - import semmle.code.java.dataflow.internal.DataFlowImpl3 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow4.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow4.qll deleted file mode 100644 index 852cfd9f813..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow4.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow4 { - import semmle.code.java.dataflow.internal.DataFlowImpl4 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow5.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow5.qll deleted file mode 100644 index f8986a03524..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow5.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow5 { - import semmle.code.java.dataflow.internal.DataFlowImpl5 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow6.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow6.qll deleted file mode 100644 index 28fa11da475..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow6.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow6 { - import semmle.code.java.dataflow.internal.DataFlowImpl6 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll b/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll index ed13837a312..e62850fbc38 100644 --- a/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll +++ b/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll @@ -4,14 +4,12 @@ */ import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.DataFlow2 import semmle.code.java.dataflow.internal.TaintTrackingUtil::StringBuilderVarModule module TaintTracking { - import semmle.code.java.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.java.dataflow.internal.TaintTrackingUtil private import semmle.code.java.dataflow.internal.DataFlowImplSpecific private import semmle.code.java.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.java.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/java/ql/lib/semmle/code/java/dataflow/TaintTracking2.qll b/java/ql/lib/semmle/code/java/dataflow/TaintTracking2.qll deleted file mode 100644 index abd909dba2b..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.code.java.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/java/ql/lib/semmle/code/java/dataflow/TaintTracking3.qll b/java/ql/lib/semmle/code/java/dataflow/TaintTracking3.qll deleted file mode 100644 index 49c43ed1418..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/TaintTracking3.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking3 { - import semmle.code.java.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 2608adffda3..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.java.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.java.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.java.dataflow.internal.DataFlowImpl as DataFlowInternal -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index 5a9c924b6bd..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.java.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.java.dataflow.DataFlow2::DataFlow2 as DataFlow -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingParameter.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 10fb6b09fa8..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.java.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.java.dataflow.DataFlow3::DataFlow3 as DataFlow -} From f07f2b0f4ad63f5565cde636d6f3a56446c4d3ce Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:40:43 +0100 Subject: [PATCH 36/63] Swift: Delete deprecated data flow api. --- .../ql/lib/codeql/swift/dataflow/DataFlow.qll | 2 +- .../codeql/swift/dataflow/TaintTracking.qll | 3 +- .../swift/dataflow/internal/DataFlowImpl1.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 7 - 5 files changed, 2 insertions(+), 539 deletions(-) delete mode 100644 swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll delete mode 100644 swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingParameter.qll diff --git a/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll b/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll index 670a94babd9..fd99bfd1999 100644 --- a/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll @@ -7,5 +7,5 @@ module DataFlow { private import codeql.dataflow.DataFlow private import codeql.swift.elements.Location import DataFlowMake - import internal.DataFlowImpl1 + import Public } diff --git a/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll b/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll index e46cd18abb4..1998e25abd7 100644 --- a/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll +++ b/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll @@ -3,11 +3,10 @@ * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import codeql.swift.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import codeql.swift.dataflow.internal.TaintTrackingPublic private import codeql.swift.dataflow.internal.DataFlowImplSpecific private import codeql.swift.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking private import codeql.swift.elements.Location import TaintFlowMake - import codeql.swift.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 1cd9cab0e54..00000000000 --- a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import codeql.swift.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import codeql.swift.dataflow.DataFlow::DataFlow as DataFlow - import codeql.swift.dataflow.internal.DataFlowImpl as DataFlowInternal - import codeql.swift.dataflow.internal.TaintTrackingPrivate -} From 20f06abe6fe53b3876a32d99f02939303a97138b Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:41:14 +0100 Subject: [PATCH 37/63] Ruby: Delete deprecated data flow api. --- ruby/ql/lib/codeql/ruby/DataFlow.qll | 2 +- ruby/ql/lib/codeql/ruby/DataFlow2.qll | 7 - ruby/ql/lib/codeql/ruby/TaintTracking.qll | 3 +- .../ruby/dataflow/internal/DataFlowImpl1.qll | 361 ------------------ .../ruby/dataflow/internal/DataFlowImpl2.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 7 - 7 files changed, 2 insertions(+), 907 deletions(-) delete mode 100644 ruby/ql/lib/codeql/ruby/DataFlow2.qll delete mode 100644 ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll delete mode 100644 ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll delete mode 100644 ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingParameter.qll diff --git a/ruby/ql/lib/codeql/ruby/DataFlow.qll b/ruby/ql/lib/codeql/ruby/DataFlow.qll index f17c85143f5..72fb8c880ec 100644 --- a/ruby/ql/lib/codeql/ruby/DataFlow.qll +++ b/ruby/ql/lib/codeql/ruby/DataFlow.qll @@ -13,5 +13,5 @@ module DataFlow { private import codeql.ruby.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import codeql.ruby.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/ruby/ql/lib/codeql/ruby/DataFlow2.qll b/ruby/ql/lib/codeql/ruby/DataFlow2.qll deleted file mode 100644 index 7486f52052d..00000000000 --- a/ruby/ql/lib/codeql/ruby/DataFlow2.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow2 { - import codeql.ruby.dataflow.internal.DataFlowImpl2 -} diff --git a/ruby/ql/lib/codeql/ruby/TaintTracking.qll b/ruby/ql/lib/codeql/ruby/TaintTracking.qll index 7534b28079a..45828c86dd2 100644 --- a/ruby/ql/lib/codeql/ruby/TaintTracking.qll +++ b/ruby/ql/lib/codeql/ruby/TaintTracking.qll @@ -3,11 +3,10 @@ * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import codeql.ruby.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import codeql.ruby.dataflow.internal.TaintTrackingPublic private import codeql.ruby.dataflow.internal.DataFlowImplSpecific private import codeql.ruby.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking private import codeql.Locations import TaintFlowMake - import codeql.ruby.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 0c87c8ac5e8..00000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import codeql.ruby.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import codeql.ruby.DataFlow::DataFlow as DataFlow - import codeql.ruby.dataflow.internal.DataFlowImpl as DataFlowInternal - import codeql.ruby.dataflow.internal.TaintTrackingPrivate -} From acc260cc3cc13159c7fde246898e073625061707 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:41:49 +0100 Subject: [PATCH 38/63] Python: Delete deprecated data flow api. --- .../semmle/python/dataflow/new/DataFlow.qll | 2 +- .../semmle/python/dataflow/new/DataFlow2.qll | 26 -- .../semmle/python/dataflow/new/DataFlow3.qll | 26 -- .../semmle/python/dataflow/new/DataFlow4.qll | 26 -- .../python/dataflow/new/TaintTracking.qll | 3 +- .../python/dataflow/new/TaintTracking2.qll | 19 - .../python/dataflow/new/TaintTracking3.qll | 19 - .../python/dataflow/new/TaintTracking4.qll | 19 - .../dataflow/new/internal/DataFlowImpl1.qll | 361 ------------------ .../dataflow/new/internal/DataFlowImpl2.qll | 361 ------------------ .../dataflow/new/internal/DataFlowImpl3.qll | 361 ------------------ .../dataflow/new/internal/DataFlowImpl4.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 7 - .../tainttracking2/TaintTrackingImpl.qll | 168 -------- .../tainttracking2/TaintTrackingParameter.qll | 6 - .../tainttracking3/TaintTrackingImpl.qll | 168 -------- .../tainttracking3/TaintTrackingParameter.qll | 6 - .../tainttracking4/TaintTrackingImpl.qll | 168 -------- .../tainttracking4/TaintTrackingParameter.qll | 6 - 20 files changed, 2 insertions(+), 2279 deletions(-) delete mode 100644 python/ql/lib/semmle/python/dataflow/new/DataFlow2.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/DataFlow3.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/DataFlow4.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/TaintTracking2.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/TaintTracking3.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/TaintTracking4.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingParameter.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingParameter.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingParameter.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll delete mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingParameter.qll diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll index 17cc0a0ee85..670f42a8dc5 100644 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll +++ b/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll @@ -25,5 +25,5 @@ module DataFlow { private import internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import internal.DataFlowImpl1 + import Public } diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow2.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow2.qll deleted file mode 100644 index 753fe553093..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow2.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.python.dataflow.new.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, call `DataFlow::localFlow` or - * `DataFlow::localFlowStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow2 { - import semmle.python.dataflow.new.internal.DataFlowImpl2 -} diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow3.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow3.qll deleted file mode 100644 index c6b7304319b..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow3.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.python.dataflow.new.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, call `DataFlow::localFlow` or - * `DataFlow::localFlowStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow3 { - import semmle.python.dataflow.new.internal.DataFlowImpl3 -} diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow4.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow4.qll deleted file mode 100644 index 44d926a274d..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow4.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.python.dataflow.new.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, call `DataFlow::localFlow` or - * `DataFlow::localFlowStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow4 { - import semmle.python.dataflow.new.internal.DataFlowImpl4 -} diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll index e085ba45dd0..01174d5e7a0 100644 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll @@ -15,10 +15,9 @@ private import python * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import semmle.python.dataflow.new.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.python.dataflow.new.internal.TaintTrackingPublic private import semmle.python.dataflow.new.internal.DataFlowImplSpecific private import semmle.python.dataflow.new.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import internal.tainttracking1.TaintTrackingImpl } diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking2.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking2.qll deleted file mode 100644 index 5d78a531e2e..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking2.qll +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - * - * To use global (interprocedural) taint tracking, extend the class - * `TaintTracking::Configuration` as documented on that class. To use local - * (intraprocedural) taint tracking, call `TaintTracking::localTaint` or - * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.python.dataflow.new.internal.tainttracking2.TaintTrackingImpl -} diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking3.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking3.qll deleted file mode 100644 index d3173ec8f9f..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking3.qll +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - * - * To use global (interprocedural) taint tracking, extend the class - * `TaintTracking::Configuration` as documented on that class. To use local - * (intraprocedural) taint tracking, call `TaintTracking::localTaint` or - * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking3 { - import semmle.python.dataflow.new.internal.tainttracking3.TaintTrackingImpl -} diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking4.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking4.qll deleted file mode 100644 index f452cf4ed00..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking4.qll +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - * - * To use global (interprocedural) taint tracking, extend the class - * `TaintTracking::Configuration` as documented on that class. To use local - * (intraprocedural) taint tracking, call `TaintTracking::localTaint` or - * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking4 { - import semmle.python.dataflow.new.internal.tainttracking4.TaintTrackingImpl -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index badbe01f4c5..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow::DataFlow as DataFlow - import semmle.python.dataflow.new.internal.DataFlowImpl as DataFlowInternal - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index fa5201b6020..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow2::DataFlow2 as DataFlow - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 390a1fd7ed0..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow3::DataFlow3 as DataFlow - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingParameter.qll deleted file mode 100644 index 3072d32c126..00000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow4::DataFlow4 as DataFlow - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} From fbff4b6e2151fcc3d124d941bff527d15c9fbdb3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:42:14 +0100 Subject: [PATCH 39/63] Go: Delete deprecated data flow api. --- go/ql/lib/semmle/go/dataflow/DataFlow.qll | 2 +- go/ql/lib/semmle/go/dataflow/DataFlow2.qll | 27 -- .../lib/semmle/go/dataflow/TaintTracking.qll | 3 +- .../lib/semmle/go/dataflow/TaintTracking2.qll | 12 - .../go/dataflow/internal/DataFlowImpl1.qll | 361 ------------------ .../go/dataflow/internal/DataFlowImpl2.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 6 - .../tainttracking2/TaintTrackingImpl.qll | 168 -------- .../tainttracking2/TaintTrackingParameter.qll | 5 - 10 files changed, 2 insertions(+), 1111 deletions(-) delete mode 100644 go/ql/lib/semmle/go/dataflow/DataFlow2.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/TaintTracking2.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingParameter.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingParameter.qll diff --git a/go/ql/lib/semmle/go/dataflow/DataFlow.qll b/go/ql/lib/semmle/go/dataflow/DataFlow.qll index 9363bc93abd..c26adbfd2c2 100644 --- a/go/ql/lib/semmle/go/dataflow/DataFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/DataFlow.qll @@ -25,7 +25,7 @@ module DataFlow { private import semmle.go.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.go.dataflow.internal.DataFlowImpl1 + import Public import Properties } diff --git a/go/ql/lib/semmle/go/dataflow/DataFlow2.qll b/go/ql/lib/semmle/go/dataflow/DataFlow2.qll deleted file mode 100644 index a2bae8bd939..00000000000 --- a/go/ql/lib/semmle/go/dataflow/DataFlow2.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.code.go.dataflow.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, invoke `DataFlow::localFlow` or - * `DataFlow::LocalFlowStep` with arguments of type `DataFlow::Node`. - */ - -import go - -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis. - */ -module DataFlow2 { - import semmle.go.dataflow.internal.DataFlowImpl2 - import Properties -} diff --git a/go/ql/lib/semmle/go/dataflow/TaintTracking.qll b/go/ql/lib/semmle/go/dataflow/TaintTracking.qll index d762e925ab5..c469574b3b9 100644 --- a/go/ql/lib/semmle/go/dataflow/TaintTracking.qll +++ b/go/ql/lib/semmle/go/dataflow/TaintTracking.qll @@ -10,11 +10,10 @@ import semmle.go.dataflow.DataFlow * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import semmle.go.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.go.dataflow.internal.TaintTrackingUtil private import semmle.go.dataflow.internal.DataFlowImplSpecific private import semmle.go.dataflow.internal.TaintTrackingImplSpecific private import semmle.go.Locations private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.go.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/go/ql/lib/semmle/go/dataflow/TaintTracking2.qll b/go/ql/lib/semmle/go/dataflow/TaintTracking2.qll deleted file mode 100644 index 6b1b2487e5b..00000000000 --- a/go/ql/lib/semmle/go/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.go.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index a5a45514a06..00000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.go.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.go.dataflow.DataFlow::DataFlow as DataFlow - import semmle.go.dataflow.internal.DataFlowImpl as DataFlowInternal -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index 1130c2e42e1..00000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.go.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.go.dataflow.DataFlow2::DataFlow2 as DataFlow -} From 0d9e5788578273674d6635385b582a0e7a7ff149 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:42:34 +0100 Subject: [PATCH 40/63] C#: Delete deprecated data flow api. --- .../semmle/code/csharp/dataflow/DataFlow.qll | 2 +- .../semmle/code/csharp/dataflow/DataFlow2.qll | 10 - .../semmle/code/csharp/dataflow/DataFlow3.qll | 10 - .../semmle/code/csharp/dataflow/DataFlow4.qll | 10 - .../semmle/code/csharp/dataflow/DataFlow5.qll | 10 - .../code/csharp/dataflow/TaintTracking.qll | 3 +- .../code/csharp/dataflow/TaintTracking2.qll | 10 - .../code/csharp/dataflow/TaintTracking3.qll | 10 - .../code/csharp/dataflow/TaintTracking4.qll | 10 - .../code/csharp/dataflow/TaintTracking5.qll | 10 - .../dataflow/internal/DataFlowImpl1.qll | 361 ------------------ .../dataflow/internal/DataFlowImpl2.qll | 361 ------------------ .../dataflow/internal/DataFlowImpl3.qll | 361 ------------------ .../dataflow/internal/DataFlowImpl4.qll | 361 ------------------ .../dataflow/internal/DataFlowImpl5.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 7 - .../tainttracking2/TaintTrackingImpl.qll | 168 -------- .../tainttracking2/TaintTrackingParameter.qll | 6 - .../tainttracking3/TaintTrackingImpl.qll | 168 -------- .../tainttracking3/TaintTrackingParameter.qll | 6 - .../tainttracking4/TaintTrackingImpl.qll | 168 -------- .../tainttracking4/TaintTrackingParameter.qll | 6 - .../tainttracking5/TaintTrackingImpl.qll | 168 -------- .../tainttracking5/TaintTrackingParameter.qll | 6 - 25 files changed, 2 insertions(+), 2759 deletions(-) delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow2.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow3.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow4.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow5.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingParameter.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingParameter.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingParameter.qll diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll index 0fc12debaa8..9c1c8c2fee3 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll @@ -9,5 +9,5 @@ module DataFlow { private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.csharp.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow2.qll deleted file mode 100644 index 60525016d31..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow2.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow2 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl2 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow3.qll deleted file mode 100644 index 7f3b9469449..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow3.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow3 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl3 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow4.qll deleted file mode 100644 index 29c994a2eec..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow4.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow4 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl4 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow5.qll deleted file mode 100644 index 48148117166..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow5.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow5 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl5 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll index fb39294ed23..781953a8348 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll @@ -6,10 +6,9 @@ import csharp module TaintTracking { - import semmle.code.csharp.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.csharp.dataflow.internal.TaintTrackingPublic private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.csharp.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll deleted file mode 100644 index 9ee798ed9fd..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking2 { - import semmle.code.csharp.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll deleted file mode 100644 index 476d7bf7dd7..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking3 { - import semmle.code.csharp.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll deleted file mode 100644 index 45b8f12be5c..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking4 { - import semmle.code.csharp.dataflow.internal.tainttracking4.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll deleted file mode 100644 index 7a75ce532bc..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking5 { - import semmle.code.csharp.dataflow.internal.tainttracking5.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 6fa484bea77..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.csharp.dataflow.internal.DataFlowImpl as DataFlowInternal - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index 6a8fa23ef31..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow2::DataFlow2 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 6c73b6ceda6..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow3::DataFlow3 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingParameter.qll deleted file mode 100644 index e394e27a50c..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow4::DataFlow4 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingParameter.qll deleted file mode 100644 index 2668be3b376..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow5::DataFlow5 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} From 371a11e6da4faaf5d118e37bff5b7ad3cccb3eb6 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:52:14 +0100 Subject: [PATCH 41/63] C++: Delete deprecated data flow api. --- .../lib/semmle/code/cpp/dataflow/DataFlow.qll | 2 +- .../semmle/code/cpp/dataflow/DataFlow2.qll | 22 -- .../semmle/code/cpp/dataflow/DataFlow3.qll | 22 -- .../semmle/code/cpp/dataflow/DataFlow4.qll | 22 -- .../code/cpp/dataflow/TaintTracking.qll | 4 +- .../code/cpp/dataflow/TaintTracking2.qll | 22 -- .../cpp/dataflow/internal/DataFlowImpl1.qll | 361 ------------------ .../cpp/dataflow/internal/DataFlowImpl2.qll | 361 ------------------ .../cpp/dataflow/internal/DataFlowImpl3.qll | 361 ------------------ .../cpp/dataflow/internal/DataFlowImpl4.qll | 361 ------------------ .../dataflow/internal/DataFlowImplLocal.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 10 - .../tainttracking2/TaintTrackingImpl.qll | 168 -------- .../tainttracking2/TaintTrackingParameter.qll | 9 - .../semmle/code/cpp/dataflow/new/DataFlow.qll | 2 +- .../code/cpp/dataflow/new/DataFlow2.qll | 20 - .../code/cpp/dataflow/new/DataFlow3.qll | 20 - .../code/cpp/dataflow/new/DataFlow4.qll | 20 - .../code/cpp/dataflow/new/TaintTracking.qll | 4 +- .../code/cpp/dataflow/new/TaintTracking2.qll | 20 - .../code/cpp/dataflow/new/TaintTracking3.qll | 20 - .../semmle/code/cpp/ir/dataflow/DataFlow.qll | 2 +- .../semmle/code/cpp/ir/dataflow/DataFlow2.qll | 16 - .../semmle/code/cpp/ir/dataflow/DataFlow3.qll | 16 - .../semmle/code/cpp/ir/dataflow/DataFlow4.qll | 16 - .../code/cpp/ir/dataflow/TaintTracking.qll | 4 +- .../code/cpp/ir/dataflow/TaintTracking2.qll | 15 - .../code/cpp/ir/dataflow/TaintTracking3.qll | 15 - .../ir/dataflow/internal/DataFlowImpl1.qll | 361 ------------------ .../ir/dataflow/internal/DataFlowImpl2.qll | 361 ------------------ .../ir/dataflow/internal/DataFlowImpl3.qll | 361 ------------------ .../ir/dataflow/internal/DataFlowImpl4.qll | 361 ------------------ .../tainttracking1/TaintTrackingImpl.qll | 168 -------- .../tainttracking1/TaintTrackingParameter.qll | 6 - .../tainttracking2/TaintTrackingImpl.qll | 168 -------- .../tainttracking2/TaintTrackingParameter.qll | 5 - .../tainttracking3/TaintTrackingImpl.qll | 168 -------- .../tainttracking3/TaintTrackingParameter.qll | 5 - 39 files changed, 6 insertions(+), 4402 deletions(-) delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow3.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow4.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow3.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow4.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking3.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow3.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow4.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking3.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll delete mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll index 505b2e190e5..a478da5193e 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll @@ -29,5 +29,5 @@ deprecated module DataFlow { private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.cpp.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow2.qll deleted file mode 100644 index 19ffa16b76c..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow2.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `DataFlow2` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow2` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -deprecated module DataFlow2 { - import semmle.code.cpp.dataflow.internal.DataFlowImpl2 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow3.qll deleted file mode 100644 index 554b2e155b4..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow3.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `DataFlow3` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow3` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -deprecated module DataFlow3 { - import semmle.code.cpp.dataflow.internal.DataFlowImpl3 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow4.qll deleted file mode 100644 index fdd4e8ab7ae..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow4.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `DataFlow4` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow4` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -deprecated module DataFlow4 { - import semmle.code.cpp.dataflow.internal.DataFlowImpl4 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll index 1f93e2a74df..36af8d9660b 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll @@ -16,7 +16,6 @@ */ import semmle.code.cpp.dataflow.DataFlow -import semmle.code.cpp.dataflow.DataFlow2 /** * DEPRECATED: Use `semmle.code.cpp.dataflow.new.TaintTracking` instead. @@ -25,10 +24,9 @@ import semmle.code.cpp.dataflow.DataFlow2 * global (inter-procedural) taint-tracking analyses. */ deprecated module TaintTracking { - import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.cpp.dataflow.internal.TaintTrackingUtil private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific private import semmle.code.cpp.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking2.qll deleted file mode 100644 index dce00316cbb..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `TaintTracking2` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.dataflow.TaintTracking` for the full documentation. - */ - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.TaintTracking2` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -deprecated module TaintTracking2 { - import semmle.code.cpp.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index f9346e28434..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - */ - -import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.cpp.dataflow.internal.DataFlowImpl as DataFlowInternal -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index e935b8d4d08..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - */ - -import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.dataflow.DataFlow2::DataFlow2 as DataFlow -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll index bcbebd0de1e..2067dc8aac0 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll @@ -29,5 +29,5 @@ module DataFlow { private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow2.qll deleted file mode 100644 index 35c5a34a656..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow2.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `DataFlow2` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.DataFlow` for the full documentation. - */ - -import cpp - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow2 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl2 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow3.qll deleted file mode 100644 index e2e402835f2..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow3.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `DataFlow3` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.DataFlow` for the full documentation. - */ - -import cpp - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow3 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl3 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow4.qll deleted file mode 100644 index f9209abe1e1..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow4.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `DataFlow4` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.DataFlow` for the full documentation. - */ - -import cpp - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow4 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl4 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll index d28a389203f..ecc927ecad7 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll @@ -16,18 +16,16 @@ */ import semmle.code.cpp.dataflow.new.DataFlow -import semmle.code.cpp.dataflow.new.DataFlow2 /** * Provides classes for performing local (intra-procedural) and * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking private import semmle.code.cpp.Location import TaintFlowMake - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking2.qll deleted file mode 100644 index 2da049cefaf..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking2.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `TaintTracking2` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.TaintTracking` for the full documentation. - */ - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking3.qll deleted file mode 100644 index 113175d8369..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking3.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `TaintTracking3` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.TaintTracking` for the full documentation. - */ - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking3 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll index 671d82c74ef..ecd474d64b2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll @@ -25,5 +25,5 @@ module DataFlow { private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow2.qll deleted file mode 100644 index 95eb979192d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow2.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides a `DataFlow2` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -module DataFlow2 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl2 -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow3.qll deleted file mode 100644 index 42529f78e5b..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow3.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides a `DataFlow3` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -module DataFlow3 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl3 -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow4.qll deleted file mode 100644 index 6cd49e39e71..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow4.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides a `DataFlow4` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -module DataFlow4 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl4 -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll index 9ca1315ec3e..69bb1978cf6 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll @@ -16,13 +16,11 @@ */ import semmle.code.cpp.ir.dataflow.DataFlow -import semmle.code.cpp.ir.dataflow.DataFlow2 module TaintTracking { - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking2.qll deleted file mode 100644 index 3ef03a3bd2c..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Provides a `TaintTracking2` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation. - */ -module TaintTracking2 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking3.qll deleted file mode 100644 index 98e1caebf38..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking3.qll +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Provides a `TaintTracking3` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation. - */ -module TaintTracking3 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431d..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 19e10871a78..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl as DataFlowInternal -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index ac0b79d067e..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.ir.dataflow.DataFlow2::DataFlow2 as DataFlow -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd26..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * Holds if `source` is a relevant taint source with the given initial - * `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } - - /** - * Holds if `sink` is a relevant taint sink - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink) { none() } - - /** - * Holds if `sink` is a relevant taint sink accepting `state`. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } - - /** Holds if the node `node` is a taint sanitizer. */ - predicate isSanitizer(DataFlow::Node node) { none() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - defaultTaintSanitizer(node) - } - - /** - * Holds if the node `node` is a taint sanitizer when the flow state is - * `state`. - */ - predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } - - final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { - this.isSanitizer(node, state) - } - - /** Holds if taint propagation into `node` is prohibited. */ - predicate isSanitizerIn(DataFlow::Node node) { none() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - final override predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - this.isAdditionalTaintStep(node1, state1, node2, state2) - } - - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 2a3b69f55cd..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.ir.dataflow.DataFlow3::DataFlow3 as DataFlow -} From c654a05998be6b8c16995a9fdd378cf7f72a83a8 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 14:52:30 +0100 Subject: [PATCH 42/63] Dataflow: Remove identical-files entries for deleted api. --- config/identical-files.json | 54 ------------------------------------- 1 file changed, 54 deletions(-) diff --git a/config/identical-files.json b/config/identical-files.json index c4436872b9a..579a22379e8 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -1,58 +1,4 @@ { - "DataFlow Java/C++/C#/Go/Python/Ruby/Swift Legacy Configuration": [ - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll", - "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll", - "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll", - "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll", - "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll", - "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll" - ], - "TaintTracking Legacy Configuration Java/C++/C#/Go/Python/Ruby/Swift": [ - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll", - "go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll", - "ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll" - ], "SsaReadPosition Java/C#": [ "java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll" From 8ea973f8380f87f85bc4f59e1cf0d2367badca44 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 15:20:07 +0100 Subject: [PATCH 43/63] C++: Update use of deleted api. --- .../cpp/dataflow/internal/DataFlowUtil.qll | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index b4f325e01df..4a8ea4ebd43 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -729,41 +729,39 @@ private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) { private module FieldFlow { private import DataFlowImplCommon - private import DataFlowImplLocal private import DataFlowPrivate + private import semmle.code.cpp.dataflow.DataFlow /** - * A configuration for finding local-only flow through fields. This uses the - * `Configuration` class in the dedicated `DataFlowImplLocal` copy of the - * shared library that's not user-exposed directly. + * A configuration for finding local-only flow through fields. * * To keep the flow local to a single function, we put barriers on parameters * and return statements. Sources and sinks are the values that go into and * out of fields, respectively. */ - private class FieldConfiguration extends Configuration { - FieldConfiguration() { this = "FieldConfiguration" } - - override predicate isSource(Node source) { + private module FieldConfig implements DataFlow::ConfigSig { + predicate isSource(Node source) { storeStep(source, _, _) or // Also mark `foo(a.b);` as a source when `a.b` may be overwritten by `foo`. readStep(_, _, any(Node node | node.asExpr() = source.asDefiningArgument())) } - override predicate isSink(Node sink) { readStep(_, _, sink) } + predicate isSink(Node sink) { readStep(_, _, sink) } - override predicate isBarrier(Node node) { node instanceof ParameterNode } + predicate isBarrier(Node node) { node instanceof ParameterNode } - override predicate isBarrierOut(Node node) { + predicate isBarrierOut(Node node) { node.asExpr().getParent() instanceof ReturnStmt or node.asExpr().getParent() instanceof ThrowExpr } } + private module Flow = DataFlow::Global; + predicate fieldFlow(Node node1, Node node2) { - exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and + Flow::flow(node1, node2) and // This configuration should not be able to cross function boundaries, but // we double-check here just to be sure. getNodeEnclosingCallable(node1) = getNodeEnclosingCallable(node2) From b50834aee8ae2aeee715979467714d315221dba3 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 29 Nov 2024 13:13:55 +0100 Subject: [PATCH 44/63] Rust: Add data flow tests for question mark operator --- .../dataflow/local/DataFlowStep.expected | 380 ++++++++++-------- .../dataflow/local/inline-flow.expected | 136 +++---- .../test/library-tests/dataflow/local/main.rs | 25 ++ 3 files changed, 303 insertions(+), 238 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index bc36656e49d..d566af4eca2 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -204,146 +204,179 @@ localStep | main.rs:224:9:224:10 | [SSA] s1 | main.rs:225:10:225:11 | s1 | | main.rs:224:9:224:10 | s1 | main.rs:224:9:224:10 | [SSA] s1 | | main.rs:224:14:224:29 | Some(...) | main.rs:224:9:224:10 | s1 | -| main.rs:234:9:234:10 | [SSA] s1 | main.rs:236:11:236:12 | s1 | -| main.rs:234:9:234:10 | s1 | main.rs:234:9:234:10 | [SSA] s1 | -| main.rs:234:14:234:39 | ...::A(...) | main.rs:234:9:234:10 | s1 | -| main.rs:235:9:235:10 | [SSA] s2 | main.rs:243:11:243:12 | s2 | -| main.rs:235:9:235:10 | s2 | main.rs:235:9:235:10 | [SSA] s2 | -| main.rs:235:14:235:30 | ...::B(...) | main.rs:235:9:235:10 | s2 | -| main.rs:236:11:236:12 | s1 | main.rs:237:9:237:25 | TupleStructPat | -| main.rs:236:11:236:12 | s1 | main.rs:238:9:238:25 | TupleStructPat | -| main.rs:236:11:236:12 | s1 | main.rs:240:11:240:12 | s1 | -| main.rs:237:24:237:24 | [SSA] n | main.rs:237:35:237:35 | n | -| main.rs:237:24:237:24 | n | main.rs:237:24:237:24 | [SSA] n | -| main.rs:237:30:237:36 | sink(...) | main.rs:236:5:239:5 | match s1 { ... } | -| main.rs:238:24:238:24 | [SSA] n | main.rs:238:35:238:35 | n | -| main.rs:238:24:238:24 | n | main.rs:238:24:238:24 | [SSA] n | -| main.rs:238:30:238:36 | sink(...) | main.rs:236:5:239:5 | match s1 { ... } | -| main.rs:240:11:240:12 | s1 | main.rs:241:9:241:45 | ... \| ... | -| main.rs:241:9:241:45 | ... \| ... | main.rs:241:9:241:25 | TupleStructPat | -| main.rs:241:9:241:45 | ... \| ... | main.rs:241:29:241:45 | TupleStructPat | -| main.rs:241:9:241:45 | [SSA] [match(true)] phi | main.rs:241:55:241:55 | n | -| main.rs:241:24:241:24 | [SSA] [input] [match(true)] phi | main.rs:241:9:241:45 | [SSA] [match(true)] phi | -| main.rs:241:24:241:24 | [SSA] n | main.rs:241:24:241:24 | [SSA] [input] [match(true)] phi | -| main.rs:241:24:241:24 | n | main.rs:241:24:241:24 | [SSA] n | -| main.rs:241:44:241:44 | [SSA] [input] [match(true)] phi | main.rs:241:9:241:45 | [SSA] [match(true)] phi | -| main.rs:241:44:241:44 | [SSA] n | main.rs:241:44:241:44 | [SSA] [input] [match(true)] phi | -| main.rs:241:44:241:44 | n | main.rs:241:44:241:44 | [SSA] n | -| main.rs:241:50:241:56 | sink(...) | main.rs:240:5:242:5 | match s1 { ... } | -| main.rs:243:5:246:5 | match s2 { ... } | main.rs:233:48:247:1 | { ... } | -| main.rs:243:11:243:12 | s2 | main.rs:244:9:244:25 | TupleStructPat | -| main.rs:243:11:243:12 | s2 | main.rs:245:9:245:25 | TupleStructPat | -| main.rs:244:24:244:24 | [SSA] n | main.rs:244:35:244:35 | n | -| main.rs:244:24:244:24 | n | main.rs:244:24:244:24 | [SSA] n | -| main.rs:244:30:244:36 | sink(...) | main.rs:243:5:246:5 | match s2 { ... } | -| main.rs:245:24:245:24 | [SSA] n | main.rs:245:35:245:35 | n | -| main.rs:245:24:245:24 | n | main.rs:245:24:245:24 | [SSA] n | -| main.rs:245:30:245:36 | sink(...) | main.rs:243:5:246:5 | match s2 { ... } | -| main.rs:252:9:252:10 | [SSA] s1 | main.rs:254:11:254:12 | s1 | -| main.rs:252:9:252:10 | s1 | main.rs:252:9:252:10 | [SSA] s1 | -| main.rs:252:14:252:26 | A(...) | main.rs:252:9:252:10 | s1 | -| main.rs:253:9:253:10 | [SSA] s2 | main.rs:261:11:261:12 | s2 | -| main.rs:253:9:253:10 | s2 | main.rs:253:9:253:10 | [SSA] s2 | -| main.rs:253:14:253:17 | B(...) | main.rs:253:9:253:10 | s2 | -| main.rs:254:11:254:12 | s1 | main.rs:255:9:255:12 | TupleStructPat | -| main.rs:254:11:254:12 | s1 | main.rs:256:9:256:12 | TupleStructPat | -| main.rs:254:11:254:12 | s1 | main.rs:258:11:258:12 | s1 | -| main.rs:255:11:255:11 | [SSA] n | main.rs:255:22:255:22 | n | -| main.rs:255:11:255:11 | n | main.rs:255:11:255:11 | [SSA] n | -| main.rs:255:17:255:23 | sink(...) | main.rs:254:5:257:5 | match s1 { ... } | -| main.rs:256:11:256:11 | [SSA] n | main.rs:256:22:256:22 | n | -| main.rs:256:11:256:11 | n | main.rs:256:11:256:11 | [SSA] n | -| main.rs:256:17:256:23 | sink(...) | main.rs:254:5:257:5 | match s1 { ... } | -| main.rs:258:11:258:12 | s1 | main.rs:259:9:259:19 | ... \| ... | -| main.rs:259:9:259:19 | ... \| ... | main.rs:259:9:259:12 | TupleStructPat | -| main.rs:259:9:259:19 | ... \| ... | main.rs:259:16:259:19 | TupleStructPat | -| main.rs:259:9:259:19 | [SSA] [match(true)] phi | main.rs:259:29:259:29 | n | -| main.rs:259:11:259:11 | [SSA] [input] [match(true)] phi | main.rs:259:9:259:19 | [SSA] [match(true)] phi | -| main.rs:259:11:259:11 | [SSA] n | main.rs:259:11:259:11 | [SSA] [input] [match(true)] phi | -| main.rs:259:11:259:11 | n | main.rs:259:11:259:11 | [SSA] n | -| main.rs:259:18:259:18 | [SSA] [input] [match(true)] phi | main.rs:259:9:259:19 | [SSA] [match(true)] phi | -| main.rs:259:18:259:18 | [SSA] n | main.rs:259:18:259:18 | [SSA] [input] [match(true)] phi | -| main.rs:259:18:259:18 | n | main.rs:259:18:259:18 | [SSA] n | -| main.rs:259:24:259:30 | sink(...) | main.rs:258:5:260:5 | match s1 { ... } | -| main.rs:261:5:264:5 | match s2 { ... } | main.rs:251:50:265:1 | { ... } | -| main.rs:261:11:261:12 | s2 | main.rs:262:9:262:12 | TupleStructPat | -| main.rs:261:11:261:12 | s2 | main.rs:263:9:263:12 | TupleStructPat | -| main.rs:262:11:262:11 | [SSA] n | main.rs:262:22:262:22 | n | -| main.rs:262:11:262:11 | n | main.rs:262:11:262:11 | [SSA] n | -| main.rs:262:17:262:23 | sink(...) | main.rs:261:5:264:5 | match s2 { ... } | -| main.rs:263:11:263:11 | [SSA] n | main.rs:263:22:263:22 | n | -| main.rs:263:11:263:11 | n | main.rs:263:11:263:11 | [SSA] n | -| main.rs:263:17:263:23 | sink(...) | main.rs:261:5:264:5 | match s2 { ... } | -| main.rs:273:9:273:10 | [SSA] s1 | main.rs:277:11:277:12 | s1 | -| main.rs:273:9:273:10 | s1 | main.rs:273:9:273:10 | [SSA] s1 | -| main.rs:273:14:275:5 | ...::C {...} | main.rs:273:9:273:10 | s1 | +| main.rs:229:9:229:10 | [SSA] s1 | main.rs:231:14:231:15 | s1 | +| main.rs:229:9:229:10 | s1 | main.rs:229:9:229:10 | [SSA] s1 | +| main.rs:229:14:229:29 | Some(...) | main.rs:229:9:229:10 | s1 | +| main.rs:230:9:230:10 | [SSA] s2 | main.rs:232:14:232:15 | s2 | +| main.rs:230:9:230:10 | s2 | main.rs:230:9:230:10 | [SSA] s2 | +| main.rs:230:14:230:20 | Some(...) | main.rs:230:9:230:10 | s2 | +| main.rs:231:9:231:10 | [SSA] i1 | main.rs:233:10:233:11 | i1 | +| main.rs:231:9:231:10 | i1 | main.rs:231:9:231:10 | [SSA] i1 | +| main.rs:231:14:231:16 | TryExpr | main.rs:231:9:231:10 | i1 | +| main.rs:232:9:232:10 | [SSA] i2 | main.rs:234:10:234:11 | i2 | +| main.rs:232:9:232:10 | i2 | main.rs:232:9:232:10 | [SSA] i2 | +| main.rs:232:14:232:16 | TryExpr | main.rs:232:9:232:10 | i2 | +| main.rs:235:5:235:11 | Some(...) | main.rs:228:41:236:1 | { ... } | +| main.rs:239:9:239:10 | [SSA] s1 | main.rs:242:14:242:15 | s1 | +| main.rs:239:9:239:10 | s1 | main.rs:239:9:239:10 | [SSA] s1 | +| main.rs:239:32:239:45 | Ok(...) | main.rs:239:9:239:10 | s1 | +| main.rs:240:9:240:10 | [SSA] s2 | main.rs:243:14:243:15 | s2 | +| main.rs:240:9:240:10 | s2 | main.rs:240:9:240:10 | [SSA] s2 | +| main.rs:240:32:240:36 | Ok(...) | main.rs:240:9:240:10 | s2 | +| main.rs:241:9:241:10 | [SSA] s3 | main.rs:246:14:246:15 | s3 | +| main.rs:241:9:241:10 | s3 | main.rs:241:9:241:10 | [SSA] s3 | +| main.rs:241:32:241:46 | Err(...) | main.rs:241:9:241:10 | s3 | +| main.rs:242:9:242:10 | [SSA] i1 | main.rs:244:10:244:11 | i1 | +| main.rs:242:9:242:10 | i1 | main.rs:242:9:242:10 | [SSA] i1 | +| main.rs:242:14:242:16 | TryExpr | main.rs:242:9:242:10 | i1 | +| main.rs:243:9:243:10 | [SSA] i2 | main.rs:245:10:245:11 | i2 | +| main.rs:243:9:243:10 | i2 | main.rs:243:9:243:10 | [SSA] i2 | +| main.rs:243:14:243:16 | TryExpr | main.rs:243:9:243:10 | i2 | +| main.rs:246:9:246:10 | [SSA] i3 | main.rs:247:10:247:11 | i3 | +| main.rs:246:9:246:10 | i3 | main.rs:246:9:246:10 | [SSA] i3 | +| main.rs:246:14:246:16 | TryExpr | main.rs:246:9:246:10 | i3 | +| main.rs:248:5:248:9 | Ok(...) | main.rs:238:46:249:1 | { ... } | +| main.rs:257:9:257:10 | [SSA] s1 | main.rs:259:11:259:12 | s1 | +| main.rs:257:9:257:10 | s1 | main.rs:257:9:257:10 | [SSA] s1 | +| main.rs:257:14:257:39 | ...::A(...) | main.rs:257:9:257:10 | s1 | +| main.rs:258:9:258:10 | [SSA] s2 | main.rs:266:11:266:12 | s2 | +| main.rs:258:9:258:10 | s2 | main.rs:258:9:258:10 | [SSA] s2 | +| main.rs:258:14:258:30 | ...::B(...) | main.rs:258:9:258:10 | s2 | +| main.rs:259:11:259:12 | s1 | main.rs:260:9:260:25 | TupleStructPat | +| main.rs:259:11:259:12 | s1 | main.rs:261:9:261:25 | TupleStructPat | +| main.rs:259:11:259:12 | s1 | main.rs:263:11:263:12 | s1 | +| main.rs:260:24:260:24 | [SSA] n | main.rs:260:35:260:35 | n | +| main.rs:260:24:260:24 | n | main.rs:260:24:260:24 | [SSA] n | +| main.rs:260:30:260:36 | sink(...) | main.rs:259:5:262:5 | match s1 { ... } | +| main.rs:261:24:261:24 | [SSA] n | main.rs:261:35:261:35 | n | +| main.rs:261:24:261:24 | n | main.rs:261:24:261:24 | [SSA] n | +| main.rs:261:30:261:36 | sink(...) | main.rs:259:5:262:5 | match s1 { ... } | +| main.rs:263:11:263:12 | s1 | main.rs:264:9:264:45 | ... \| ... | +| main.rs:264:9:264:45 | ... \| ... | main.rs:264:9:264:25 | TupleStructPat | +| main.rs:264:9:264:45 | ... \| ... | main.rs:264:29:264:45 | TupleStructPat | +| main.rs:264:9:264:45 | [SSA] [match(true)] phi | main.rs:264:55:264:55 | n | +| main.rs:264:24:264:24 | [SSA] [input] [match(true)] phi | main.rs:264:9:264:45 | [SSA] [match(true)] phi | +| main.rs:264:24:264:24 | [SSA] n | main.rs:264:24:264:24 | [SSA] [input] [match(true)] phi | +| main.rs:264:24:264:24 | n | main.rs:264:24:264:24 | [SSA] n | +| main.rs:264:44:264:44 | [SSA] [input] [match(true)] phi | main.rs:264:9:264:45 | [SSA] [match(true)] phi | +| main.rs:264:44:264:44 | [SSA] n | main.rs:264:44:264:44 | [SSA] [input] [match(true)] phi | +| main.rs:264:44:264:44 | n | main.rs:264:44:264:44 | [SSA] n | +| main.rs:264:50:264:56 | sink(...) | main.rs:263:5:265:5 | match s1 { ... } | +| main.rs:266:5:269:5 | match s2 { ... } | main.rs:256:48:270:1 | { ... } | +| main.rs:266:11:266:12 | s2 | main.rs:267:9:267:25 | TupleStructPat | +| main.rs:266:11:266:12 | s2 | main.rs:268:9:268:25 | TupleStructPat | +| main.rs:267:24:267:24 | [SSA] n | main.rs:267:35:267:35 | n | +| main.rs:267:24:267:24 | n | main.rs:267:24:267:24 | [SSA] n | +| main.rs:267:30:267:36 | sink(...) | main.rs:266:5:269:5 | match s2 { ... } | +| main.rs:268:24:268:24 | [SSA] n | main.rs:268:35:268:35 | n | +| main.rs:268:24:268:24 | n | main.rs:268:24:268:24 | [SSA] n | +| main.rs:268:30:268:36 | sink(...) | main.rs:266:5:269:5 | match s2 { ... } | +| main.rs:275:9:275:10 | [SSA] s1 | main.rs:277:11:277:12 | s1 | +| main.rs:275:9:275:10 | s1 | main.rs:275:9:275:10 | [SSA] s1 | +| main.rs:275:14:275:26 | A(...) | main.rs:275:9:275:10 | s1 | | main.rs:276:9:276:10 | [SSA] s2 | main.rs:284:11:284:12 | s2 | | main.rs:276:9:276:10 | s2 | main.rs:276:9:276:10 | [SSA] s2 | -| main.rs:276:14:276:43 | ...::D {...} | main.rs:276:9:276:10 | s2 | -| main.rs:277:11:277:12 | s1 | main.rs:278:9:278:38 | ...::C {...} | -| main.rs:277:11:277:12 | s1 | main.rs:279:9:279:38 | ...::D {...} | +| main.rs:276:14:276:17 | B(...) | main.rs:276:9:276:10 | s2 | +| main.rs:277:11:277:12 | s1 | main.rs:278:9:278:12 | TupleStructPat | +| main.rs:277:11:277:12 | s1 | main.rs:279:9:279:12 | TupleStructPat | | main.rs:277:11:277:12 | s1 | main.rs:281:11:281:12 | s1 | -| main.rs:278:36:278:36 | [SSA] n | main.rs:278:48:278:48 | n | -| main.rs:278:36:278:36 | n | main.rs:278:36:278:36 | [SSA] n | -| main.rs:278:43:278:49 | sink(...) | main.rs:277:5:280:5 | match s1 { ... } | -| main.rs:279:36:279:36 | [SSA] n | main.rs:279:48:279:48 | n | -| main.rs:279:36:279:36 | n | main.rs:279:36:279:36 | [SSA] n | -| main.rs:279:43:279:49 | sink(...) | main.rs:277:5:280:5 | match s1 { ... } | -| main.rs:281:11:281:12 | s1 | main.rs:282:9:282:71 | ... \| ... | -| main.rs:282:9:282:71 | ... \| ... | main.rs:282:9:282:38 | ...::C {...} | -| main.rs:282:9:282:71 | ... \| ... | main.rs:282:42:282:71 | ...::D {...} | -| main.rs:282:9:282:71 | [SSA] [match(true)] phi | main.rs:282:81:282:81 | n | -| main.rs:282:36:282:36 | [SSA] [input] [match(true)] phi | main.rs:282:9:282:71 | [SSA] [match(true)] phi | -| main.rs:282:36:282:36 | [SSA] n | main.rs:282:36:282:36 | [SSA] [input] [match(true)] phi | -| main.rs:282:36:282:36 | n | main.rs:282:36:282:36 | [SSA] n | -| main.rs:282:69:282:69 | [SSA] [input] [match(true)] phi | main.rs:282:9:282:71 | [SSA] [match(true)] phi | -| main.rs:282:69:282:69 | [SSA] n | main.rs:282:69:282:69 | [SSA] [input] [match(true)] phi | -| main.rs:282:69:282:69 | n | main.rs:282:69:282:69 | [SSA] n | -| main.rs:282:76:282:82 | sink(...) | main.rs:281:5:283:5 | match s1 { ... } | -| main.rs:284:5:287:5 | match s2 { ... } | main.rs:272:49:288:1 | { ... } | -| main.rs:284:11:284:12 | s2 | main.rs:285:9:285:38 | ...::C {...} | -| main.rs:284:11:284:12 | s2 | main.rs:286:9:286:38 | ...::D {...} | -| main.rs:285:36:285:36 | [SSA] n | main.rs:285:48:285:48 | n | -| main.rs:285:36:285:36 | n | main.rs:285:36:285:36 | [SSA] n | -| main.rs:285:43:285:49 | sink(...) | main.rs:284:5:287:5 | match s2 { ... } | -| main.rs:286:36:286:36 | [SSA] n | main.rs:286:48:286:48 | n | -| main.rs:286:36:286:36 | n | main.rs:286:36:286:36 | [SSA] n | -| main.rs:286:43:286:49 | sink(...) | main.rs:284:5:287:5 | match s2 { ... } | -| main.rs:293:9:293:10 | [SSA] s1 | main.rs:297:11:297:12 | s1 | -| main.rs:293:9:293:10 | s1 | main.rs:293:9:293:10 | [SSA] s1 | -| main.rs:293:14:295:5 | C {...} | main.rs:293:9:293:10 | s1 | -| main.rs:296:9:296:10 | [SSA] s2 | main.rs:304:11:304:12 | s2 | -| main.rs:296:9:296:10 | s2 | main.rs:296:9:296:10 | [SSA] s2 | -| main.rs:296:14:296:29 | D {...} | main.rs:296:9:296:10 | s2 | -| main.rs:297:11:297:12 | s1 | main.rs:298:9:298:24 | C {...} | -| main.rs:297:11:297:12 | s1 | main.rs:299:9:299:24 | D {...} | -| main.rs:297:11:297:12 | s1 | main.rs:301:11:301:12 | s1 | -| main.rs:298:22:298:22 | [SSA] n | main.rs:298:34:298:34 | n | -| main.rs:298:22:298:22 | n | main.rs:298:22:298:22 | [SSA] n | -| main.rs:298:29:298:35 | sink(...) | main.rs:297:5:300:5 | match s1 { ... } | -| main.rs:299:22:299:22 | [SSA] n | main.rs:299:34:299:34 | n | -| main.rs:299:22:299:22 | n | main.rs:299:22:299:22 | [SSA] n | -| main.rs:299:29:299:35 | sink(...) | main.rs:297:5:300:5 | match s1 { ... } | -| main.rs:301:11:301:12 | s1 | main.rs:302:9:302:43 | ... \| ... | -| main.rs:302:9:302:43 | ... \| ... | main.rs:302:9:302:24 | C {...} | -| main.rs:302:9:302:43 | ... \| ... | main.rs:302:28:302:43 | D {...} | -| main.rs:302:9:302:43 | [SSA] [match(true)] phi | main.rs:302:53:302:53 | n | -| main.rs:302:22:302:22 | [SSA] [input] [match(true)] phi | main.rs:302:9:302:43 | [SSA] [match(true)] phi | -| main.rs:302:22:302:22 | [SSA] n | main.rs:302:22:302:22 | [SSA] [input] [match(true)] phi | -| main.rs:302:22:302:22 | n | main.rs:302:22:302:22 | [SSA] n | -| main.rs:302:41:302:41 | [SSA] [input] [match(true)] phi | main.rs:302:9:302:43 | [SSA] [match(true)] phi | -| main.rs:302:41:302:41 | [SSA] n | main.rs:302:41:302:41 | [SSA] [input] [match(true)] phi | -| main.rs:302:41:302:41 | n | main.rs:302:41:302:41 | [SSA] n | -| main.rs:302:48:302:54 | sink(...) | main.rs:301:5:303:5 | match s1 { ... } | -| main.rs:304:5:307:5 | match s2 { ... } | main.rs:292:51:308:1 | { ... } | -| main.rs:304:11:304:12 | s2 | main.rs:305:9:305:24 | C {...} | -| main.rs:304:11:304:12 | s2 | main.rs:306:9:306:24 | D {...} | -| main.rs:305:22:305:22 | [SSA] n | main.rs:305:34:305:34 | n | -| main.rs:305:22:305:22 | n | main.rs:305:22:305:22 | [SSA] n | -| main.rs:305:29:305:35 | sink(...) | main.rs:304:5:307:5 | match s2 { ... } | -| main.rs:306:22:306:22 | [SSA] n | main.rs:306:34:306:34 | n | -| main.rs:306:22:306:22 | n | main.rs:306:22:306:22 | [SSA] n | -| main.rs:306:29:306:35 | sink(...) | main.rs:304:5:307:5 | match s2 { ... } | +| main.rs:278:11:278:11 | [SSA] n | main.rs:278:22:278:22 | n | +| main.rs:278:11:278:11 | n | main.rs:278:11:278:11 | [SSA] n | +| main.rs:278:17:278:23 | sink(...) | main.rs:277:5:280:5 | match s1 { ... } | +| main.rs:279:11:279:11 | [SSA] n | main.rs:279:22:279:22 | n | +| main.rs:279:11:279:11 | n | main.rs:279:11:279:11 | [SSA] n | +| main.rs:279:17:279:23 | sink(...) | main.rs:277:5:280:5 | match s1 { ... } | +| main.rs:281:11:281:12 | s1 | main.rs:282:9:282:19 | ... \| ... | +| main.rs:282:9:282:19 | ... \| ... | main.rs:282:9:282:12 | TupleStructPat | +| main.rs:282:9:282:19 | ... \| ... | main.rs:282:16:282:19 | TupleStructPat | +| main.rs:282:9:282:19 | [SSA] [match(true)] phi | main.rs:282:29:282:29 | n | +| main.rs:282:11:282:11 | [SSA] [input] [match(true)] phi | main.rs:282:9:282:19 | [SSA] [match(true)] phi | +| main.rs:282:11:282:11 | [SSA] n | main.rs:282:11:282:11 | [SSA] [input] [match(true)] phi | +| main.rs:282:11:282:11 | n | main.rs:282:11:282:11 | [SSA] n | +| main.rs:282:18:282:18 | [SSA] [input] [match(true)] phi | main.rs:282:9:282:19 | [SSA] [match(true)] phi | +| main.rs:282:18:282:18 | [SSA] n | main.rs:282:18:282:18 | [SSA] [input] [match(true)] phi | +| main.rs:282:18:282:18 | n | main.rs:282:18:282:18 | [SSA] n | +| main.rs:282:24:282:30 | sink(...) | main.rs:281:5:283:5 | match s1 { ... } | +| main.rs:284:5:287:5 | match s2 { ... } | main.rs:274:50:288:1 | { ... } | +| main.rs:284:11:284:12 | s2 | main.rs:285:9:285:12 | TupleStructPat | +| main.rs:284:11:284:12 | s2 | main.rs:286:9:286:12 | TupleStructPat | +| main.rs:285:11:285:11 | [SSA] n | main.rs:285:22:285:22 | n | +| main.rs:285:11:285:11 | n | main.rs:285:11:285:11 | [SSA] n | +| main.rs:285:17:285:23 | sink(...) | main.rs:284:5:287:5 | match s2 { ... } | +| main.rs:286:11:286:11 | [SSA] n | main.rs:286:22:286:22 | n | +| main.rs:286:11:286:11 | n | main.rs:286:11:286:11 | [SSA] n | +| main.rs:286:17:286:23 | sink(...) | main.rs:284:5:287:5 | match s2 { ... } | +| main.rs:296:9:296:10 | [SSA] s1 | main.rs:300:11:300:12 | s1 | +| main.rs:296:9:296:10 | s1 | main.rs:296:9:296:10 | [SSA] s1 | +| main.rs:296:14:298:5 | ...::C {...} | main.rs:296:9:296:10 | s1 | +| main.rs:299:9:299:10 | [SSA] s2 | main.rs:307:11:307:12 | s2 | +| main.rs:299:9:299:10 | s2 | main.rs:299:9:299:10 | [SSA] s2 | +| main.rs:299:14:299:43 | ...::D {...} | main.rs:299:9:299:10 | s2 | +| main.rs:300:11:300:12 | s1 | main.rs:301:9:301:38 | ...::C {...} | +| main.rs:300:11:300:12 | s1 | main.rs:302:9:302:38 | ...::D {...} | +| main.rs:300:11:300:12 | s1 | main.rs:304:11:304:12 | s1 | +| main.rs:301:36:301:36 | [SSA] n | main.rs:301:48:301:48 | n | +| main.rs:301:36:301:36 | n | main.rs:301:36:301:36 | [SSA] n | +| main.rs:301:43:301:49 | sink(...) | main.rs:300:5:303:5 | match s1 { ... } | +| main.rs:302:36:302:36 | [SSA] n | main.rs:302:48:302:48 | n | +| main.rs:302:36:302:36 | n | main.rs:302:36:302:36 | [SSA] n | +| main.rs:302:43:302:49 | sink(...) | main.rs:300:5:303:5 | match s1 { ... } | +| main.rs:304:11:304:12 | s1 | main.rs:305:9:305:71 | ... \| ... | +| main.rs:305:9:305:71 | ... \| ... | main.rs:305:9:305:38 | ...::C {...} | +| main.rs:305:9:305:71 | ... \| ... | main.rs:305:42:305:71 | ...::D {...} | +| main.rs:305:9:305:71 | [SSA] [match(true)] phi | main.rs:305:81:305:81 | n | +| main.rs:305:36:305:36 | [SSA] [input] [match(true)] phi | main.rs:305:9:305:71 | [SSA] [match(true)] phi | +| main.rs:305:36:305:36 | [SSA] n | main.rs:305:36:305:36 | [SSA] [input] [match(true)] phi | +| main.rs:305:36:305:36 | n | main.rs:305:36:305:36 | [SSA] n | +| main.rs:305:69:305:69 | [SSA] [input] [match(true)] phi | main.rs:305:9:305:71 | [SSA] [match(true)] phi | +| main.rs:305:69:305:69 | [SSA] n | main.rs:305:69:305:69 | [SSA] [input] [match(true)] phi | +| main.rs:305:69:305:69 | n | main.rs:305:69:305:69 | [SSA] n | +| main.rs:305:76:305:82 | sink(...) | main.rs:304:5:306:5 | match s1 { ... } | +| main.rs:307:5:310:5 | match s2 { ... } | main.rs:295:49:311:1 | { ... } | +| main.rs:307:11:307:12 | s2 | main.rs:308:9:308:38 | ...::C {...} | +| main.rs:307:11:307:12 | s2 | main.rs:309:9:309:38 | ...::D {...} | +| main.rs:308:36:308:36 | [SSA] n | main.rs:308:48:308:48 | n | +| main.rs:308:36:308:36 | n | main.rs:308:36:308:36 | [SSA] n | +| main.rs:308:43:308:49 | sink(...) | main.rs:307:5:310:5 | match s2 { ... } | +| main.rs:309:36:309:36 | [SSA] n | main.rs:309:48:309:48 | n | +| main.rs:309:36:309:36 | n | main.rs:309:36:309:36 | [SSA] n | +| main.rs:309:43:309:49 | sink(...) | main.rs:307:5:310:5 | match s2 { ... } | +| main.rs:316:9:316:10 | [SSA] s1 | main.rs:320:11:320:12 | s1 | +| main.rs:316:9:316:10 | s1 | main.rs:316:9:316:10 | [SSA] s1 | +| main.rs:316:14:318:5 | C {...} | main.rs:316:9:316:10 | s1 | +| main.rs:319:9:319:10 | [SSA] s2 | main.rs:327:11:327:12 | s2 | +| main.rs:319:9:319:10 | s2 | main.rs:319:9:319:10 | [SSA] s2 | +| main.rs:319:14:319:29 | D {...} | main.rs:319:9:319:10 | s2 | +| main.rs:320:11:320:12 | s1 | main.rs:321:9:321:24 | C {...} | +| main.rs:320:11:320:12 | s1 | main.rs:322:9:322:24 | D {...} | +| main.rs:320:11:320:12 | s1 | main.rs:324:11:324:12 | s1 | +| main.rs:321:22:321:22 | [SSA] n | main.rs:321:34:321:34 | n | +| main.rs:321:22:321:22 | n | main.rs:321:22:321:22 | [SSA] n | +| main.rs:321:29:321:35 | sink(...) | main.rs:320:5:323:5 | match s1 { ... } | +| main.rs:322:22:322:22 | [SSA] n | main.rs:322:34:322:34 | n | +| main.rs:322:22:322:22 | n | main.rs:322:22:322:22 | [SSA] n | +| main.rs:322:29:322:35 | sink(...) | main.rs:320:5:323:5 | match s1 { ... } | +| main.rs:324:11:324:12 | s1 | main.rs:325:9:325:43 | ... \| ... | +| main.rs:325:9:325:43 | ... \| ... | main.rs:325:9:325:24 | C {...} | +| main.rs:325:9:325:43 | ... \| ... | main.rs:325:28:325:43 | D {...} | +| main.rs:325:9:325:43 | [SSA] [match(true)] phi | main.rs:325:53:325:53 | n | +| main.rs:325:22:325:22 | [SSA] [input] [match(true)] phi | main.rs:325:9:325:43 | [SSA] [match(true)] phi | +| main.rs:325:22:325:22 | [SSA] n | main.rs:325:22:325:22 | [SSA] [input] [match(true)] phi | +| main.rs:325:22:325:22 | n | main.rs:325:22:325:22 | [SSA] n | +| main.rs:325:41:325:41 | [SSA] [input] [match(true)] phi | main.rs:325:9:325:43 | [SSA] [match(true)] phi | +| main.rs:325:41:325:41 | [SSA] n | main.rs:325:41:325:41 | [SSA] [input] [match(true)] phi | +| main.rs:325:41:325:41 | n | main.rs:325:41:325:41 | [SSA] n | +| main.rs:325:48:325:54 | sink(...) | main.rs:324:5:326:5 | match s1 { ... } | +| main.rs:327:5:330:5 | match s2 { ... } | main.rs:315:51:331:1 | { ... } | +| main.rs:327:11:327:12 | s2 | main.rs:328:9:328:24 | C {...} | +| main.rs:327:11:327:12 | s2 | main.rs:329:9:329:24 | D {...} | +| main.rs:328:22:328:22 | [SSA] n | main.rs:328:34:328:34 | n | +| main.rs:328:22:328:22 | n | main.rs:328:22:328:22 | [SSA] n | +| main.rs:328:29:328:35 | sink(...) | main.rs:327:5:330:5 | match s2 { ... } | +| main.rs:329:22:329:22 | [SSA] n | main.rs:329:34:329:34 | n | +| main.rs:329:22:329:22 | n | main.rs:329:22:329:22 | [SSA] n | +| main.rs:329:29:329:35 | sink(...) | main.rs:327:5:330:5 | match s2 { ... } | +| main.rs:354:13:354:33 | result_questionmark(...) | main.rs:354:9:354:9 | _ | storeStep | main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr | | main.rs:94:25:94:25 | 2 | tuple.1 | main.rs:94:13:94:26 | TupleExpr | @@ -377,15 +410,22 @@ storeStep | main.rs:211:19:211:28 | source(...) | Some | main.rs:211:14:211:29 | Some(...) | | main.rs:212:19:212:19 | 2 | Some | main.rs:212:14:212:20 | Some(...) | | main.rs:224:19:224:28 | source(...) | Some | main.rs:224:14:224:29 | Some(...) | -| main.rs:234:29:234:38 | source(...) | A | main.rs:234:14:234:39 | ...::A(...) | -| main.rs:235:29:235:29 | 2 | B | main.rs:235:14:235:30 | ...::B(...) | -| main.rs:252:16:252:25 | source(...) | A | main.rs:252:14:252:26 | A(...) | -| main.rs:253:16:253:16 | 2 | B | main.rs:253:14:253:17 | B(...) | -| main.rs:274:18:274:27 | source(...) | C | main.rs:273:14:275:5 | ...::C {...} | -| main.rs:276:41:276:41 | 2 | D | main.rs:276:14:276:43 | ...::D {...} | -| main.rs:294:18:294:27 | source(...) | C | main.rs:293:14:295:5 | C {...} | -| main.rs:296:27:296:27 | 2 | D | main.rs:296:14:296:29 | D {...} | -| main.rs:314:27:314:27 | 0 | Some | main.rs:314:22:314:28 | Some(...) | +| main.rs:229:19:229:28 | source(...) | Some | main.rs:229:14:229:29 | Some(...) | +| main.rs:230:19:230:19 | 2 | Some | main.rs:230:14:230:20 | Some(...) | +| main.rs:235:10:235:10 | 0 | Some | main.rs:235:5:235:11 | Some(...) | +| main.rs:239:35:239:44 | source(...) | Ok | main.rs:239:32:239:45 | Ok(...) | +| main.rs:240:35:240:35 | 2 | Ok | main.rs:240:32:240:36 | Ok(...) | +| main.rs:241:36:241:45 | source(...) | Err | main.rs:241:32:241:46 | Err(...) | +| main.rs:248:8:248:8 | 0 | Ok | main.rs:248:5:248:9 | Ok(...) | +| main.rs:257:29:257:38 | source(...) | A | main.rs:257:14:257:39 | ...::A(...) | +| main.rs:258:29:258:29 | 2 | B | main.rs:258:14:258:30 | ...::B(...) | +| main.rs:275:16:275:25 | source(...) | A | main.rs:275:14:275:26 | A(...) | +| main.rs:276:16:276:16 | 2 | B | main.rs:276:14:276:17 | B(...) | +| main.rs:297:18:297:27 | source(...) | C | main.rs:296:14:298:5 | ...::C {...} | +| main.rs:299:41:299:41 | 2 | D | main.rs:299:14:299:43 | ...::D {...} | +| main.rs:317:18:317:27 | source(...) | C | main.rs:316:14:318:5 | C {...} | +| main.rs:319:27:319:27 | 2 | D | main.rs:319:14:319:29 | D {...} | +| main.rs:337:27:337:27 | 0 | Some | main.rs:337:22:337:28 | Some(...) | readStep | file://:0:0:0:0 | [summary param] self in lang:core::_::::unwrap | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::::unwrap | | main.rs:33:9:33:15 | TupleStructPat | Some | main.rs:33:14:33:14 | _ | @@ -409,27 +449,27 @@ readStep | main.rs:205:9:205:23 | TupleStructPat | Some | main.rs:205:22:205:22 | n | | main.rs:214:9:214:15 | TupleStructPat | Some | main.rs:214:14:214:14 | n | | main.rs:218:9:218:15 | TupleStructPat | Some | main.rs:218:14:218:14 | n | -| main.rs:237:9:237:25 | TupleStructPat | A | main.rs:237:24:237:24 | n | -| main.rs:238:9:238:25 | TupleStructPat | B | main.rs:238:24:238:24 | n | -| main.rs:241:9:241:25 | TupleStructPat | A | main.rs:241:24:241:24 | n | -| main.rs:241:29:241:45 | TupleStructPat | B | main.rs:241:44:241:44 | n | -| main.rs:244:9:244:25 | TupleStructPat | A | main.rs:244:24:244:24 | n | -| main.rs:245:9:245:25 | TupleStructPat | B | main.rs:245:24:245:24 | n | -| main.rs:255:9:255:12 | TupleStructPat | A | main.rs:255:11:255:11 | n | -| main.rs:256:9:256:12 | TupleStructPat | B | main.rs:256:11:256:11 | n | -| main.rs:259:9:259:12 | TupleStructPat | A | main.rs:259:11:259:11 | n | -| main.rs:259:16:259:19 | TupleStructPat | B | main.rs:259:18:259:18 | n | -| main.rs:262:9:262:12 | TupleStructPat | A | main.rs:262:11:262:11 | n | -| main.rs:263:9:263:12 | TupleStructPat | B | main.rs:263:11:263:11 | n | -| main.rs:278:9:278:38 | ...::C {...} | C | main.rs:278:36:278:36 | n | -| main.rs:279:9:279:38 | ...::D {...} | D | main.rs:279:36:279:36 | n | -| main.rs:282:9:282:38 | ...::C {...} | C | main.rs:282:36:282:36 | n | -| main.rs:282:42:282:71 | ...::D {...} | D | main.rs:282:69:282:69 | n | -| main.rs:285:9:285:38 | ...::C {...} | C | main.rs:285:36:285:36 | n | -| main.rs:286:9:286:38 | ...::D {...} | D | main.rs:286:36:286:36 | n | -| main.rs:298:9:298:24 | C {...} | C | main.rs:298:22:298:22 | n | -| main.rs:299:9:299:24 | D {...} | D | main.rs:299:22:299:22 | n | -| main.rs:302:9:302:24 | C {...} | C | main.rs:302:22:302:22 | n | -| main.rs:302:28:302:43 | D {...} | D | main.rs:302:41:302:41 | n | -| main.rs:305:9:305:24 | C {...} | C | main.rs:305:22:305:22 | n | -| main.rs:306:9:306:24 | D {...} | D | main.rs:306:22:306:22 | n | +| main.rs:260:9:260:25 | TupleStructPat | A | main.rs:260:24:260:24 | n | +| main.rs:261:9:261:25 | TupleStructPat | B | main.rs:261:24:261:24 | n | +| main.rs:264:9:264:25 | TupleStructPat | A | main.rs:264:24:264:24 | n | +| main.rs:264:29:264:45 | TupleStructPat | B | main.rs:264:44:264:44 | n | +| main.rs:267:9:267:25 | TupleStructPat | A | main.rs:267:24:267:24 | n | +| main.rs:268:9:268:25 | TupleStructPat | B | main.rs:268:24:268:24 | n | +| main.rs:278:9:278:12 | TupleStructPat | A | main.rs:278:11:278:11 | n | +| main.rs:279:9:279:12 | TupleStructPat | B | main.rs:279:11:279:11 | n | +| main.rs:282:9:282:12 | TupleStructPat | A | main.rs:282:11:282:11 | n | +| main.rs:282:16:282:19 | TupleStructPat | B | main.rs:282:18:282:18 | n | +| main.rs:285:9:285:12 | TupleStructPat | A | main.rs:285:11:285:11 | n | +| main.rs:286:9:286:12 | TupleStructPat | B | main.rs:286:11:286:11 | n | +| main.rs:301:9:301:38 | ...::C {...} | C | main.rs:301:36:301:36 | n | +| main.rs:302:9:302:38 | ...::D {...} | D | main.rs:302:36:302:36 | n | +| main.rs:305:9:305:38 | ...::C {...} | C | main.rs:305:36:305:36 | n | +| main.rs:305:42:305:71 | ...::D {...} | D | main.rs:305:69:305:69 | n | +| main.rs:308:9:308:38 | ...::C {...} | C | main.rs:308:36:308:36 | n | +| main.rs:309:9:309:38 | ...::D {...} | D | main.rs:309:36:309:36 | n | +| main.rs:321:9:321:24 | C {...} | C | main.rs:321:22:321:22 | n | +| main.rs:322:9:322:24 | D {...} | D | main.rs:322:22:322:22 | n | +| main.rs:325:9:325:24 | C {...} | C | main.rs:325:22:325:22 | n | +| main.rs:325:28:325:43 | D {...} | D | main.rs:325:41:325:41 | n | +| main.rs:328:9:328:24 | C {...} | C | main.rs:328:22:328:22 | n | +| main.rs:329:9:329:24 | D {...} | D | main.rs:329:22:329:22 | n | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index ed51d66a1ad..75b0273f8e6 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -36,34 +36,34 @@ edges | main.rs:224:14:224:29 | Some(...) [Some] | main.rs:225:10:225:11 | s1 [Some] | provenance | | | main.rs:224:19:224:28 | source(...) | main.rs:224:14:224:29 | Some(...) [Some] | provenance | | | main.rs:225:10:225:11 | s1 [Some] | main.rs:225:10:225:20 | ... .unwrap(...) | provenance | | -| main.rs:234:14:234:39 | ...::A(...) [A] | main.rs:237:9:237:25 | TupleStructPat [A] | provenance | | -| main.rs:234:14:234:39 | ...::A(...) [A] | main.rs:241:9:241:25 | TupleStructPat [A] | provenance | | -| main.rs:234:29:234:38 | source(...) | main.rs:234:14:234:39 | ...::A(...) [A] | provenance | | -| main.rs:237:9:237:25 | TupleStructPat [A] | main.rs:237:24:237:24 | n | provenance | | -| main.rs:237:24:237:24 | n | main.rs:237:35:237:35 | n | provenance | | -| main.rs:241:9:241:25 | TupleStructPat [A] | main.rs:241:24:241:24 | n | provenance | | -| main.rs:241:24:241:24 | n | main.rs:241:55:241:55 | n | provenance | | -| main.rs:252:14:252:26 | A(...) [A] | main.rs:255:9:255:12 | TupleStructPat [A] | provenance | | -| main.rs:252:14:252:26 | A(...) [A] | main.rs:259:9:259:12 | TupleStructPat [A] | provenance | | -| main.rs:252:16:252:25 | source(...) | main.rs:252:14:252:26 | A(...) [A] | provenance | | -| main.rs:255:9:255:12 | TupleStructPat [A] | main.rs:255:11:255:11 | n | provenance | | -| main.rs:255:11:255:11 | n | main.rs:255:22:255:22 | n | provenance | | -| main.rs:259:9:259:12 | TupleStructPat [A] | main.rs:259:11:259:11 | n | provenance | | -| main.rs:259:11:259:11 | n | main.rs:259:29:259:29 | n | provenance | | -| main.rs:273:14:275:5 | ...::C {...} [C] | main.rs:278:9:278:38 | ...::C {...} [C] | provenance | | -| main.rs:273:14:275:5 | ...::C {...} [C] | main.rs:282:9:282:38 | ...::C {...} [C] | provenance | | -| main.rs:274:18:274:27 | source(...) | main.rs:273:14:275:5 | ...::C {...} [C] | provenance | | -| main.rs:278:9:278:38 | ...::C {...} [C] | main.rs:278:36:278:36 | n | provenance | | -| main.rs:278:36:278:36 | n | main.rs:278:48:278:48 | n | provenance | | -| main.rs:282:9:282:38 | ...::C {...} [C] | main.rs:282:36:282:36 | n | provenance | | -| main.rs:282:36:282:36 | n | main.rs:282:81:282:81 | n | provenance | | -| main.rs:293:14:295:5 | C {...} [C] | main.rs:298:9:298:24 | C {...} [C] | provenance | | -| main.rs:293:14:295:5 | C {...} [C] | main.rs:302:9:302:24 | C {...} [C] | provenance | | -| main.rs:294:18:294:27 | source(...) | main.rs:293:14:295:5 | C {...} [C] | provenance | | -| main.rs:298:9:298:24 | C {...} [C] | main.rs:298:22:298:22 | n | provenance | | -| main.rs:298:22:298:22 | n | main.rs:298:34:298:34 | n | provenance | | -| main.rs:302:9:302:24 | C {...} [C] | main.rs:302:22:302:22 | n | provenance | | -| main.rs:302:22:302:22 | n | main.rs:302:53:302:53 | n | provenance | | +| main.rs:257:14:257:39 | ...::A(...) [A] | main.rs:260:9:260:25 | TupleStructPat [A] | provenance | | +| main.rs:257:14:257:39 | ...::A(...) [A] | main.rs:264:9:264:25 | TupleStructPat [A] | provenance | | +| main.rs:257:29:257:38 | source(...) | main.rs:257:14:257:39 | ...::A(...) [A] | provenance | | +| main.rs:260:9:260:25 | TupleStructPat [A] | main.rs:260:24:260:24 | n | provenance | | +| main.rs:260:24:260:24 | n | main.rs:260:35:260:35 | n | provenance | | +| main.rs:264:9:264:25 | TupleStructPat [A] | main.rs:264:24:264:24 | n | provenance | | +| main.rs:264:24:264:24 | n | main.rs:264:55:264:55 | n | provenance | | +| main.rs:275:14:275:26 | A(...) [A] | main.rs:278:9:278:12 | TupleStructPat [A] | provenance | | +| main.rs:275:14:275:26 | A(...) [A] | main.rs:282:9:282:12 | TupleStructPat [A] | provenance | | +| main.rs:275:16:275:25 | source(...) | main.rs:275:14:275:26 | A(...) [A] | provenance | | +| main.rs:278:9:278:12 | TupleStructPat [A] | main.rs:278:11:278:11 | n | provenance | | +| main.rs:278:11:278:11 | n | main.rs:278:22:278:22 | n | provenance | | +| main.rs:282:9:282:12 | TupleStructPat [A] | main.rs:282:11:282:11 | n | provenance | | +| main.rs:282:11:282:11 | n | main.rs:282:29:282:29 | n | provenance | | +| main.rs:296:14:298:5 | ...::C {...} [C] | main.rs:301:9:301:38 | ...::C {...} [C] | provenance | | +| main.rs:296:14:298:5 | ...::C {...} [C] | main.rs:305:9:305:38 | ...::C {...} [C] | provenance | | +| main.rs:297:18:297:27 | source(...) | main.rs:296:14:298:5 | ...::C {...} [C] | provenance | | +| main.rs:301:9:301:38 | ...::C {...} [C] | main.rs:301:36:301:36 | n | provenance | | +| main.rs:301:36:301:36 | n | main.rs:301:48:301:48 | n | provenance | | +| main.rs:305:9:305:38 | ...::C {...} [C] | main.rs:305:36:305:36 | n | provenance | | +| main.rs:305:36:305:36 | n | main.rs:305:81:305:81 | n | provenance | | +| main.rs:316:14:318:5 | C {...} [C] | main.rs:321:9:321:24 | C {...} [C] | provenance | | +| main.rs:316:14:318:5 | C {...} [C] | main.rs:325:9:325:24 | C {...} [C] | provenance | | +| main.rs:317:18:317:27 | source(...) | main.rs:316:14:318:5 | C {...} [C] | provenance | | +| main.rs:321:9:321:24 | C {...} [C] | main.rs:321:22:321:22 | n | provenance | | +| main.rs:321:22:321:22 | n | main.rs:321:34:321:34 | n | provenance | | +| main.rs:325:9:325:24 | C {...} [C] | main.rs:325:22:325:22 | n | provenance | | +| main.rs:325:22:325:22 | n | main.rs:325:53:325:53 | n | provenance | | nodes | main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | | main.rs:19:13:19:21 | source(...) | semmle.label | source(...) | @@ -115,38 +115,38 @@ nodes | main.rs:224:19:224:28 | source(...) | semmle.label | source(...) | | main.rs:225:10:225:11 | s1 [Some] | semmle.label | s1 [Some] | | main.rs:225:10:225:20 | ... .unwrap(...) | semmle.label | ... .unwrap(...) | -| main.rs:234:14:234:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | -| main.rs:234:29:234:38 | source(...) | semmle.label | source(...) | -| main.rs:237:9:237:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:237:24:237:24 | n | semmle.label | n | -| main.rs:237:35:237:35 | n | semmle.label | n | -| main.rs:241:9:241:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:241:24:241:24 | n | semmle.label | n | -| main.rs:241:55:241:55 | n | semmle.label | n | -| main.rs:252:14:252:26 | A(...) [A] | semmle.label | A(...) [A] | -| main.rs:252:16:252:25 | source(...) | semmle.label | source(...) | -| main.rs:255:9:255:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:255:11:255:11 | n | semmle.label | n | -| main.rs:255:22:255:22 | n | semmle.label | n | -| main.rs:259:9:259:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:259:11:259:11 | n | semmle.label | n | -| main.rs:259:29:259:29 | n | semmle.label | n | -| main.rs:273:14:275:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:274:18:274:27 | source(...) | semmle.label | source(...) | -| main.rs:278:9:278:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:278:36:278:36 | n | semmle.label | n | -| main.rs:278:48:278:48 | n | semmle.label | n | -| main.rs:282:9:282:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:282:36:282:36 | n | semmle.label | n | -| main.rs:282:81:282:81 | n | semmle.label | n | -| main.rs:293:14:295:5 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:294:18:294:27 | source(...) | semmle.label | source(...) | -| main.rs:298:9:298:24 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:298:22:298:22 | n | semmle.label | n | -| main.rs:298:34:298:34 | n | semmle.label | n | -| main.rs:302:9:302:24 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:302:22:302:22 | n | semmle.label | n | -| main.rs:302:53:302:53 | n | semmle.label | n | +| main.rs:257:14:257:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | +| main.rs:257:29:257:38 | source(...) | semmle.label | source(...) | +| main.rs:260:9:260:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:260:24:260:24 | n | semmle.label | n | +| main.rs:260:35:260:35 | n | semmle.label | n | +| main.rs:264:9:264:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:264:24:264:24 | n | semmle.label | n | +| main.rs:264:55:264:55 | n | semmle.label | n | +| main.rs:275:14:275:26 | A(...) [A] | semmle.label | A(...) [A] | +| main.rs:275:16:275:25 | source(...) | semmle.label | source(...) | +| main.rs:278:9:278:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:278:11:278:11 | n | semmle.label | n | +| main.rs:278:22:278:22 | n | semmle.label | n | +| main.rs:282:9:282:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:282:11:282:11 | n | semmle.label | n | +| main.rs:282:29:282:29 | n | semmle.label | n | +| main.rs:296:14:298:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:297:18:297:27 | source(...) | semmle.label | source(...) | +| main.rs:301:9:301:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:301:36:301:36 | n | semmle.label | n | +| main.rs:301:48:301:48 | n | semmle.label | n | +| main.rs:305:9:305:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:305:36:305:36 | n | semmle.label | n | +| main.rs:305:81:305:81 | n | semmle.label | n | +| main.rs:316:14:318:5 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:317:18:317:27 | source(...) | semmle.label | source(...) | +| main.rs:321:9:321:24 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:321:22:321:22 | n | semmle.label | n | +| main.rs:321:34:321:34 | n | semmle.label | n | +| main.rs:325:9:325:24 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:325:22:325:22 | n | semmle.label | n | +| main.rs:325:53:325:53 | n | semmle.label | n | subpaths testFailures #select @@ -164,11 +164,11 @@ testFailures | main.rs:201:33:201:33 | n | main.rs:198:27:198:36 | source(...) | main.rs:201:33:201:33 | n | $@ | main.rs:198:27:198:36 | source(...) | source(...) | | main.rs:214:25:214:25 | n | main.rs:211:19:211:28 | source(...) | main.rs:214:25:214:25 | n | $@ | main.rs:211:19:211:28 | source(...) | source(...) | | main.rs:225:10:225:20 | ... .unwrap(...) | main.rs:224:19:224:28 | source(...) | main.rs:225:10:225:20 | ... .unwrap(...) | $@ | main.rs:224:19:224:28 | source(...) | source(...) | -| main.rs:237:35:237:35 | n | main.rs:234:29:234:38 | source(...) | main.rs:237:35:237:35 | n | $@ | main.rs:234:29:234:38 | source(...) | source(...) | -| main.rs:241:55:241:55 | n | main.rs:234:29:234:38 | source(...) | main.rs:241:55:241:55 | n | $@ | main.rs:234:29:234:38 | source(...) | source(...) | -| main.rs:255:22:255:22 | n | main.rs:252:16:252:25 | source(...) | main.rs:255:22:255:22 | n | $@ | main.rs:252:16:252:25 | source(...) | source(...) | -| main.rs:259:29:259:29 | n | main.rs:252:16:252:25 | source(...) | main.rs:259:29:259:29 | n | $@ | main.rs:252:16:252:25 | source(...) | source(...) | -| main.rs:278:48:278:48 | n | main.rs:274:18:274:27 | source(...) | main.rs:278:48:278:48 | n | $@ | main.rs:274:18:274:27 | source(...) | source(...) | -| main.rs:282:81:282:81 | n | main.rs:274:18:274:27 | source(...) | main.rs:282:81:282:81 | n | $@ | main.rs:274:18:274:27 | source(...) | source(...) | -| main.rs:298:34:298:34 | n | main.rs:294:18:294:27 | source(...) | main.rs:298:34:298:34 | n | $@ | main.rs:294:18:294:27 | source(...) | source(...) | -| main.rs:302:53:302:53 | n | main.rs:294:18:294:27 | source(...) | main.rs:302:53:302:53 | n | $@ | main.rs:294:18:294:27 | source(...) | source(...) | +| main.rs:260:35:260:35 | n | main.rs:257:29:257:38 | source(...) | main.rs:260:35:260:35 | n | $@ | main.rs:257:29:257:38 | source(...) | source(...) | +| main.rs:264:55:264:55 | n | main.rs:257:29:257:38 | source(...) | main.rs:264:55:264:55 | n | $@ | main.rs:257:29:257:38 | source(...) | source(...) | +| main.rs:278:22:278:22 | n | main.rs:275:16:275:25 | source(...) | main.rs:278:22:278:22 | n | $@ | main.rs:275:16:275:25 | source(...) | source(...) | +| main.rs:282:29:282:29 | n | main.rs:275:16:275:25 | source(...) | main.rs:282:29:282:29 | n | $@ | main.rs:275:16:275:25 | source(...) | source(...) | +| main.rs:301:48:301:48 | n | main.rs:297:18:297:27 | source(...) | main.rs:301:48:301:48 | n | $@ | main.rs:297:18:297:27 | source(...) | source(...) | +| main.rs:305:81:305:81 | n | main.rs:297:18:297:27 | source(...) | main.rs:305:81:305:81 | n | $@ | main.rs:297:18:297:27 | source(...) | source(...) | +| main.rs:321:34:321:34 | n | main.rs:317:18:317:27 | source(...) | main.rs:321:34:321:34 | n | $@ | main.rs:317:18:317:27 | source(...) | source(...) | +| main.rs:325:53:325:53 | n | main.rs:317:18:317:27 | source(...) | main.rs:325:53:325:53 | n | $@ | main.rs:317:18:317:27 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 2732e00ecb1..8ddfcfbf130 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -225,6 +225,29 @@ fn option_unwrap() { sink(s1.unwrap()); // $ hasValueFlow=19 } +fn option_questionmark() -> Option { + let s1 = Some(source(20)); + let s2 = Some(2); + let i1 = s1?; + let i2 = s2?; + sink(i1); // $ MISSING: hasValueFlow=20 + sink(i2); + Some(0) +} + +fn result_questionmark() -> Result { + let s1: Result = Ok(source(20)); + let s2: Result = Ok(2); + let s3: Result = Err(source(77)); + let i1 = s1?; + let i2 = s2?; + sink(i1); // $ MISSING: hasValueFlow=20 + sink(i2); + let i3 = s3?; + sink(i3); // No flow since value is in `Err`. + Ok(0) +} + enum MyTupleEnum { A(i64), B(i64), @@ -327,6 +350,8 @@ fn main() { option_pattern_match_qualified(); option_pattern_match_unqualified(); option_unwrap(); + option_questionmark(); + let _ = result_questionmark(); custom_tuple_enum_pattern_match_qualified(); custom_tuple_enum_pattern_match_unqualified(); custom_record_enum_pattern_match_qualified(); From 70c60868a69d284aed4daf145636ddf1bbc2b825 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 29 Nov 2024 13:18:11 +0100 Subject: [PATCH 45/63] Rust: Model `?` as reading from `Option` and `Result` --- .../rust/dataflow/internal/DataFlowImpl.qll | 10 +- .../dataflow/local/DataFlowStep.expected | 383 +++++++++--------- .../dataflow/local/inline-flow.expected | 156 +++---- .../test/library-tests/dataflow/local/main.rs | 7 +- 4 files changed, 295 insertions(+), 261 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index a474d778e4e..e1f970ed6d0 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -884,6 +884,13 @@ module RustDataFlow implements InputSig { node1.asExpr() = access.getExpr() and node2.asExpr() = access ) + or + exists(TryExprCfgNode try | + node1.asExpr() = try.getExpr() and + node2.asExpr() = try and + c.(VariantPositionContent).getVariantCanonicalPath(0).getExtendedCanonicalPath() = + ["crate::option::Option::Some", "crate::result::Result::Ok"] + ) ) or FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(Node::FlowSummaryNode).getSummaryNode(), @@ -1050,7 +1057,8 @@ private module Cached { TSourceParameterNode(ParamBaseCfgNode p) or TPatNode(PatCfgNode p) or TExprPostUpdateNode(ExprCfgNode e) { - isArgumentForCall(e, _, _) or e = any(FieldExprCfgNode access).getExpr() + isArgumentForCall(e, _, _) or + e = [any(FieldExprCfgNode access).getExpr(), any(TryExprCfgNode try).getExpr()] } or TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) or TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index d566af4eca2..781a57dd553 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -207,176 +207,173 @@ localStep | main.rs:229:9:229:10 | [SSA] s1 | main.rs:231:14:231:15 | s1 | | main.rs:229:9:229:10 | s1 | main.rs:229:9:229:10 | [SSA] s1 | | main.rs:229:14:229:29 | Some(...) | main.rs:229:9:229:10 | s1 | -| main.rs:230:9:230:10 | [SSA] s2 | main.rs:232:14:232:15 | s2 | +| main.rs:230:9:230:10 | [SSA] s2 | main.rs:233:10:233:11 | s2 | | main.rs:230:9:230:10 | s2 | main.rs:230:9:230:10 | [SSA] s2 | | main.rs:230:14:230:20 | Some(...) | main.rs:230:9:230:10 | s2 | -| main.rs:231:9:231:10 | [SSA] i1 | main.rs:233:10:233:11 | i1 | +| main.rs:231:9:231:10 | [SSA] i1 | main.rs:232:10:232:11 | i1 | | main.rs:231:9:231:10 | i1 | main.rs:231:9:231:10 | [SSA] i1 | | main.rs:231:14:231:16 | TryExpr | main.rs:231:9:231:10 | i1 | -| main.rs:232:9:232:10 | [SSA] i2 | main.rs:234:10:234:11 | i2 | -| main.rs:232:9:232:10 | i2 | main.rs:232:9:232:10 | [SSA] i2 | -| main.rs:232:14:232:16 | TryExpr | main.rs:232:9:232:10 | i2 | -| main.rs:235:5:235:11 | Some(...) | main.rs:228:41:236:1 | { ... } | -| main.rs:239:9:239:10 | [SSA] s1 | main.rs:242:14:242:15 | s1 | -| main.rs:239:9:239:10 | s1 | main.rs:239:9:239:10 | [SSA] s1 | -| main.rs:239:32:239:45 | Ok(...) | main.rs:239:9:239:10 | s1 | -| main.rs:240:9:240:10 | [SSA] s2 | main.rs:243:14:243:15 | s2 | -| main.rs:240:9:240:10 | s2 | main.rs:240:9:240:10 | [SSA] s2 | -| main.rs:240:32:240:36 | Ok(...) | main.rs:240:9:240:10 | s2 | -| main.rs:241:9:241:10 | [SSA] s3 | main.rs:246:14:246:15 | s3 | -| main.rs:241:9:241:10 | s3 | main.rs:241:9:241:10 | [SSA] s3 | -| main.rs:241:32:241:46 | Err(...) | main.rs:241:9:241:10 | s3 | -| main.rs:242:9:242:10 | [SSA] i1 | main.rs:244:10:244:11 | i1 | -| main.rs:242:9:242:10 | i1 | main.rs:242:9:242:10 | [SSA] i1 | -| main.rs:242:14:242:16 | TryExpr | main.rs:242:9:242:10 | i1 | -| main.rs:243:9:243:10 | [SSA] i2 | main.rs:245:10:245:11 | i2 | -| main.rs:243:9:243:10 | i2 | main.rs:243:9:243:10 | [SSA] i2 | -| main.rs:243:14:243:16 | TryExpr | main.rs:243:9:243:10 | i2 | -| main.rs:246:9:246:10 | [SSA] i3 | main.rs:247:10:247:11 | i3 | -| main.rs:246:9:246:10 | i3 | main.rs:246:9:246:10 | [SSA] i3 | -| main.rs:246:14:246:16 | TryExpr | main.rs:246:9:246:10 | i3 | -| main.rs:248:5:248:9 | Ok(...) | main.rs:238:46:249:1 | { ... } | -| main.rs:257:9:257:10 | [SSA] s1 | main.rs:259:11:259:12 | s1 | -| main.rs:257:9:257:10 | s1 | main.rs:257:9:257:10 | [SSA] s1 | -| main.rs:257:14:257:39 | ...::A(...) | main.rs:257:9:257:10 | s1 | -| main.rs:258:9:258:10 | [SSA] s2 | main.rs:266:11:266:12 | s2 | -| main.rs:258:9:258:10 | s2 | main.rs:258:9:258:10 | [SSA] s2 | -| main.rs:258:14:258:30 | ...::B(...) | main.rs:258:9:258:10 | s2 | -| main.rs:259:11:259:12 | s1 | main.rs:260:9:260:25 | TupleStructPat | -| main.rs:259:11:259:12 | s1 | main.rs:261:9:261:25 | TupleStructPat | -| main.rs:259:11:259:12 | s1 | main.rs:263:11:263:12 | s1 | +| main.rs:234:5:234:11 | Some(...) | main.rs:228:41:235:1 | { ... } | +| main.rs:238:9:238:10 | [SSA] s1 | main.rs:241:14:241:15 | s1 | +| main.rs:238:9:238:10 | s1 | main.rs:238:9:238:10 | [SSA] s1 | +| main.rs:238:32:238:45 | Ok(...) | main.rs:238:9:238:10 | s1 | +| main.rs:239:9:239:10 | [SSA] s2 | main.rs:242:14:242:15 | s2 | +| main.rs:239:9:239:10 | s2 | main.rs:239:9:239:10 | [SSA] s2 | +| main.rs:239:32:239:36 | Ok(...) | main.rs:239:9:239:10 | s2 | +| main.rs:240:9:240:10 | [SSA] s3 | main.rs:245:14:245:15 | s3 | +| main.rs:240:9:240:10 | s3 | main.rs:240:9:240:10 | [SSA] s3 | +| main.rs:240:32:240:46 | Err(...) | main.rs:240:9:240:10 | s3 | +| main.rs:241:9:241:10 | [SSA] i1 | main.rs:243:10:243:11 | i1 | +| main.rs:241:9:241:10 | i1 | main.rs:241:9:241:10 | [SSA] i1 | +| main.rs:241:14:241:16 | TryExpr | main.rs:241:9:241:10 | i1 | +| main.rs:242:9:242:10 | [SSA] i2 | main.rs:244:10:244:11 | i2 | +| main.rs:242:9:242:10 | i2 | main.rs:242:9:242:10 | [SSA] i2 | +| main.rs:242:14:242:16 | TryExpr | main.rs:242:9:242:10 | i2 | +| main.rs:245:9:245:10 | [SSA] i3 | main.rs:246:10:246:11 | i3 | +| main.rs:245:9:245:10 | i3 | main.rs:245:9:245:10 | [SSA] i3 | +| main.rs:245:14:245:16 | TryExpr | main.rs:245:9:245:10 | i3 | +| main.rs:247:5:247:9 | Ok(...) | main.rs:237:46:248:1 | { ... } | +| main.rs:256:9:256:10 | [SSA] s1 | main.rs:258:11:258:12 | s1 | +| main.rs:256:9:256:10 | s1 | main.rs:256:9:256:10 | [SSA] s1 | +| main.rs:256:14:256:39 | ...::A(...) | main.rs:256:9:256:10 | s1 | +| main.rs:257:9:257:10 | [SSA] s2 | main.rs:265:11:265:12 | s2 | +| main.rs:257:9:257:10 | s2 | main.rs:257:9:257:10 | [SSA] s2 | +| main.rs:257:14:257:30 | ...::B(...) | main.rs:257:9:257:10 | s2 | +| main.rs:258:11:258:12 | s1 | main.rs:259:9:259:25 | TupleStructPat | +| main.rs:258:11:258:12 | s1 | main.rs:260:9:260:25 | TupleStructPat | +| main.rs:258:11:258:12 | s1 | main.rs:262:11:262:12 | s1 | +| main.rs:259:24:259:24 | [SSA] n | main.rs:259:35:259:35 | n | +| main.rs:259:24:259:24 | n | main.rs:259:24:259:24 | [SSA] n | +| main.rs:259:30:259:36 | sink(...) | main.rs:258:5:261:5 | match s1 { ... } | | main.rs:260:24:260:24 | [SSA] n | main.rs:260:35:260:35 | n | | main.rs:260:24:260:24 | n | main.rs:260:24:260:24 | [SSA] n | -| main.rs:260:30:260:36 | sink(...) | main.rs:259:5:262:5 | match s1 { ... } | -| main.rs:261:24:261:24 | [SSA] n | main.rs:261:35:261:35 | n | -| main.rs:261:24:261:24 | n | main.rs:261:24:261:24 | [SSA] n | -| main.rs:261:30:261:36 | sink(...) | main.rs:259:5:262:5 | match s1 { ... } | -| main.rs:263:11:263:12 | s1 | main.rs:264:9:264:45 | ... \| ... | -| main.rs:264:9:264:45 | ... \| ... | main.rs:264:9:264:25 | TupleStructPat | -| main.rs:264:9:264:45 | ... \| ... | main.rs:264:29:264:45 | TupleStructPat | -| main.rs:264:9:264:45 | [SSA] [match(true)] phi | main.rs:264:55:264:55 | n | -| main.rs:264:24:264:24 | [SSA] [input] [match(true)] phi | main.rs:264:9:264:45 | [SSA] [match(true)] phi | -| main.rs:264:24:264:24 | [SSA] n | main.rs:264:24:264:24 | [SSA] [input] [match(true)] phi | -| main.rs:264:24:264:24 | n | main.rs:264:24:264:24 | [SSA] n | -| main.rs:264:44:264:44 | [SSA] [input] [match(true)] phi | main.rs:264:9:264:45 | [SSA] [match(true)] phi | -| main.rs:264:44:264:44 | [SSA] n | main.rs:264:44:264:44 | [SSA] [input] [match(true)] phi | -| main.rs:264:44:264:44 | n | main.rs:264:44:264:44 | [SSA] n | -| main.rs:264:50:264:56 | sink(...) | main.rs:263:5:265:5 | match s1 { ... } | -| main.rs:266:5:269:5 | match s2 { ... } | main.rs:256:48:270:1 | { ... } | -| main.rs:266:11:266:12 | s2 | main.rs:267:9:267:25 | TupleStructPat | -| main.rs:266:11:266:12 | s2 | main.rs:268:9:268:25 | TupleStructPat | +| main.rs:260:30:260:36 | sink(...) | main.rs:258:5:261:5 | match s1 { ... } | +| main.rs:262:11:262:12 | s1 | main.rs:263:9:263:45 | ... \| ... | +| main.rs:263:9:263:45 | ... \| ... | main.rs:263:9:263:25 | TupleStructPat | +| main.rs:263:9:263:45 | ... \| ... | main.rs:263:29:263:45 | TupleStructPat | +| main.rs:263:9:263:45 | [SSA] [match(true)] phi | main.rs:263:55:263:55 | n | +| main.rs:263:24:263:24 | [SSA] [input] [match(true)] phi | main.rs:263:9:263:45 | [SSA] [match(true)] phi | +| main.rs:263:24:263:24 | [SSA] n | main.rs:263:24:263:24 | [SSA] [input] [match(true)] phi | +| main.rs:263:24:263:24 | n | main.rs:263:24:263:24 | [SSA] n | +| main.rs:263:44:263:44 | [SSA] [input] [match(true)] phi | main.rs:263:9:263:45 | [SSA] [match(true)] phi | +| main.rs:263:44:263:44 | [SSA] n | main.rs:263:44:263:44 | [SSA] [input] [match(true)] phi | +| main.rs:263:44:263:44 | n | main.rs:263:44:263:44 | [SSA] n | +| main.rs:263:50:263:56 | sink(...) | main.rs:262:5:264:5 | match s1 { ... } | +| main.rs:265:5:268:5 | match s2 { ... } | main.rs:255:48:269:1 | { ... } | +| main.rs:265:11:265:12 | s2 | main.rs:266:9:266:25 | TupleStructPat | +| main.rs:265:11:265:12 | s2 | main.rs:267:9:267:25 | TupleStructPat | +| main.rs:266:24:266:24 | [SSA] n | main.rs:266:35:266:35 | n | +| main.rs:266:24:266:24 | n | main.rs:266:24:266:24 | [SSA] n | +| main.rs:266:30:266:36 | sink(...) | main.rs:265:5:268:5 | match s2 { ... } | | main.rs:267:24:267:24 | [SSA] n | main.rs:267:35:267:35 | n | | main.rs:267:24:267:24 | n | main.rs:267:24:267:24 | [SSA] n | -| main.rs:267:30:267:36 | sink(...) | main.rs:266:5:269:5 | match s2 { ... } | -| main.rs:268:24:268:24 | [SSA] n | main.rs:268:35:268:35 | n | -| main.rs:268:24:268:24 | n | main.rs:268:24:268:24 | [SSA] n | -| main.rs:268:30:268:36 | sink(...) | main.rs:266:5:269:5 | match s2 { ... } | -| main.rs:275:9:275:10 | [SSA] s1 | main.rs:277:11:277:12 | s1 | -| main.rs:275:9:275:10 | s1 | main.rs:275:9:275:10 | [SSA] s1 | -| main.rs:275:14:275:26 | A(...) | main.rs:275:9:275:10 | s1 | -| main.rs:276:9:276:10 | [SSA] s2 | main.rs:284:11:284:12 | s2 | -| main.rs:276:9:276:10 | s2 | main.rs:276:9:276:10 | [SSA] s2 | -| main.rs:276:14:276:17 | B(...) | main.rs:276:9:276:10 | s2 | -| main.rs:277:11:277:12 | s1 | main.rs:278:9:278:12 | TupleStructPat | -| main.rs:277:11:277:12 | s1 | main.rs:279:9:279:12 | TupleStructPat | -| main.rs:277:11:277:12 | s1 | main.rs:281:11:281:12 | s1 | +| main.rs:267:30:267:36 | sink(...) | main.rs:265:5:268:5 | match s2 { ... } | +| main.rs:274:9:274:10 | [SSA] s1 | main.rs:276:11:276:12 | s1 | +| main.rs:274:9:274:10 | s1 | main.rs:274:9:274:10 | [SSA] s1 | +| main.rs:274:14:274:26 | A(...) | main.rs:274:9:274:10 | s1 | +| main.rs:275:9:275:10 | [SSA] s2 | main.rs:283:11:283:12 | s2 | +| main.rs:275:9:275:10 | s2 | main.rs:275:9:275:10 | [SSA] s2 | +| main.rs:275:14:275:17 | B(...) | main.rs:275:9:275:10 | s2 | +| main.rs:276:11:276:12 | s1 | main.rs:277:9:277:12 | TupleStructPat | +| main.rs:276:11:276:12 | s1 | main.rs:278:9:278:12 | TupleStructPat | +| main.rs:276:11:276:12 | s1 | main.rs:280:11:280:12 | s1 | +| main.rs:277:11:277:11 | [SSA] n | main.rs:277:22:277:22 | n | +| main.rs:277:11:277:11 | n | main.rs:277:11:277:11 | [SSA] n | +| main.rs:277:17:277:23 | sink(...) | main.rs:276:5:279:5 | match s1 { ... } | | main.rs:278:11:278:11 | [SSA] n | main.rs:278:22:278:22 | n | | main.rs:278:11:278:11 | n | main.rs:278:11:278:11 | [SSA] n | -| main.rs:278:17:278:23 | sink(...) | main.rs:277:5:280:5 | match s1 { ... } | -| main.rs:279:11:279:11 | [SSA] n | main.rs:279:22:279:22 | n | -| main.rs:279:11:279:11 | n | main.rs:279:11:279:11 | [SSA] n | -| main.rs:279:17:279:23 | sink(...) | main.rs:277:5:280:5 | match s1 { ... } | -| main.rs:281:11:281:12 | s1 | main.rs:282:9:282:19 | ... \| ... | -| main.rs:282:9:282:19 | ... \| ... | main.rs:282:9:282:12 | TupleStructPat | -| main.rs:282:9:282:19 | ... \| ... | main.rs:282:16:282:19 | TupleStructPat | -| main.rs:282:9:282:19 | [SSA] [match(true)] phi | main.rs:282:29:282:29 | n | -| main.rs:282:11:282:11 | [SSA] [input] [match(true)] phi | main.rs:282:9:282:19 | [SSA] [match(true)] phi | -| main.rs:282:11:282:11 | [SSA] n | main.rs:282:11:282:11 | [SSA] [input] [match(true)] phi | -| main.rs:282:11:282:11 | n | main.rs:282:11:282:11 | [SSA] n | -| main.rs:282:18:282:18 | [SSA] [input] [match(true)] phi | main.rs:282:9:282:19 | [SSA] [match(true)] phi | -| main.rs:282:18:282:18 | [SSA] n | main.rs:282:18:282:18 | [SSA] [input] [match(true)] phi | -| main.rs:282:18:282:18 | n | main.rs:282:18:282:18 | [SSA] n | -| main.rs:282:24:282:30 | sink(...) | main.rs:281:5:283:5 | match s1 { ... } | -| main.rs:284:5:287:5 | match s2 { ... } | main.rs:274:50:288:1 | { ... } | -| main.rs:284:11:284:12 | s2 | main.rs:285:9:285:12 | TupleStructPat | -| main.rs:284:11:284:12 | s2 | main.rs:286:9:286:12 | TupleStructPat | +| main.rs:278:17:278:23 | sink(...) | main.rs:276:5:279:5 | match s1 { ... } | +| main.rs:280:11:280:12 | s1 | main.rs:281:9:281:19 | ... \| ... | +| main.rs:281:9:281:19 | ... \| ... | main.rs:281:9:281:12 | TupleStructPat | +| main.rs:281:9:281:19 | ... \| ... | main.rs:281:16:281:19 | TupleStructPat | +| main.rs:281:9:281:19 | [SSA] [match(true)] phi | main.rs:281:29:281:29 | n | +| main.rs:281:11:281:11 | [SSA] [input] [match(true)] phi | main.rs:281:9:281:19 | [SSA] [match(true)] phi | +| main.rs:281:11:281:11 | [SSA] n | main.rs:281:11:281:11 | [SSA] [input] [match(true)] phi | +| main.rs:281:11:281:11 | n | main.rs:281:11:281:11 | [SSA] n | +| main.rs:281:18:281:18 | [SSA] [input] [match(true)] phi | main.rs:281:9:281:19 | [SSA] [match(true)] phi | +| main.rs:281:18:281:18 | [SSA] n | main.rs:281:18:281:18 | [SSA] [input] [match(true)] phi | +| main.rs:281:18:281:18 | n | main.rs:281:18:281:18 | [SSA] n | +| main.rs:281:24:281:30 | sink(...) | main.rs:280:5:282:5 | match s1 { ... } | +| main.rs:283:5:286:5 | match s2 { ... } | main.rs:273:50:287:1 | { ... } | +| main.rs:283:11:283:12 | s2 | main.rs:284:9:284:12 | TupleStructPat | +| main.rs:283:11:283:12 | s2 | main.rs:285:9:285:12 | TupleStructPat | +| main.rs:284:11:284:11 | [SSA] n | main.rs:284:22:284:22 | n | +| main.rs:284:11:284:11 | n | main.rs:284:11:284:11 | [SSA] n | +| main.rs:284:17:284:23 | sink(...) | main.rs:283:5:286:5 | match s2 { ... } | | main.rs:285:11:285:11 | [SSA] n | main.rs:285:22:285:22 | n | | main.rs:285:11:285:11 | n | main.rs:285:11:285:11 | [SSA] n | -| main.rs:285:17:285:23 | sink(...) | main.rs:284:5:287:5 | match s2 { ... } | -| main.rs:286:11:286:11 | [SSA] n | main.rs:286:22:286:22 | n | -| main.rs:286:11:286:11 | n | main.rs:286:11:286:11 | [SSA] n | -| main.rs:286:17:286:23 | sink(...) | main.rs:284:5:287:5 | match s2 { ... } | -| main.rs:296:9:296:10 | [SSA] s1 | main.rs:300:11:300:12 | s1 | -| main.rs:296:9:296:10 | s1 | main.rs:296:9:296:10 | [SSA] s1 | -| main.rs:296:14:298:5 | ...::C {...} | main.rs:296:9:296:10 | s1 | -| main.rs:299:9:299:10 | [SSA] s2 | main.rs:307:11:307:12 | s2 | -| main.rs:299:9:299:10 | s2 | main.rs:299:9:299:10 | [SSA] s2 | -| main.rs:299:14:299:43 | ...::D {...} | main.rs:299:9:299:10 | s2 | -| main.rs:300:11:300:12 | s1 | main.rs:301:9:301:38 | ...::C {...} | -| main.rs:300:11:300:12 | s1 | main.rs:302:9:302:38 | ...::D {...} | -| main.rs:300:11:300:12 | s1 | main.rs:304:11:304:12 | s1 | +| main.rs:285:17:285:23 | sink(...) | main.rs:283:5:286:5 | match s2 { ... } | +| main.rs:295:9:295:10 | [SSA] s1 | main.rs:299:11:299:12 | s1 | +| main.rs:295:9:295:10 | s1 | main.rs:295:9:295:10 | [SSA] s1 | +| main.rs:295:14:297:5 | ...::C {...} | main.rs:295:9:295:10 | s1 | +| main.rs:298:9:298:10 | [SSA] s2 | main.rs:306:11:306:12 | s2 | +| main.rs:298:9:298:10 | s2 | main.rs:298:9:298:10 | [SSA] s2 | +| main.rs:298:14:298:43 | ...::D {...} | main.rs:298:9:298:10 | s2 | +| main.rs:299:11:299:12 | s1 | main.rs:300:9:300:38 | ...::C {...} | +| main.rs:299:11:299:12 | s1 | main.rs:301:9:301:38 | ...::D {...} | +| main.rs:299:11:299:12 | s1 | main.rs:303:11:303:12 | s1 | +| main.rs:300:36:300:36 | [SSA] n | main.rs:300:48:300:48 | n | +| main.rs:300:36:300:36 | n | main.rs:300:36:300:36 | [SSA] n | +| main.rs:300:43:300:49 | sink(...) | main.rs:299:5:302:5 | match s1 { ... } | | main.rs:301:36:301:36 | [SSA] n | main.rs:301:48:301:48 | n | | main.rs:301:36:301:36 | n | main.rs:301:36:301:36 | [SSA] n | -| main.rs:301:43:301:49 | sink(...) | main.rs:300:5:303:5 | match s1 { ... } | -| main.rs:302:36:302:36 | [SSA] n | main.rs:302:48:302:48 | n | -| main.rs:302:36:302:36 | n | main.rs:302:36:302:36 | [SSA] n | -| main.rs:302:43:302:49 | sink(...) | main.rs:300:5:303:5 | match s1 { ... } | -| main.rs:304:11:304:12 | s1 | main.rs:305:9:305:71 | ... \| ... | -| main.rs:305:9:305:71 | ... \| ... | main.rs:305:9:305:38 | ...::C {...} | -| main.rs:305:9:305:71 | ... \| ... | main.rs:305:42:305:71 | ...::D {...} | -| main.rs:305:9:305:71 | [SSA] [match(true)] phi | main.rs:305:81:305:81 | n | -| main.rs:305:36:305:36 | [SSA] [input] [match(true)] phi | main.rs:305:9:305:71 | [SSA] [match(true)] phi | -| main.rs:305:36:305:36 | [SSA] n | main.rs:305:36:305:36 | [SSA] [input] [match(true)] phi | -| main.rs:305:36:305:36 | n | main.rs:305:36:305:36 | [SSA] n | -| main.rs:305:69:305:69 | [SSA] [input] [match(true)] phi | main.rs:305:9:305:71 | [SSA] [match(true)] phi | -| main.rs:305:69:305:69 | [SSA] n | main.rs:305:69:305:69 | [SSA] [input] [match(true)] phi | -| main.rs:305:69:305:69 | n | main.rs:305:69:305:69 | [SSA] n | -| main.rs:305:76:305:82 | sink(...) | main.rs:304:5:306:5 | match s1 { ... } | -| main.rs:307:5:310:5 | match s2 { ... } | main.rs:295:49:311:1 | { ... } | -| main.rs:307:11:307:12 | s2 | main.rs:308:9:308:38 | ...::C {...} | -| main.rs:307:11:307:12 | s2 | main.rs:309:9:309:38 | ...::D {...} | +| main.rs:301:43:301:49 | sink(...) | main.rs:299:5:302:5 | match s1 { ... } | +| main.rs:303:11:303:12 | s1 | main.rs:304:9:304:71 | ... \| ... | +| main.rs:304:9:304:71 | ... \| ... | main.rs:304:9:304:38 | ...::C {...} | +| main.rs:304:9:304:71 | ... \| ... | main.rs:304:42:304:71 | ...::D {...} | +| main.rs:304:9:304:71 | [SSA] [match(true)] phi | main.rs:304:81:304:81 | n | +| main.rs:304:36:304:36 | [SSA] [input] [match(true)] phi | main.rs:304:9:304:71 | [SSA] [match(true)] phi | +| main.rs:304:36:304:36 | [SSA] n | main.rs:304:36:304:36 | [SSA] [input] [match(true)] phi | +| main.rs:304:36:304:36 | n | main.rs:304:36:304:36 | [SSA] n | +| main.rs:304:69:304:69 | [SSA] [input] [match(true)] phi | main.rs:304:9:304:71 | [SSA] [match(true)] phi | +| main.rs:304:69:304:69 | [SSA] n | main.rs:304:69:304:69 | [SSA] [input] [match(true)] phi | +| main.rs:304:69:304:69 | n | main.rs:304:69:304:69 | [SSA] n | +| main.rs:304:76:304:82 | sink(...) | main.rs:303:5:305:5 | match s1 { ... } | +| main.rs:306:5:309:5 | match s2 { ... } | main.rs:294:49:310:1 | { ... } | +| main.rs:306:11:306:12 | s2 | main.rs:307:9:307:38 | ...::C {...} | +| main.rs:306:11:306:12 | s2 | main.rs:308:9:308:38 | ...::D {...} | +| main.rs:307:36:307:36 | [SSA] n | main.rs:307:48:307:48 | n | +| main.rs:307:36:307:36 | n | main.rs:307:36:307:36 | [SSA] n | +| main.rs:307:43:307:49 | sink(...) | main.rs:306:5:309:5 | match s2 { ... } | | main.rs:308:36:308:36 | [SSA] n | main.rs:308:48:308:48 | n | | main.rs:308:36:308:36 | n | main.rs:308:36:308:36 | [SSA] n | -| main.rs:308:43:308:49 | sink(...) | main.rs:307:5:310:5 | match s2 { ... } | -| main.rs:309:36:309:36 | [SSA] n | main.rs:309:48:309:48 | n | -| main.rs:309:36:309:36 | n | main.rs:309:36:309:36 | [SSA] n | -| main.rs:309:43:309:49 | sink(...) | main.rs:307:5:310:5 | match s2 { ... } | -| main.rs:316:9:316:10 | [SSA] s1 | main.rs:320:11:320:12 | s1 | -| main.rs:316:9:316:10 | s1 | main.rs:316:9:316:10 | [SSA] s1 | -| main.rs:316:14:318:5 | C {...} | main.rs:316:9:316:10 | s1 | -| main.rs:319:9:319:10 | [SSA] s2 | main.rs:327:11:327:12 | s2 | -| main.rs:319:9:319:10 | s2 | main.rs:319:9:319:10 | [SSA] s2 | -| main.rs:319:14:319:29 | D {...} | main.rs:319:9:319:10 | s2 | -| main.rs:320:11:320:12 | s1 | main.rs:321:9:321:24 | C {...} | -| main.rs:320:11:320:12 | s1 | main.rs:322:9:322:24 | D {...} | -| main.rs:320:11:320:12 | s1 | main.rs:324:11:324:12 | s1 | +| main.rs:308:43:308:49 | sink(...) | main.rs:306:5:309:5 | match s2 { ... } | +| main.rs:315:9:315:10 | [SSA] s1 | main.rs:319:11:319:12 | s1 | +| main.rs:315:9:315:10 | s1 | main.rs:315:9:315:10 | [SSA] s1 | +| main.rs:315:14:317:5 | C {...} | main.rs:315:9:315:10 | s1 | +| main.rs:318:9:318:10 | [SSA] s2 | main.rs:326:11:326:12 | s2 | +| main.rs:318:9:318:10 | s2 | main.rs:318:9:318:10 | [SSA] s2 | +| main.rs:318:14:318:29 | D {...} | main.rs:318:9:318:10 | s2 | +| main.rs:319:11:319:12 | s1 | main.rs:320:9:320:24 | C {...} | +| main.rs:319:11:319:12 | s1 | main.rs:321:9:321:24 | D {...} | +| main.rs:319:11:319:12 | s1 | main.rs:323:11:323:12 | s1 | +| main.rs:320:22:320:22 | [SSA] n | main.rs:320:34:320:34 | n | +| main.rs:320:22:320:22 | n | main.rs:320:22:320:22 | [SSA] n | +| main.rs:320:29:320:35 | sink(...) | main.rs:319:5:322:5 | match s1 { ... } | | main.rs:321:22:321:22 | [SSA] n | main.rs:321:34:321:34 | n | | main.rs:321:22:321:22 | n | main.rs:321:22:321:22 | [SSA] n | -| main.rs:321:29:321:35 | sink(...) | main.rs:320:5:323:5 | match s1 { ... } | -| main.rs:322:22:322:22 | [SSA] n | main.rs:322:34:322:34 | n | -| main.rs:322:22:322:22 | n | main.rs:322:22:322:22 | [SSA] n | -| main.rs:322:29:322:35 | sink(...) | main.rs:320:5:323:5 | match s1 { ... } | -| main.rs:324:11:324:12 | s1 | main.rs:325:9:325:43 | ... \| ... | -| main.rs:325:9:325:43 | ... \| ... | main.rs:325:9:325:24 | C {...} | -| main.rs:325:9:325:43 | ... \| ... | main.rs:325:28:325:43 | D {...} | -| main.rs:325:9:325:43 | [SSA] [match(true)] phi | main.rs:325:53:325:53 | n | -| main.rs:325:22:325:22 | [SSA] [input] [match(true)] phi | main.rs:325:9:325:43 | [SSA] [match(true)] phi | -| main.rs:325:22:325:22 | [SSA] n | main.rs:325:22:325:22 | [SSA] [input] [match(true)] phi | -| main.rs:325:22:325:22 | n | main.rs:325:22:325:22 | [SSA] n | -| main.rs:325:41:325:41 | [SSA] [input] [match(true)] phi | main.rs:325:9:325:43 | [SSA] [match(true)] phi | -| main.rs:325:41:325:41 | [SSA] n | main.rs:325:41:325:41 | [SSA] [input] [match(true)] phi | -| main.rs:325:41:325:41 | n | main.rs:325:41:325:41 | [SSA] n | -| main.rs:325:48:325:54 | sink(...) | main.rs:324:5:326:5 | match s1 { ... } | -| main.rs:327:5:330:5 | match s2 { ... } | main.rs:315:51:331:1 | { ... } | -| main.rs:327:11:327:12 | s2 | main.rs:328:9:328:24 | C {...} | -| main.rs:327:11:327:12 | s2 | main.rs:329:9:329:24 | D {...} | +| main.rs:321:29:321:35 | sink(...) | main.rs:319:5:322:5 | match s1 { ... } | +| main.rs:323:11:323:12 | s1 | main.rs:324:9:324:43 | ... \| ... | +| main.rs:324:9:324:43 | ... \| ... | main.rs:324:9:324:24 | C {...} | +| main.rs:324:9:324:43 | ... \| ... | main.rs:324:28:324:43 | D {...} | +| main.rs:324:9:324:43 | [SSA] [match(true)] phi | main.rs:324:53:324:53 | n | +| main.rs:324:22:324:22 | [SSA] [input] [match(true)] phi | main.rs:324:9:324:43 | [SSA] [match(true)] phi | +| main.rs:324:22:324:22 | [SSA] n | main.rs:324:22:324:22 | [SSA] [input] [match(true)] phi | +| main.rs:324:22:324:22 | n | main.rs:324:22:324:22 | [SSA] n | +| main.rs:324:41:324:41 | [SSA] [input] [match(true)] phi | main.rs:324:9:324:43 | [SSA] [match(true)] phi | +| main.rs:324:41:324:41 | [SSA] n | main.rs:324:41:324:41 | [SSA] [input] [match(true)] phi | +| main.rs:324:41:324:41 | n | main.rs:324:41:324:41 | [SSA] n | +| main.rs:324:48:324:54 | sink(...) | main.rs:323:5:325:5 | match s1 { ... } | +| main.rs:326:5:329:5 | match s2 { ... } | main.rs:314:51:330:1 | { ... } | +| main.rs:326:11:326:12 | s2 | main.rs:327:9:327:24 | C {...} | +| main.rs:326:11:326:12 | s2 | main.rs:328:9:328:24 | D {...} | +| main.rs:327:22:327:22 | [SSA] n | main.rs:327:34:327:34 | n | +| main.rs:327:22:327:22 | n | main.rs:327:22:327:22 | [SSA] n | +| main.rs:327:29:327:35 | sink(...) | main.rs:326:5:329:5 | match s2 { ... } | | main.rs:328:22:328:22 | [SSA] n | main.rs:328:34:328:34 | n | | main.rs:328:22:328:22 | n | main.rs:328:22:328:22 | [SSA] n | -| main.rs:328:29:328:35 | sink(...) | main.rs:327:5:330:5 | match s2 { ... } | -| main.rs:329:22:329:22 | [SSA] n | main.rs:329:34:329:34 | n | -| main.rs:329:22:329:22 | n | main.rs:329:22:329:22 | [SSA] n | -| main.rs:329:29:329:35 | sink(...) | main.rs:327:5:330:5 | match s2 { ... } | -| main.rs:354:13:354:33 | result_questionmark(...) | main.rs:354:9:354:9 | _ | +| main.rs:328:29:328:35 | sink(...) | main.rs:326:5:329:5 | match s2 { ... } | +| main.rs:353:13:353:33 | result_questionmark(...) | main.rs:353:9:353:9 | _ | storeStep | main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr | | main.rs:94:25:94:25 | 2 | tuple.1 | main.rs:94:13:94:26 | TupleExpr | @@ -412,20 +409,20 @@ storeStep | main.rs:224:19:224:28 | source(...) | Some | main.rs:224:14:224:29 | Some(...) | | main.rs:229:19:229:28 | source(...) | Some | main.rs:229:14:229:29 | Some(...) | | main.rs:230:19:230:19 | 2 | Some | main.rs:230:14:230:20 | Some(...) | -| main.rs:235:10:235:10 | 0 | Some | main.rs:235:5:235:11 | Some(...) | -| main.rs:239:35:239:44 | source(...) | Ok | main.rs:239:32:239:45 | Ok(...) | -| main.rs:240:35:240:35 | 2 | Ok | main.rs:240:32:240:36 | Ok(...) | -| main.rs:241:36:241:45 | source(...) | Err | main.rs:241:32:241:46 | Err(...) | -| main.rs:248:8:248:8 | 0 | Ok | main.rs:248:5:248:9 | Ok(...) | -| main.rs:257:29:257:38 | source(...) | A | main.rs:257:14:257:39 | ...::A(...) | -| main.rs:258:29:258:29 | 2 | B | main.rs:258:14:258:30 | ...::B(...) | -| main.rs:275:16:275:25 | source(...) | A | main.rs:275:14:275:26 | A(...) | -| main.rs:276:16:276:16 | 2 | B | main.rs:276:14:276:17 | B(...) | -| main.rs:297:18:297:27 | source(...) | C | main.rs:296:14:298:5 | ...::C {...} | -| main.rs:299:41:299:41 | 2 | D | main.rs:299:14:299:43 | ...::D {...} | -| main.rs:317:18:317:27 | source(...) | C | main.rs:316:14:318:5 | C {...} | -| main.rs:319:27:319:27 | 2 | D | main.rs:319:14:319:29 | D {...} | -| main.rs:337:27:337:27 | 0 | Some | main.rs:337:22:337:28 | Some(...) | +| main.rs:234:10:234:10 | 0 | Some | main.rs:234:5:234:11 | Some(...) | +| main.rs:238:35:238:44 | source(...) | Ok | main.rs:238:32:238:45 | Ok(...) | +| main.rs:239:35:239:35 | 2 | Ok | main.rs:239:32:239:36 | Ok(...) | +| main.rs:240:36:240:45 | source(...) | Err | main.rs:240:32:240:46 | Err(...) | +| main.rs:247:8:247:8 | 0 | Ok | main.rs:247:5:247:9 | Ok(...) | +| main.rs:256:29:256:38 | source(...) | A | main.rs:256:14:256:39 | ...::A(...) | +| main.rs:257:29:257:29 | 2 | B | main.rs:257:14:257:30 | ...::B(...) | +| main.rs:274:16:274:25 | source(...) | A | main.rs:274:14:274:26 | A(...) | +| main.rs:275:16:275:16 | 2 | B | main.rs:275:14:275:17 | B(...) | +| main.rs:296:18:296:27 | source(...) | C | main.rs:295:14:297:5 | ...::C {...} | +| main.rs:298:41:298:41 | 2 | D | main.rs:298:14:298:43 | ...::D {...} | +| main.rs:316:18:316:27 | source(...) | C | main.rs:315:14:317:5 | C {...} | +| main.rs:318:27:318:27 | 2 | D | main.rs:318:14:318:29 | D {...} | +| main.rs:336:27:336:27 | 0 | Some | main.rs:336:22:336:28 | Some(...) | readStep | file://:0:0:0:0 | [summary param] self in lang:core::_::::unwrap | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::::unwrap | | main.rs:33:9:33:15 | TupleStructPat | Some | main.rs:33:14:33:14 | _ | @@ -449,27 +446,37 @@ readStep | main.rs:205:9:205:23 | TupleStructPat | Some | main.rs:205:22:205:22 | n | | main.rs:214:9:214:15 | TupleStructPat | Some | main.rs:214:14:214:14 | n | | main.rs:218:9:218:15 | TupleStructPat | Some | main.rs:218:14:218:14 | n | -| main.rs:260:9:260:25 | TupleStructPat | A | main.rs:260:24:260:24 | n | -| main.rs:261:9:261:25 | TupleStructPat | B | main.rs:261:24:261:24 | n | -| main.rs:264:9:264:25 | TupleStructPat | A | main.rs:264:24:264:24 | n | -| main.rs:264:29:264:45 | TupleStructPat | B | main.rs:264:44:264:44 | n | -| main.rs:267:9:267:25 | TupleStructPat | A | main.rs:267:24:267:24 | n | -| main.rs:268:9:268:25 | TupleStructPat | B | main.rs:268:24:268:24 | n | -| main.rs:278:9:278:12 | TupleStructPat | A | main.rs:278:11:278:11 | n | -| main.rs:279:9:279:12 | TupleStructPat | B | main.rs:279:11:279:11 | n | -| main.rs:282:9:282:12 | TupleStructPat | A | main.rs:282:11:282:11 | n | -| main.rs:282:16:282:19 | TupleStructPat | B | main.rs:282:18:282:18 | n | -| main.rs:285:9:285:12 | TupleStructPat | A | main.rs:285:11:285:11 | n | -| main.rs:286:9:286:12 | TupleStructPat | B | main.rs:286:11:286:11 | n | -| main.rs:301:9:301:38 | ...::C {...} | C | main.rs:301:36:301:36 | n | -| main.rs:302:9:302:38 | ...::D {...} | D | main.rs:302:36:302:36 | n | -| main.rs:305:9:305:38 | ...::C {...} | C | main.rs:305:36:305:36 | n | -| main.rs:305:42:305:71 | ...::D {...} | D | main.rs:305:69:305:69 | n | -| main.rs:308:9:308:38 | ...::C {...} | C | main.rs:308:36:308:36 | n | -| main.rs:309:9:309:38 | ...::D {...} | D | main.rs:309:36:309:36 | n | -| main.rs:321:9:321:24 | C {...} | C | main.rs:321:22:321:22 | n | -| main.rs:322:9:322:24 | D {...} | D | main.rs:322:22:322:22 | n | -| main.rs:325:9:325:24 | C {...} | C | main.rs:325:22:325:22 | n | -| main.rs:325:28:325:43 | D {...} | D | main.rs:325:41:325:41 | n | -| main.rs:328:9:328:24 | C {...} | C | main.rs:328:22:328:22 | n | -| main.rs:329:9:329:24 | D {...} | D | main.rs:329:22:329:22 | n | +| main.rs:231:14:231:15 | s1 | Ok | main.rs:231:14:231:16 | TryExpr | +| main.rs:231:14:231:15 | s1 | Some | main.rs:231:14:231:16 | TryExpr | +| main.rs:233:10:233:11 | s2 | Ok | main.rs:233:10:233:12 | TryExpr | +| main.rs:233:10:233:11 | s2 | Some | main.rs:233:10:233:12 | TryExpr | +| main.rs:241:14:241:15 | s1 | Ok | main.rs:241:14:241:16 | TryExpr | +| main.rs:241:14:241:15 | s1 | Some | main.rs:241:14:241:16 | TryExpr | +| main.rs:242:14:242:15 | s2 | Ok | main.rs:242:14:242:16 | TryExpr | +| main.rs:242:14:242:15 | s2 | Some | main.rs:242:14:242:16 | TryExpr | +| main.rs:245:14:245:15 | s3 | Ok | main.rs:245:14:245:16 | TryExpr | +| main.rs:245:14:245:15 | s3 | Some | main.rs:245:14:245:16 | TryExpr | +| main.rs:259:9:259:25 | TupleStructPat | A | main.rs:259:24:259:24 | n | +| main.rs:260:9:260:25 | TupleStructPat | B | main.rs:260:24:260:24 | n | +| main.rs:263:9:263:25 | TupleStructPat | A | main.rs:263:24:263:24 | n | +| main.rs:263:29:263:45 | TupleStructPat | B | main.rs:263:44:263:44 | n | +| main.rs:266:9:266:25 | TupleStructPat | A | main.rs:266:24:266:24 | n | +| main.rs:267:9:267:25 | TupleStructPat | B | main.rs:267:24:267:24 | n | +| main.rs:277:9:277:12 | TupleStructPat | A | main.rs:277:11:277:11 | n | +| main.rs:278:9:278:12 | TupleStructPat | B | main.rs:278:11:278:11 | n | +| main.rs:281:9:281:12 | TupleStructPat | A | main.rs:281:11:281:11 | n | +| main.rs:281:16:281:19 | TupleStructPat | B | main.rs:281:18:281:18 | n | +| main.rs:284:9:284:12 | TupleStructPat | A | main.rs:284:11:284:11 | n | +| main.rs:285:9:285:12 | TupleStructPat | B | main.rs:285:11:285:11 | n | +| main.rs:300:9:300:38 | ...::C {...} | C | main.rs:300:36:300:36 | n | +| main.rs:301:9:301:38 | ...::D {...} | D | main.rs:301:36:301:36 | n | +| main.rs:304:9:304:38 | ...::C {...} | C | main.rs:304:36:304:36 | n | +| main.rs:304:42:304:71 | ...::D {...} | D | main.rs:304:69:304:69 | n | +| main.rs:307:9:307:38 | ...::C {...} | C | main.rs:307:36:307:36 | n | +| main.rs:308:9:308:38 | ...::D {...} | D | main.rs:308:36:308:36 | n | +| main.rs:320:9:320:24 | C {...} | C | main.rs:320:22:320:22 | n | +| main.rs:321:9:321:24 | D {...} | D | main.rs:321:22:321:22 | n | +| main.rs:324:9:324:24 | C {...} | C | main.rs:324:22:324:22 | n | +| main.rs:324:28:324:43 | D {...} | D | main.rs:324:41:324:41 | n | +| main.rs:327:9:327:24 | C {...} | C | main.rs:327:22:327:22 | n | +| main.rs:328:9:328:24 | D {...} | D | main.rs:328:22:328:22 | n | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 75b0273f8e6..ceff7cf93be 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -36,34 +36,42 @@ edges | main.rs:224:14:224:29 | Some(...) [Some] | main.rs:225:10:225:11 | s1 [Some] | provenance | | | main.rs:224:19:224:28 | source(...) | main.rs:224:14:224:29 | Some(...) [Some] | provenance | | | main.rs:225:10:225:11 | s1 [Some] | main.rs:225:10:225:20 | ... .unwrap(...) | provenance | | -| main.rs:257:14:257:39 | ...::A(...) [A] | main.rs:260:9:260:25 | TupleStructPat [A] | provenance | | -| main.rs:257:14:257:39 | ...::A(...) [A] | main.rs:264:9:264:25 | TupleStructPat [A] | provenance | | -| main.rs:257:29:257:38 | source(...) | main.rs:257:14:257:39 | ...::A(...) [A] | provenance | | -| main.rs:260:9:260:25 | TupleStructPat [A] | main.rs:260:24:260:24 | n | provenance | | -| main.rs:260:24:260:24 | n | main.rs:260:35:260:35 | n | provenance | | -| main.rs:264:9:264:25 | TupleStructPat [A] | main.rs:264:24:264:24 | n | provenance | | -| main.rs:264:24:264:24 | n | main.rs:264:55:264:55 | n | provenance | | -| main.rs:275:14:275:26 | A(...) [A] | main.rs:278:9:278:12 | TupleStructPat [A] | provenance | | -| main.rs:275:14:275:26 | A(...) [A] | main.rs:282:9:282:12 | TupleStructPat [A] | provenance | | -| main.rs:275:16:275:25 | source(...) | main.rs:275:14:275:26 | A(...) [A] | provenance | | -| main.rs:278:9:278:12 | TupleStructPat [A] | main.rs:278:11:278:11 | n | provenance | | -| main.rs:278:11:278:11 | n | main.rs:278:22:278:22 | n | provenance | | -| main.rs:282:9:282:12 | TupleStructPat [A] | main.rs:282:11:282:11 | n | provenance | | -| main.rs:282:11:282:11 | n | main.rs:282:29:282:29 | n | provenance | | -| main.rs:296:14:298:5 | ...::C {...} [C] | main.rs:301:9:301:38 | ...::C {...} [C] | provenance | | -| main.rs:296:14:298:5 | ...::C {...} [C] | main.rs:305:9:305:38 | ...::C {...} [C] | provenance | | -| main.rs:297:18:297:27 | source(...) | main.rs:296:14:298:5 | ...::C {...} [C] | provenance | | -| main.rs:301:9:301:38 | ...::C {...} [C] | main.rs:301:36:301:36 | n | provenance | | -| main.rs:301:36:301:36 | n | main.rs:301:48:301:48 | n | provenance | | -| main.rs:305:9:305:38 | ...::C {...} [C] | main.rs:305:36:305:36 | n | provenance | | -| main.rs:305:36:305:36 | n | main.rs:305:81:305:81 | n | provenance | | -| main.rs:316:14:318:5 | C {...} [C] | main.rs:321:9:321:24 | C {...} [C] | provenance | | -| main.rs:316:14:318:5 | C {...} [C] | main.rs:325:9:325:24 | C {...} [C] | provenance | | -| main.rs:317:18:317:27 | source(...) | main.rs:316:14:318:5 | C {...} [C] | provenance | | -| main.rs:321:9:321:24 | C {...} [C] | main.rs:321:22:321:22 | n | provenance | | -| main.rs:321:22:321:22 | n | main.rs:321:34:321:34 | n | provenance | | -| main.rs:325:9:325:24 | C {...} [C] | main.rs:325:22:325:22 | n | provenance | | -| main.rs:325:22:325:22 | n | main.rs:325:53:325:53 | n | provenance | | +| main.rs:229:14:229:29 | Some(...) [Some] | main.rs:231:14:231:15 | s1 [Some] | provenance | | +| main.rs:229:19:229:28 | source(...) | main.rs:229:14:229:29 | Some(...) [Some] | provenance | | +| main.rs:231:14:231:15 | s1 [Some] | main.rs:231:14:231:16 | TryExpr | provenance | | +| main.rs:231:14:231:16 | TryExpr | main.rs:232:10:232:11 | i1 | provenance | | +| main.rs:238:32:238:45 | Ok(...) [Ok] | main.rs:241:14:241:15 | s1 [Ok] | provenance | | +| main.rs:238:35:238:44 | source(...) | main.rs:238:32:238:45 | Ok(...) [Ok] | provenance | | +| main.rs:241:14:241:15 | s1 [Ok] | main.rs:241:14:241:16 | TryExpr | provenance | | +| main.rs:241:14:241:16 | TryExpr | main.rs:243:10:243:11 | i1 | provenance | | +| main.rs:256:14:256:39 | ...::A(...) [A] | main.rs:259:9:259:25 | TupleStructPat [A] | provenance | | +| main.rs:256:14:256:39 | ...::A(...) [A] | main.rs:263:9:263:25 | TupleStructPat [A] | provenance | | +| main.rs:256:29:256:38 | source(...) | main.rs:256:14:256:39 | ...::A(...) [A] | provenance | | +| main.rs:259:9:259:25 | TupleStructPat [A] | main.rs:259:24:259:24 | n | provenance | | +| main.rs:259:24:259:24 | n | main.rs:259:35:259:35 | n | provenance | | +| main.rs:263:9:263:25 | TupleStructPat [A] | main.rs:263:24:263:24 | n | provenance | | +| main.rs:263:24:263:24 | n | main.rs:263:55:263:55 | n | provenance | | +| main.rs:274:14:274:26 | A(...) [A] | main.rs:277:9:277:12 | TupleStructPat [A] | provenance | | +| main.rs:274:14:274:26 | A(...) [A] | main.rs:281:9:281:12 | TupleStructPat [A] | provenance | | +| main.rs:274:16:274:25 | source(...) | main.rs:274:14:274:26 | A(...) [A] | provenance | | +| main.rs:277:9:277:12 | TupleStructPat [A] | main.rs:277:11:277:11 | n | provenance | | +| main.rs:277:11:277:11 | n | main.rs:277:22:277:22 | n | provenance | | +| main.rs:281:9:281:12 | TupleStructPat [A] | main.rs:281:11:281:11 | n | provenance | | +| main.rs:281:11:281:11 | n | main.rs:281:29:281:29 | n | provenance | | +| main.rs:295:14:297:5 | ...::C {...} [C] | main.rs:300:9:300:38 | ...::C {...} [C] | provenance | | +| main.rs:295:14:297:5 | ...::C {...} [C] | main.rs:304:9:304:38 | ...::C {...} [C] | provenance | | +| main.rs:296:18:296:27 | source(...) | main.rs:295:14:297:5 | ...::C {...} [C] | provenance | | +| main.rs:300:9:300:38 | ...::C {...} [C] | main.rs:300:36:300:36 | n | provenance | | +| main.rs:300:36:300:36 | n | main.rs:300:48:300:48 | n | provenance | | +| main.rs:304:9:304:38 | ...::C {...} [C] | main.rs:304:36:304:36 | n | provenance | | +| main.rs:304:36:304:36 | n | main.rs:304:81:304:81 | n | provenance | | +| main.rs:315:14:317:5 | C {...} [C] | main.rs:320:9:320:24 | C {...} [C] | provenance | | +| main.rs:315:14:317:5 | C {...} [C] | main.rs:324:9:324:24 | C {...} [C] | provenance | | +| main.rs:316:18:316:27 | source(...) | main.rs:315:14:317:5 | C {...} [C] | provenance | | +| main.rs:320:9:320:24 | C {...} [C] | main.rs:320:22:320:22 | n | provenance | | +| main.rs:320:22:320:22 | n | main.rs:320:34:320:34 | n | provenance | | +| main.rs:324:9:324:24 | C {...} [C] | main.rs:324:22:324:22 | n | provenance | | +| main.rs:324:22:324:22 | n | main.rs:324:53:324:53 | n | provenance | | nodes | main.rs:15:10:15:18 | source(...) | semmle.label | source(...) | | main.rs:19:13:19:21 | source(...) | semmle.label | source(...) | @@ -115,38 +123,48 @@ nodes | main.rs:224:19:224:28 | source(...) | semmle.label | source(...) | | main.rs:225:10:225:11 | s1 [Some] | semmle.label | s1 [Some] | | main.rs:225:10:225:20 | ... .unwrap(...) | semmle.label | ... .unwrap(...) | -| main.rs:257:14:257:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | -| main.rs:257:29:257:38 | source(...) | semmle.label | source(...) | -| main.rs:260:9:260:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:260:24:260:24 | n | semmle.label | n | -| main.rs:260:35:260:35 | n | semmle.label | n | -| main.rs:264:9:264:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:264:24:264:24 | n | semmle.label | n | -| main.rs:264:55:264:55 | n | semmle.label | n | -| main.rs:275:14:275:26 | A(...) [A] | semmle.label | A(...) [A] | -| main.rs:275:16:275:25 | source(...) | semmle.label | source(...) | -| main.rs:278:9:278:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:278:11:278:11 | n | semmle.label | n | -| main.rs:278:22:278:22 | n | semmle.label | n | -| main.rs:282:9:282:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | -| main.rs:282:11:282:11 | n | semmle.label | n | -| main.rs:282:29:282:29 | n | semmle.label | n | -| main.rs:296:14:298:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:297:18:297:27 | source(...) | semmle.label | source(...) | -| main.rs:301:9:301:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:301:36:301:36 | n | semmle.label | n | -| main.rs:301:48:301:48 | n | semmle.label | n | -| main.rs:305:9:305:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:305:36:305:36 | n | semmle.label | n | -| main.rs:305:81:305:81 | n | semmle.label | n | -| main.rs:316:14:318:5 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:317:18:317:27 | source(...) | semmle.label | source(...) | -| main.rs:321:9:321:24 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:321:22:321:22 | n | semmle.label | n | -| main.rs:321:34:321:34 | n | semmle.label | n | -| main.rs:325:9:325:24 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:325:22:325:22 | n | semmle.label | n | -| main.rs:325:53:325:53 | n | semmle.label | n | +| main.rs:229:14:229:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:229:19:229:28 | source(...) | semmle.label | source(...) | +| main.rs:231:14:231:15 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:231:14:231:16 | TryExpr | semmle.label | TryExpr | +| main.rs:232:10:232:11 | i1 | semmle.label | i1 | +| main.rs:238:32:238:45 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] | +| main.rs:238:35:238:44 | source(...) | semmle.label | source(...) | +| main.rs:241:14:241:15 | s1 [Ok] | semmle.label | s1 [Ok] | +| main.rs:241:14:241:16 | TryExpr | semmle.label | TryExpr | +| main.rs:243:10:243:11 | i1 | semmle.label | i1 | +| main.rs:256:14:256:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | +| main.rs:256:29:256:38 | source(...) | semmle.label | source(...) | +| main.rs:259:9:259:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:259:24:259:24 | n | semmle.label | n | +| main.rs:259:35:259:35 | n | semmle.label | n | +| main.rs:263:9:263:25 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:263:24:263:24 | n | semmle.label | n | +| main.rs:263:55:263:55 | n | semmle.label | n | +| main.rs:274:14:274:26 | A(...) [A] | semmle.label | A(...) [A] | +| main.rs:274:16:274:25 | source(...) | semmle.label | source(...) | +| main.rs:277:9:277:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:277:11:277:11 | n | semmle.label | n | +| main.rs:277:22:277:22 | n | semmle.label | n | +| main.rs:281:9:281:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] | +| main.rs:281:11:281:11 | n | semmle.label | n | +| main.rs:281:29:281:29 | n | semmle.label | n | +| main.rs:295:14:297:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:296:18:296:27 | source(...) | semmle.label | source(...) | +| main.rs:300:9:300:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:300:36:300:36 | n | semmle.label | n | +| main.rs:300:48:300:48 | n | semmle.label | n | +| main.rs:304:9:304:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:304:36:304:36 | n | semmle.label | n | +| main.rs:304:81:304:81 | n | semmle.label | n | +| main.rs:315:14:317:5 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:316:18:316:27 | source(...) | semmle.label | source(...) | +| main.rs:320:9:320:24 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:320:22:320:22 | n | semmle.label | n | +| main.rs:320:34:320:34 | n | semmle.label | n | +| main.rs:324:9:324:24 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:324:22:324:22 | n | semmle.label | n | +| main.rs:324:53:324:53 | n | semmle.label | n | subpaths testFailures #select @@ -164,11 +182,13 @@ testFailures | main.rs:201:33:201:33 | n | main.rs:198:27:198:36 | source(...) | main.rs:201:33:201:33 | n | $@ | main.rs:198:27:198:36 | source(...) | source(...) | | main.rs:214:25:214:25 | n | main.rs:211:19:211:28 | source(...) | main.rs:214:25:214:25 | n | $@ | main.rs:211:19:211:28 | source(...) | source(...) | | main.rs:225:10:225:20 | ... .unwrap(...) | main.rs:224:19:224:28 | source(...) | main.rs:225:10:225:20 | ... .unwrap(...) | $@ | main.rs:224:19:224:28 | source(...) | source(...) | -| main.rs:260:35:260:35 | n | main.rs:257:29:257:38 | source(...) | main.rs:260:35:260:35 | n | $@ | main.rs:257:29:257:38 | source(...) | source(...) | -| main.rs:264:55:264:55 | n | main.rs:257:29:257:38 | source(...) | main.rs:264:55:264:55 | n | $@ | main.rs:257:29:257:38 | source(...) | source(...) | -| main.rs:278:22:278:22 | n | main.rs:275:16:275:25 | source(...) | main.rs:278:22:278:22 | n | $@ | main.rs:275:16:275:25 | source(...) | source(...) | -| main.rs:282:29:282:29 | n | main.rs:275:16:275:25 | source(...) | main.rs:282:29:282:29 | n | $@ | main.rs:275:16:275:25 | source(...) | source(...) | -| main.rs:301:48:301:48 | n | main.rs:297:18:297:27 | source(...) | main.rs:301:48:301:48 | n | $@ | main.rs:297:18:297:27 | source(...) | source(...) | -| main.rs:305:81:305:81 | n | main.rs:297:18:297:27 | source(...) | main.rs:305:81:305:81 | n | $@ | main.rs:297:18:297:27 | source(...) | source(...) | -| main.rs:321:34:321:34 | n | main.rs:317:18:317:27 | source(...) | main.rs:321:34:321:34 | n | $@ | main.rs:317:18:317:27 | source(...) | source(...) | -| main.rs:325:53:325:53 | n | main.rs:317:18:317:27 | source(...) | main.rs:325:53:325:53 | n | $@ | main.rs:317:18:317:27 | source(...) | source(...) | +| main.rs:232:10:232:11 | i1 | main.rs:229:19:229:28 | source(...) | main.rs:232:10:232:11 | i1 | $@ | main.rs:229:19:229:28 | source(...) | source(...) | +| main.rs:243:10:243:11 | i1 | main.rs:238:35:238:44 | source(...) | main.rs:243:10:243:11 | i1 | $@ | main.rs:238:35:238:44 | source(...) | source(...) | +| main.rs:259:35:259:35 | n | main.rs:256:29:256:38 | source(...) | main.rs:259:35:259:35 | n | $@ | main.rs:256:29:256:38 | source(...) | source(...) | +| main.rs:263:55:263:55 | n | main.rs:256:29:256:38 | source(...) | main.rs:263:55:263:55 | n | $@ | main.rs:256:29:256:38 | source(...) | source(...) | +| main.rs:277:22:277:22 | n | main.rs:274:16:274:25 | source(...) | main.rs:277:22:277:22 | n | $@ | main.rs:274:16:274:25 | source(...) | source(...) | +| main.rs:281:29:281:29 | n | main.rs:274:16:274:25 | source(...) | main.rs:281:29:281:29 | n | $@ | main.rs:274:16:274:25 | source(...) | source(...) | +| main.rs:300:48:300:48 | n | main.rs:296:18:296:27 | source(...) | main.rs:300:48:300:48 | n | $@ | main.rs:296:18:296:27 | source(...) | source(...) | +| main.rs:304:81:304:81 | n | main.rs:296:18:296:27 | source(...) | main.rs:304:81:304:81 | n | $@ | main.rs:296:18:296:27 | source(...) | source(...) | +| main.rs:320:34:320:34 | n | main.rs:316:18:316:27 | source(...) | main.rs:320:34:320:34 | n | $@ | main.rs:316:18:316:27 | source(...) | source(...) | +| main.rs:324:53:324:53 | n | main.rs:316:18:316:27 | source(...) | main.rs:324:53:324:53 | n | $@ | main.rs:316:18:316:27 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 8ddfcfbf130..5f24267f8ff 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -229,9 +229,8 @@ fn option_questionmark() -> Option { let s1 = Some(source(20)); let s2 = Some(2); let i1 = s1?; - let i2 = s2?; - sink(i1); // $ MISSING: hasValueFlow=20 - sink(i2); + sink(i1); // $ hasValueFlow=20 + sink(s2?); Some(0) } @@ -241,7 +240,7 @@ fn result_questionmark() -> Result { let s3: Result = Err(source(77)); let i1 = s1?; let i2 = s2?; - sink(i1); // $ MISSING: hasValueFlow=20 + sink(i1); // $ hasValueFlow=20 sink(i2); let i3 = s3?; sink(i3); // No flow since value is in `Err`. From e6641e7630b6c07138befb20b84107424c5a94fd Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 3 Dec 2024 11:06:08 -0500 Subject: [PATCH 46/63] Code and comment simplifications --- .../lib/semmle/code/cpp/models/interfaces/NonThrowing.qll | 3 ++- cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll index 5ddf754f745..85b9b66cd66 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll @@ -7,7 +7,8 @@ import semmle.code.cpp.models.Models /** * A function that is guaranteed to never throw a C++ exception - * (distinct from a structured exception handling, SEH, exception). + * + * The function may still raise a structured exception handling (SEH) exception. */ abstract class NonCppThrowingFunction extends Function { } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index 044b30f7b70..cc294806709 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -14,8 +14,6 @@ import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs * A function that is known to raise an exception. */ abstract class ThrowingFunction extends Function { - ThrowingFunction() { any() } - /** * Holds if this function may throw an exception during evaluation. * If `unconditional` is `true` the function always throws an exception. @@ -24,8 +22,6 @@ abstract class ThrowingFunction extends Function { } /** - * A function that is known to raise an exception unconditionally. - * The only cases known where this happens is for SEH - * (structured exception handling) exceptions. + * A function that unconditionally raises a structured exception handling (SEH) exception. */ abstract class AlwaysSehThrowingFunction extends Function { } From 8271ad60c12040916674aa02bc500c3415e02873 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 15:54:07 +0100 Subject: [PATCH 47/63] Remove deprecated `InlineExpectationsTest` class-based API --- ...eprected-inline-expecation-test-classes.md | 4 ++ .../util/test/InlineExpectationsTest.qll | 49 ------------------- 2 files changed, 4 insertions(+), 49 deletions(-) create mode 100644 shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md diff --git a/shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md b/shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md new file mode 100644 index 00000000000..6126e37b619 --- /dev/null +++ b/shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated inline expectation test API that was based on the `InlineExpectationsTest` class. diff --git a/shared/util/codeql/util/test/InlineExpectationsTest.qll b/shared/util/codeql/util/test/InlineExpectationsTest.qll index bd51ad1c2bd..415450c1603 100644 --- a/shared/util/codeql/util/test/InlineExpectationsTest.qll +++ b/shared/util/codeql/util/test/InlineExpectationsTest.qll @@ -500,55 +500,6 @@ module Make { } } - deprecated private module LegacyImpl implements TestSig { - string getARelevantTag() { result = any(InlineExpectationsTest t).getARelevantTag() } - - predicate hasActualResult(Impl::Location location, string element, string tag, string value) { - any(InlineExpectationsTest t).hasActualResult(location, element, tag, value) - } - - predicate hasOptionalResult(Impl::Location location, string element, string tag, string value) { - any(InlineExpectationsTest t).hasOptionalResult(location, element, tag, value) - } - } - - /** - * DEPRECATED: Use the InlineExpectationsTest module. - * - * The base class for tests with inline expectations. The test extends this class to provide the actual - * results of the query, which are then compared with the expected results in comments to produce a - * list of failure messages that point out where the actual results differ from the expected - * results. - */ - abstract deprecated class InlineExpectationsTest extends string { - bindingset[this] - InlineExpectationsTest() { any() } - - abstract string getARelevantTag(); - - abstract predicate hasActualResult( - Impl::Location location, string element, string tag, string value - ); - - predicate hasOptionalResult(Impl::Location location, string element, string tag, string value) { - none() - } - } - - deprecated import MakeTest as LegacyTest - - deprecated query predicate failures = LegacyTest::testFailures/2; - - deprecated class ActualResult = LegacyTest::ActualTestResult; - - deprecated class GoodExpectation = LegacyTest::GoodTestExpectation; - - deprecated class FalsePositiveExpectation = LegacyTest::FalsePositiveTestExpectation; - - deprecated class FalseNegativeExpectation = LegacyTest::FalseNegativeTestExpectation; - - deprecated class InvalidExpectation = LegacyTest::InvalidTestExpectation; - /** * Holds if the expectation `tag=value` is found in one or more expectation comments. * From ca40b60e620d7c51c29613f0bdfe40b49b2ae265 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 16:02:35 +0100 Subject: [PATCH 48/63] Ruby: update expected test results --- .../test/library-tests/concepts/CryptographicOperation.expected | 2 -- .../dataflow/api-graphs/VerifyApiGraphExpectations.expected | 2 -- .../dataflow/array-flow/type-tracking-array-flow.expected | 2 -- .../dataflow/barrier-guards/barrier-guards.expected | 1 - .../dataflow/global/TypeTrackingInlineTest.expected | 2 -- .../dataflow/hash-flow/type-tracking-hash-flow.expected | 2 -- .../improper-memoization/ImproperMemoization.expected | 1 - .../IncompleteMultiCharacterSanitization.expected | 2 -- .../query-tests/security/cwe-300/InsecureDependency.expected | 1 - .../test/query-tests/security/cwe-829/InsecureDownload.expected | 1 - 10 files changed, 16 deletions(-) diff --git a/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected b/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected index 48de9172b36..e69de29bb2d 100644 --- a/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected +++ b/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected b/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected index 8ec8033d086..e69de29bb2d 100644 --- a/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected +++ b/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected index 08bd543b2cd..af0a1e7ef11 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected @@ -1,4 +1,3 @@ -testFailures | array_flow.rb:107:10:107:13 | ...[...] | Unexpected result: hasValueFlow=11.2 | | array_flow.rb:179:28:179:46 | # $ hasValueFlow=19 | Missing result: hasValueFlow=19 | | array_flow.rb:180:28:180:46 | # $ hasValueFlow=19 | Missing result: hasValueFlow=19 | @@ -65,4 +64,3 @@ testFailures | array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result: hasValueFlow=136.2 | | array_flow.rb:1627:19:1627:40 | # $ hasValueFlow=136.1 | Missing result: hasValueFlow=136.1 | | array_flow.rb:1699:13:1699:32 | # $ hasValueFlow=143 | Missing result: hasValueFlow=143 | -failures diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index 21d697c86e9..919dcb71c2f 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -1,5 +1,4 @@ testFailures -failures newStyleBarrierGuards | barrier-guards.rb:3:16:4:19 | [input] SSA phi read(foo) | | barrier-guards.rb:4:5:4:7 | foo | diff --git a/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected b/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected index 0f65c470b9c..413b5d6748f 100644 --- a/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected +++ b/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected @@ -1,4 +1,3 @@ -testFailures | blocks.rb:4:10:4:10 | r | Fixed missing result: hasValueFlow=1 | | captured_variables.rb:50:10:50:10 | x | Fixed missing result: hasValueFlow=2 | | captured_variables.rb:68:25:68:68 | # $ hasValueFlow=3 $ MISSING: hasValueFlow=4 | Missing result: hasValueFlow=3 | @@ -30,4 +29,3 @@ testFailures | instance_variables.rb:114:23:114:41 | # $ hasValueFlow=28 | Missing result: hasValueFlow=28 | | instance_variables.rb:117:23:117:41 | # $ hasValueFlow=29 | Missing result: hasValueFlow=29 | | instance_variables.rb:120:23:120:41 | # $ hasValueFlow=30 | Missing result: hasValueFlow=30 | -failures diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected b/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected index c3d0d531ffa..e812393899e 100644 --- a/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected @@ -1,4 +1,3 @@ -testFailures | hash_flow.rb:65:21:65:40 | # $ hasValueFlow=3.3 | Missing result: hasValueFlow=3.3 | | hash_flow.rb:66:21:66:49 | # $ SPURIOUS hasValueFlow=3.3 | Missing result: hasValueFlow=3.3 | | hash_flow.rb:117:10:117:17 | ...[...] | Unexpected result: hasValueFlow=7.1 | @@ -21,4 +20,3 @@ testFailures | hash_flow.rb:779:10:779:14 | ...[...] | Unexpected result: hasValueFlow=46.3 | | hash_flow.rb:781:10:781:17 | ...[...] | Unexpected result: hasValueFlow=46.1 | | hash_flow.rb:784:10:784:17 | ...[...] | Unexpected result: hasValueFlow=46.3 | -failures diff --git a/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected b/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected index 86c29d64b6e..36c07e3e105 100644 --- a/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected +++ b/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected @@ -1,4 +1,3 @@ -failures testFailures | improper_memoization.rb:100:1:104:3 | m14 | Unexpected result: result=BAD | #select diff --git a/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected b/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected index 48de9172b36..e69de29bb2d 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected +++ b/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected b/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected index d123230e55d..c27dc45b686 100644 --- a/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected +++ b/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected @@ -1,4 +1,3 @@ -failures testFailures #select | Gemfile:2:8:2:28 | "http://rubygems.org" | Dependency source URL uses the unencrypted protocol HTTP. Use HTTPS instead. | diff --git a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected index c025499f2e8..2ea527a3fc6 100644 --- a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected +++ b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected @@ -1,5 +1,4 @@ testFailures -failures edges | insecure_download.rb:31:5:31:7 | url | insecure_download.rb:33:15:33:17 | url | provenance | | | insecure_download.rb:31:5:31:7 | url | insecure_download.rb:33:15:33:17 | url | provenance | | From 67052bf9e50a8425dd560b2cdbcb3306f9391aca Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 16:14:50 +0100 Subject: [PATCH 49/63] Swift: Update expected test results --- .../ql/test/library-tests/dataflow/capture/FlowInline.expected | 2 -- .../library-tests/dataflow/dataflow/DataFlowInline.expected | 2 -- .../dataflow/flowsources/FlowSourcesInline.expected | 2 -- .../test/library-tests/dataflow/taint/core/TaintInline.expected | 2 -- .../library-tests/dataflow/taint/libraries/TaintInline.expected | 2 -- swift/ql/test/library-tests/regex/regex.expected | 2 -- .../Security/CWE-022/PathInjection/PathInjectionTest.expected | 2 -- .../query-tests/Security/CWE-312/CleartextLoggingTest.expected | 2 -- swift/ql/test/query-tests/Security/CWE-611/XXETest.expected | 2 -- .../Security/CWE-946/PredicateInjectionTest.expected | 2 -- 10 files changed, 20 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/capture/FlowInline.expected b/swift/ql/test/library-tests/dataflow/capture/FlowInline.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/capture/FlowInline.expected +++ b/swift/ql/test/library-tests/dataflow/capture/FlowInline.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/swift/ql/test/library-tests/dataflow/flowsources/FlowSourcesInline.expected b/swift/ql/test/library-tests/dataflow/flowsources/FlowSourcesInline.expected index 8ec8033d086..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/flowsources/FlowSourcesInline.expected +++ b/swift/ql/test/library-tests/dataflow/flowsources/FlowSourcesInline.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/swift/ql/test/library-tests/dataflow/taint/core/TaintInline.expected b/swift/ql/test/library-tests/dataflow/taint/core/TaintInline.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/TaintInline.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/TaintInline.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/TaintInline.expected b/swift/ql/test/library-tests/dataflow/taint/libraries/TaintInline.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/TaintInline.expected +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/TaintInline.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/swift/ql/test/library-tests/regex/regex.expected b/swift/ql/test/library-tests/regex/regex.expected index 8ec8033d086..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/regex/regex.expected +++ b/swift/ql/test/library-tests/regex/regex.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/swift/ql/test/query-tests/Security/CWE-022/PathInjection/PathInjectionTest.expected b/swift/ql/test/query-tests/Security/CWE-022/PathInjection/PathInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/query-tests/Security/CWE-022/PathInjection/PathInjectionTest.expected +++ b/swift/ql/test/query-tests/Security/CWE-022/PathInjection/PathInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected b/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected +++ b/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/swift/ql/test/query-tests/Security/CWE-611/XXETest.expected b/swift/ql/test/query-tests/Security/CWE-611/XXETest.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/query-tests/Security/CWE-611/XXETest.expected +++ b/swift/ql/test/query-tests/Security/CWE-611/XXETest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/swift/ql/test/query-tests/Security/CWE-946/PredicateInjectionTest.expected b/swift/ql/test/query-tests/Security/CWE-946/PredicateInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/swift/ql/test/query-tests/Security/CWE-946/PredicateInjectionTest.expected +++ b/swift/ql/test/query-tests/Security/CWE-946/PredicateInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures From 99cbeb7eb66192c88845047686229e1a0432b653 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 16:23:50 +0100 Subject: [PATCH 50/63] Go: Update expected test results --- .../CWE-522-DecompressionBombs/DecompressionBombTest.expected | 1 - .../test/experimental/frameworks/CleverGo/HeaderWrite.expected | 2 -- .../test/experimental/frameworks/CleverGo/HttpRedirect.expected | 2 -- .../experimental/frameworks/CleverGo/HttpResponseBody.expected | 2 -- .../experimental/frameworks/CleverGo/RemoteSources.expected | 2 -- go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected | 2 -- go/ql/test/experimental/frameworks/Fiber/Redirect.expected | 2 -- .../experimental/frameworks/Fiber/RemoteFlowSources.expected | 2 -- go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected | 2 -- go/ql/test/library-tests/semmle/go/Function/isVariadic.expected | 2 -- .../library-tests/semmle/go/Types/ImplementsComparable.expected | 2 -- .../semmle/go/Types/SignatureType_isVariadic.expected | 2 -- .../test/library-tests/semmle/go/concepts/HTTP/Handler.expected | 2 -- .../semmle/go/concepts/LoggerCall/LoggerCall.expected | 1 - .../ExternalFlowInheritance/mad_I1_subtypes_false.expected | 1 - .../ExternalFlowInheritance/mad_I1_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_I2_subtypes_false.expected | 1 - .../ExternalFlowInheritance/mad_I2_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.expected | 1 - .../mad_PImplEmbedI1_subtypes_true.expected | 1 - .../mad_PImplEmbedI2_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_S1_subtypes_false.expected | 1 - .../ExternalFlowInheritance/mad_S1_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected | 1 - .../mad_SEmbedPtrP1_subtypes_true.expected | 1 - .../mad_SEmbedPtrP2_subtypes_true.expected | 1 - .../mad_SEmbedPtrS1_subtypes_true.expected | 1 - .../mad_SEmbedPtrS2_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.expected | 1 - .../ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.expected | 1 - .../mad_SImplEmbedI1_subtypes_true.expected | 1 - .../mad_SImplEmbedI2_subtypes_true.expected | 1 - .../mad_SImplEmbedS1_subtypes_true.expected | 1 - .../mad_SImplEmbedS2_subtypes_true.expected | 1 - .../semmle/go/dataflow/ExternalFlowInheritance/ql_I1.expected | 1 - .../semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected | 1 - .../semmle/go/dataflow/ExternalFlowInheritance/ql_S1.expected | 1 - .../semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected | 1 - .../go/dataflow/flowsources/local/environment/test.expected | 1 - .../semmle/go/dataflow/flowsources/local/file/test.expected | 1 - .../semmle/go/dataflow/flowsources/local/stdin/source.expected | 1 - .../library-tests/semmle/go/frameworks/Afero/Query.expected | 1 - .../semmle/go/frameworks/BeegoOrm/QueryString.expected | 1 - .../semmle/go/frameworks/CouchbaseV1/test.expected | 1 - .../semmle/go/frameworks/ElazarlGoproxy/test.expected | 1 - .../semmle/go/frameworks/Fasthttp/EscapeFunction.expected | 2 -- .../semmle/go/frameworks/Fasthttp/FileSystemAccess.expected | 2 -- .../semmle/go/frameworks/Fasthttp/OpenRedirect.expected | 2 -- .../semmle/go/frameworks/Fasthttp/RemoteFlowSources.expected | 2 -- .../library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected | 2 -- .../library-tests/semmle/go/frameworks/Fasthttp/Xss.expected | 2 -- .../library-tests/semmle/go/frameworks/Fiber/Query.expected | 1 - .../semmle/go/frameworks/GoKit/RemoteFlowSources.expected | 1 - .../library-tests/semmle/go/frameworks/GoMicro/gomicro.expected | 1 - .../test/library-tests/semmle/go/frameworks/Iris/Query.expected | 1 - .../go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected | 1 - .../library-tests/semmle/go/frameworks/Macaron/Sources.expected | 1 - .../library-tests/semmle/go/frameworks/NoSQL/Query.expected | 1 - .../test/library-tests/semmle/go/frameworks/Revel/test.expected | 2 -- .../semmle/go/frameworks/SQL/Gorm/QueryString.expected | 1 - .../library-tests/semmle/go/frameworks/SQL/QueryString.expected | 1 - .../semmle/go/frameworks/SQL/Sqlx/QueryString.expected | 1 - .../semmle/go/frameworks/SQL/bun/QueryString.expected | 1 - .../semmle/go/frameworks/SQL/gogf/QueryString.expected | 1 - .../semmle/go/frameworks/SQL/gorqlite/QueryString.expected | 1 - .../semmle/go/frameworks/StdlibTaintFlow/test.expected | 1 - .../test/library-tests/semmle/go/frameworks/Yaml/tests.expected | 1 - .../library-tests/semmle/go/frameworks/gqlgen/gqlgen.expected | 1 - .../Security/CWE-681/IncorrectIntegerConversion.expected | 1 - 73 files changed, 92 deletions(-) diff --git a/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombTest.expected b/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombTest.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombTest.expected +++ b/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombTest.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/RemoteSources.expected b/go/ql/test/experimental/frameworks/CleverGo/RemoteSources.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/RemoteSources.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/RemoteSources.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected +++ b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/Redirect.expected b/go/ql/test/experimental/frameworks/Fiber/Redirect.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/Fiber/Redirect.expected +++ b/go/ql/test/experimental/frameworks/Fiber/Redirect.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/RemoteFlowSources.expected b/go/ql/test/experimental/frameworks/Fiber/RemoteFlowSources.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/Fiber/RemoteFlowSources.expected +++ b/go/ql/test/experimental/frameworks/Fiber/RemoteFlowSources.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected +++ b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected b/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected +++ b/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected +++ b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected +++ b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_false.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_false.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_false.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_false.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_false.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_false.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_false.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_false.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_I2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_false.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_false.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_false.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_false.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_S1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected b/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/environment/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/environment/test.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/environment/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/environment/test.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/file/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/file/test.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/file/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/file/test.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/stdin/source.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Afero/Query.expected b/go/ql/test/library-tests/semmle/go/frameworks/Afero/Query.expected index 08c5eee5289..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Afero/Query.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Afero/Query.expected @@ -1,3 +1,2 @@ invalidModelRow testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/QueryString.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/QueryString.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/EscapeFunction.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/EscapeFunction.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/EscapeFunction.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/EscapeFunction.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/FileSystemAccess.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/FileSystemAccess.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/FileSystemAccess.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/FileSystemAccess.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/OpenRedirect.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/OpenRedirect.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/RemoteFlowSources.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/RemoteFlowSources.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/RemoteFlowSources.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/RemoteFlowSources.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/Xss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/Xss.expected index 8ec8033d086..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/Xss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/Xss.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fiber/Query.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fiber/Query.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fiber/Query.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fiber/Query.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoKit/RemoteFlowSources.expected b/go/ql/test/library-tests/semmle/go/frameworks/GoKit/RemoteFlowSources.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoKit/RemoteFlowSources.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoKit/RemoteFlowSources.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/gomicro.expected b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/gomicro.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/gomicro.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/gomicro.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Iris/Query.expected b/go/ql/test/library-tests/semmle/go/frameworks/Iris/Query.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Iris/Query.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Iris/Query.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Sources.expected b/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Sources.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Sources.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Sources.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected b/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/QueryString.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/Sqlx/QueryString.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/bun/QueryString.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gogf/QueryString.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected index db33d6d2504..55e9aed2e93 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/gorqlite/QueryString.expected @@ -1,3 +1,2 @@ testFailures invalidModelRow -failures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/gqlgen/gqlgen.expected b/go/ql/test/library-tests/semmle/go/frameworks/gqlgen/gqlgen.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/gqlgen/gqlgen.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/gqlgen/gqlgen.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures diff --git a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected index 105b7026d0c..42831abaf15 100644 --- a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected +++ b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected @@ -1,3 +1,2 @@ -failures invalidModelRow testFailures From e89f37df1a478831ff8e351dad511648b49dd4e2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 16:33:53 +0100 Subject: [PATCH 51/63] Rust: Update expected test results --- rust/ql/test/library-tests/variables/variables.expected | 1 - rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected | 2 -- 2 files changed, 3 deletions(-) diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 9abee1df82e..dd3c3cf6c10 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,5 +1,4 @@ testFailures -failures variable | variables.rs:3:14:3:14 | s | | variables.rs:7:14:7:14 | i | diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected b/rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected index 8ec8033d086..e69de29bb2d 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected +++ b/rust/ql/test/query-tests/security/CWE-089/SqlSinks.expected @@ -1,2 +0,0 @@ -testFailures -failures From 1420f564a5366960931f3f25067d46c556fe862a Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 16:37:50 +0100 Subject: [PATCH 52/63] C++: Update expected test results --- .../test/library-tests/dataflow/asExpr/test-indirect.expected | 2 -- cpp/ql/test/library-tests/dataflow/asExpr/test.expected | 2 -- .../dataflow-tests/guard-condition-regression-test.expected | 2 -- .../dataflow/dataflow-tests/has-parameter-flow-out.expected | 2 -- .../dataflow/dataflow-tests/test-number-of-outnodes.expected | 2 -- cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected | 2 -- .../dataflow/dataflow-tests/test_self_argument_flow.expected | 2 -- .../dataflow/dataflow-tests/test_self_parameter_flow.expected | 2 -- .../library-tests/dataflow/dataflow-tests/type-bugs.expected | 1 - .../test/library-tests/dataflow/external-models/flow.expected | 1 - cpp/ql/test/library-tests/dataflow/fields/flow.expected | 2 -- .../dataflow/models-as-data/interpretElement.expected | 2 -- .../test/library-tests/dataflow/models-as-data/taint.expected | 2 -- .../dataflow/parameters-without-defs/test.expected | 2 -- .../library-tests/dataflow/smart-pointers-taint/taint.expected | 2 -- .../dataflow/source-sink-tests/local-flow.expected | 2 -- .../dataflow/source-sink-tests/remote-flow.expected | 2 -- cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected | 2 -- .../library-tests/ir/modulus-analysis/ModulusAnalysis.expected | 2 -- cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected | 2 -- .../test/library-tests/ir/range-analysis/RangeAnalysis.expected | 2 -- .../test/library-tests/ir/sign-analysis/SignAnalysis.expected | 2 -- cpp/ql/test/library-tests/ir/types/irtypes.expected | 2 -- .../Security/CWE/CWE-193/AllocationToInvalidPointer.expected | 2 -- .../Security/CWE/CWE-193/InvalidPointerToDereference.expected | 2 -- 25 files changed, 48 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/asExpr/test-indirect.expected b/cpp/ql/test/library-tests/dataflow/asExpr/test-indirect.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/asExpr/test-indirect.expected +++ b/cpp/ql/test/library-tests/dataflow/asExpr/test-indirect.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/asExpr/test.expected b/cpp/ql/test/library-tests/dataflow/asExpr/test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/asExpr/test.expected +++ b/cpp/ql/test/library-tests/dataflow/asExpr/test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected index 22f278d41ae..5711cec229d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected @@ -1,3 +1 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (has-parameter-flow-out.ql:5,18-61) -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected index a32c8f7af91..316ac213731 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected @@ -1,3 +1 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (test-number-of-outnodes.ql:5,18-61) -failures -testFailures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected index 48de9172b36..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected index 02f5544fe14..87ebdc9e83a 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected @@ -52,4 +52,3 @@ incorrectBaseType | test.cpp:854:10:854:36 | * ... | Expected 'Node.getType()' to be const int, but it was int | | test.cpp:867:10:867:30 | * ... | Expected 'Node.getType()' to be const int, but it was int | | test.cpp:1098:52:1098:53 | *& ... | Expected 'Node.getType()' to be char, but it was char * | -failures diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index a3d09178f2c..8a954e9235a 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -1,5 +1,4 @@ testFailures -failures edges | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:10 | | asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:2 | diff --git a/cpp/ql/test/library-tests/dataflow/fields/flow.expected b/cpp/ql/test/library-tests/dataflow/fields/flow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/flow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/interpretElement.expected b/cpp/ql/test/library-tests/dataflow/models-as-data/interpretElement.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/models-as-data/interpretElement.expected +++ b/cpp/ql/test/library-tests/dataflow/models-as-data/interpretElement.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/taint.expected b/cpp/ql/test/library-tests/dataflow/models-as-data/taint.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/models-as-data/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/models-as-data/taint.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/parameters-without-defs/test.expected b/cpp/ql/test/library-tests/dataflow/parameters-without-defs/test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/parameters-without-defs/test.expected +++ b/cpp/ql/test/library-tests/dataflow/parameters-without-defs/test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected index dfa7c56f90b..a3e8b75f996 100644 --- a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected @@ -2,5 +2,3 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (tai WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:7,24-32) WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:11,22-30) WARNING: module 'TaintTracking' has been deprecated and may be removed in future (taint.ql:19,20-33) -failures -testFailures diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 299f1413878..444be256516 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -3,5 +3,3 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (tai WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:61,22-30) WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: module 'TaintTracking' has been deprecated and may be removed in future (taint.ql:73,20-33) -testFailures -failures diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected +++ b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected +++ b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/library-tests/ir/types/irtypes.expected b/cpp/ql/test/library-tests/ir/types/irtypes.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/ir/types/irtypes.expected +++ b/cpp/ql/test/library-tests/ir/types/irtypes.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-193/AllocationToInvalidPointer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-193/AllocationToInvalidPointer.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-193/AllocationToInvalidPointer.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-193/AllocationToInvalidPointer.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-193/InvalidPointerToDereference.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-193/InvalidPointerToDereference.expected index 8ec8033d086..e69de29bb2d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-193/InvalidPointerToDereference.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-193/InvalidPointerToDereference.expected @@ -1,2 +0,0 @@ -testFailures -failures From c3ea883b1113b13dc7c1a31ee2aadce9dcee552d Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 16:51:43 +0100 Subject: [PATCH 53/63] Python: Update expected test results --- .../ql/test/experimental/import-resolution/importflow.expected | 2 -- python/ql/test/experimental/import-resolution/imports.expected | 2 -- .../CallGraph-implicit-init/InlineCallGraphTest.expected | 1 - .../CallGraph-imports/InlineCallGraphTest.expected | 1 - .../library-tests/CallGraph/InlineCallGraphTest.expected | 1 - .../meta/inline-taint-test-demo/InlineTaintTest.expected | 1 - .../Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected | 1 - .../CWE-074-RemoteCommandExecution/ConceptsTest.expected | 2 -- .../CWE-074-RemoteCommandExecution/DataflowQueryTest.expected | 1 - .../query-tests/Security/CWE-409/DataflowQueryTest.expected | 1 - python/ql/test/library-tests/ApiGraphs/py2/use.expected | 2 -- .../InlineExpectationsTest/missing-relevant-tag/Test.expected | 2 -- .../library-tests/dataflow/basic/localFlowStepTest.expected | 2 -- .../test/library-tests/dataflow/basic/maximalFlowTest.expected | 2 -- .../test/library-tests/dataflow/calls/DataFlowCallTest.expected | 2 -- .../dataflow/coverage-py2/argumentRoutingTest.expected | 2 -- .../dataflow/coverage-py3/argumentRoutingTest.expected | 2 -- .../library-tests/dataflow/coverage/NormalDataflowTest.expected | 1 - .../dataflow/coverage/argumentRoutingTest.expected | 2 -- .../dataflow/exceptions/NormalDataflowTest.expected | 1 - .../dataflow/fieldflow/NormalDataflowTest.expected | 1 - .../library-tests/dataflow/fieldflow/UnresolvedCalls.expected | 2 -- .../test/library-tests/dataflow/global-flow/accesses.expected | 2 -- .../dataflow/global-or-captured-vars/test.expected | 1 - .../library-tests/dataflow/match/NormalDataflowTest.expected | 1 - .../dataflow/model-summaries/InlineTaintTest.expected | 1 - .../dataflow/model-summaries/NormalDataflowTest.expected | 1 - .../dataflow/module-initialization/localFlow.expected | 2 -- .../test/library-tests/dataflow/path-graph/PathNodes.expected | 2 -- .../dataflow/sensitive-data/TestSensitiveDataSources.expected | 2 -- .../library-tests/dataflow/summaries/InlineTaintTest.expected | 1 - .../dataflow/summaries/NormalTaintTrackingTest.expected | 1 - .../tainttracking/commonSanitizer/InlineTaintTest.expected | 1 - .../tainttracking/customSanitizer/InlineTaintTest.expected | 1 - .../defaultAdditionalTaintStep-py3/InlineTaintTest.expected | 1 - .../defaultAdditionalTaintStep/InlineTaintTest.expected | 1 - .../tainttracking/generator-flow/InlineTaintTest.expected | 1 - .../tainttracking/generator-flow/NormalDataflowTest.expected | 1 - .../dataflow/tainttracking/isinstance/InlineTaintTest.expected | 1 - .../tainttracking/unwanted-global-flow/InlineTaintTest.expected | 1 - .../dataflow/typetracking-summaries/tracked.expected | 2 -- .../test/library-tests/dataflow/typetracking/tracked.expected | 2 -- .../dataflow/typetracking_imports/tracked.expected | 2 -- .../dataflow/variable-capture/CaptureTest.expected | 2 -- python/ql/test/library-tests/essa/ssa-compute/UseUse.expected | 2 -- .../test/library-tests/frameworks/aioch/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/aiofile/ConceptsTest.expected | 2 -- .../library-tests/frameworks/aiofiles/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/aiohttp/ConceptsTest.expected | 2 -- .../library-tests/frameworks/aiohttp/InlineTaintTest.expected | 1 - .../library-tests/frameworks/aiomysql/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/aiopg/ConceptsTest.expected | 2 -- .../library-tests/frameworks/aiosqlite/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/anyio/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/asyncpg/ConceptsTest.expected | 2 -- .../ql/test/library-tests/frameworks/asyncpg/MaDTest.expected | 2 -- .../test/library-tests/frameworks/baize/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/bottle/ConceptsTest.expected | 2 -- .../library-tests/frameworks/bottle/InlineTaintTest.expected | 1 - .../frameworks/cassandra-driver/ConceptsTest.expected | 2 -- .../library-tests/frameworks/cherrypy/ConceptsTest.expected | 2 -- .../frameworks/clickhouse_driver/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/crypto/ConceptsTest.expected | 2 -- .../library-tests/frameworks/cryptodome/ConceptsTest.expected | 2 -- .../library-tests/frameworks/cryptography/ConceptsTest.expected | 2 -- .../library-tests/frameworks/cx_Oracle/ConceptsTest.expected | 2 -- .../ql/test/library-tests/frameworks/dill/ConceptsTest.expected | 2 -- .../frameworks/django-orm/NormalDataflowTest.expected | 1 - .../library-tests/frameworks/django-v1/ConceptsTest.expected | 2 -- .../library-tests/frameworks/django-v2-v3/ConceptsTest.expected | 2 -- .../frameworks/django-v2-v3/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/django/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/fabric/ConceptsTest.expected | 2 -- .../library-tests/frameworks/fabric/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/fastapi/ConceptsTest.expected | 2 -- .../library-tests/frameworks/fastapi/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/flask/ConceptsTest.expected | 2 -- .../library-tests/frameworks/flask/InlineTaintTest.expected | 1 - .../library-tests/frameworks/flask_admin/ConceptsTest.expected | 2 -- .../frameworks/flask_admin/InlineTaintTest.expected | 1 - .../frameworks/flask_sqlalchemy/ConceptsTest.expected | 2 -- .../frameworks/flask_sqlalchemy/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/gradio/source_test.expected | 2 -- .../test/library-tests/frameworks/httpx/ConceptsTest.expected | 2 -- .../ql/test/library-tests/frameworks/idna/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/idna/InlineTaintTest.expected | 1 - .../internal-ql-helpers/PoorMansFunctionResolutionTest.expected | 2 -- .../test/library-tests/frameworks/invoke/ConceptsTest.expected | 2 -- .../library-tests/frameworks/jmespath/ConceptsTest.expected | 2 -- .../library-tests/frameworks/jmespath/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/joblib/ConceptsTest.expected | 2 -- .../library-tests/frameworks/jsonpickle/ConceptsTest.expected | 2 -- .../library-tests/frameworks/libtaxii/ConceptsTest.expected | 2 -- .../ql/test/library-tests/frameworks/lxml/ConceptsTest.expected | 2 -- .../library-tests/frameworks/markupsafe/ConceptsTest.expected | 2 -- .../frameworks/markupsafe/InlineTaintTest.expected | 1 - .../library-tests/frameworks/multidict/ConceptsTest.expected | 2 -- .../library-tests/frameworks/multidict/InlineTaintTest.expected | 1 - .../frameworks/mysql-connector-python/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/mysqldb/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/numpy/ConceptsTest.expected | 2 -- .../library-tests/frameworks/oracledb/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/pandas/ConceptsTest.expected | 2 -- .../library-tests/frameworks/paramiko/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/peewee/ConceptsTest.expected | 2 -- .../library-tests/frameworks/peewee/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/pexpect/ConceptsTest.expected | 2 -- .../library-tests/frameworks/phoenixdb/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/psycopg/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/pycurl/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/pymssql/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/pymysql/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/pyodbc/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/pyramid/ConceptsTest.expected | 2 -- .../library-tests/frameworks/pyramid/InlineTaintTest.expected | 1 - .../library-tests/frameworks/requests/ConceptsTest.expected | 2 -- .../library-tests/frameworks/requests/InlineTaintTest.expected | 1 - .../frameworks/rest_framework/ConceptsTest.expected | 2 -- .../frameworks/rest_framework/InlineTaintTest.expected | 1 - .../ql/test/library-tests/frameworks/rsa/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/rsa/InlineTaintTest.expected | 1 - .../library-tests/frameworks/ruamel.yaml/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/sanic/ConceptsTest.expected | 2 -- .../frameworks/serverless/InlineTaintTest.expected | 1 - .../library-tests/frameworks/simplejson/ConceptsTest.expected | 2 -- .../frameworks/simplejson/InlineTaintTest.expected | 1 - .../library-tests/frameworks/sqlalchemy/ConceptsTest.expected | 2 -- .../frameworks/sqlalchemy/InlineTaintTest.expected | 1 - .../library-tests/frameworks/starlette/ConceptsTest.expected | 2 -- .../library-tests/frameworks/stdlib-py2/ConceptsTest.expected | 2 -- .../library-tests/frameworks/stdlib-py3/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/stdlib/ConceptsTest.expected | 2 -- .../library-tests/frameworks/stdlib/InlineTaintTest.expected | 1 - .../library-tests/frameworks/streamlit/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/streamlit/rfs-test.expected | 2 -- .../ql/test/library-tests/frameworks/toml/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/torch/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/tornado/ConceptsTest.expected | 2 -- .../library-tests/frameworks/tornado/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/twisted/ConceptsTest.expected | 2 -- .../library-tests/frameworks/twisted/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/ujson/ConceptsTest.expected | 2 -- .../library-tests/frameworks/ujson/InlineTaintTest.expected | 1 - .../library-tests/frameworks/urllib/InlineTaintTest.expected | 1 - .../test/library-tests/frameworks/urllib3/ConceptsTest.expected | 2 -- .../library-tests/frameworks/xmltodict/ConceptsTest.expected | 2 -- .../ql/test/library-tests/frameworks/yaml/ConceptsTest.expected | 2 -- .../ql/test/library-tests/frameworks/yarl/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/yarl/InlineTaintTest.expected | 1 - python/ql/test/library-tests/regex/SubstructureTests.expected | 2 -- python/ql/test/library-tests/regexparser/Locations.expected | 2 -- .../Functions/ModificationOfParameterWithDefault/test.expected | 2 -- .../Security/CWE-022-PathInjection/DataflowQueryTest.expected | 1 - .../CWE-078-CommandInjection/DataflowQueryTest.expected | 1 - .../DataflowQueryTest.expected | 1 - .../Security/CWE-209-StackTraceExposure/ExceptionInfo.expected | 2 -- .../Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected | 1 - 157 files changed, 259 deletions(-) diff --git a/python/ql/test/experimental/import-resolution/importflow.expected b/python/ql/test/experimental/import-resolution/importflow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/experimental/import-resolution/importflow.expected +++ b/python/ql/test/experimental/import-resolution/importflow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/experimental/import-resolution/imports.expected b/python/ql/test/experimental/import-resolution/imports.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/experimental/import-resolution/imports.expected +++ b/python/ql/test/experimental/import-resolution/imports.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected index 802b8ff5d13..ff7202ce84d 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected @@ -1,5 +1,4 @@ testFailures -failures debug_callableNotUnique pointsTo_found_typeTracker_notFound typeTracker_found_pointsTo_notFound diff --git a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected index 802b8ff5d13..ff7202ce84d 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected @@ -1,5 +1,4 @@ testFailures -failures debug_callableNotUnique pointsTo_found_typeTracker_notFound typeTracker_found_pointsTo_notFound diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected index ef82a9ad20c..b353309e852 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected @@ -1,5 +1,4 @@ testFailures -failures debug_callableNotUnique pointsTo_found_typeTracker_notFound | code/class_attr_assign.py:10:9:10:27 | ControlFlowNode for Attribute() | my_func | diff --git a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected index e0ad49ff807..400399346d8 100644 --- a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected +++ b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected @@ -5,4 +5,3 @@ untaintedArgumentToEnsureTaintedNotMarkedAsMissing | taint_test.py:37:24:37:40 | taint_test.py:37 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted | testFailures | taint_test.py:41:20:41:21 | ts | Fixed missing result: tainted | -failures diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/ConceptsTest.expected b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/ConceptsTest.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/DataflowQueryTest.expected b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/DataflowQueryTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/DataflowQueryTest.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/DataflowQueryTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DataflowQueryTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/ApiGraphs/py2/use.expected b/python/ql/test/library-tests/ApiGraphs/py2/use.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/ApiGraphs/py2/use.expected +++ b/python/ql/test/library-tests/ApiGraphs/py2/use.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected index 8dd0c425627..561ab92d635 100644 --- a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected +++ b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected @@ -1,4 +1,2 @@ -testFailures | test.py:1:1:1:3 | foo | Tag mismatch: Actual result with tag 'foo' that is not part of getARelevantTag() | | test.py:4:1:4:3 | foo | Tag mismatch: Actual result with tag 'foo' that is not part of getARelevantTag() | -failures diff --git a/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected +++ b/python/ql/test/library-tests/dataflow/basic/localFlowStepTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected +++ b/python/ql/test/library-tests/dataflow/basic/maximalFlowTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected b/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected +++ b/python/ql/test/library-tests/dataflow/calls/DataFlowCallTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected +++ b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected index f7763cc9c1e..a0001b7c55c 100644 --- a/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected +++ b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.expected @@ -1,6 +1,4 @@ -testFailures | classes.py:54:44:54:107 | Comment #$ arg1="with_length_hint" func=With_length_hint.__length_hint__ | Missing result: arg1="with_length_hint" | | classes.py:54:44:54:107 | Comment #$ arg1="with_length_hint" func=With_length_hint.__length_hint__ | Missing result: func=With_length_hint.__length_hint__ | | classes.py:71:32:71:77 | Comment #$ arg1="with_index" func=With_index.__index__ | Missing result: arg1="with_index" | | classes.py:71:32:71:77 | Comment #$ arg1="with_index" func=With_index.__index__ | Missing result: func=With_index.__index__ | -failures diff --git a/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/dataflow/coverage/NormalDataflowTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected +++ b/python/ql/test/library-tests/dataflow/coverage/argumentRoutingTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/dataflow/exceptions/NormalDataflowTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/dataflow/fieldflow/NormalDataflowTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected index 96182702074..593b6e11887 100644 --- a/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected +++ b/python/ql/test/library-tests/dataflow/fieldflow/UnresolvedCalls.expected @@ -1,6 +1,4 @@ -testFailures | test.py:4:17:4:60 | ControlFlowNode for Attribute() | Unexpected result: unresolved_call=os.path.dirname(..) | | test.py:4:33:4:59 | ControlFlowNode for Attribute() | Unexpected result: unresolved_call=os.path.dirname(..) | | test_dict.py:4:17:4:60 | ControlFlowNode for Attribute() | Unexpected result: unresolved_call=os.path.dirname(..) | | test_dict.py:4:33:4:59 | ControlFlowNode for Attribute() | Unexpected result: unresolved_call=os.path.dirname(..) | -failures diff --git a/python/ql/test/library-tests/dataflow/global-flow/accesses.expected b/python/ql/test/library-tests/dataflow/global-flow/accesses.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/global-flow/accesses.expected +++ b/python/ql/test/library-tests/dataflow/global-flow/accesses.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected +++ b/python/ql/test/library-tests/dataflow/global-or-captured-vars/test.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/dataflow/match/NormalDataflowTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected +++ b/python/ql/test/library-tests/dataflow/module-initialization/localFlow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected +++ b/python/ql/test/library-tests/dataflow/path-graph/PathNodes.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected b/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected +++ b/python/ql/test/library-tests/dataflow/sensitive-data/TestSensitiveDataSources.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/summaries/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected +++ b/python/ql/test/library-tests/dataflow/summaries/NormalTaintTrackingTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected index 5a7d215048d..86d49b2b249 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected @@ -1,7 +1,6 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures isSanitizer | test.py:21:39:21:39 | ControlFlowNode for s | | test.py:34:39:34:39 | ControlFlowNode for s | diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/tainttracking/isinstance/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/isinstance/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/isinstance/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/isinstance/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected +++ b/python/ql/test/library-tests/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected +++ b/python/ql/test/library-tests/dataflow/typetracking-summaries/tracked.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/typetracking/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking/tracked.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/typetracking/tracked.expected +++ b/python/ql/test/library-tests/dataflow/typetracking/tracked.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected +++ b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected +++ b/python/ql/test/library-tests/dataflow/variable-capture/CaptureTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected b/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected +++ b/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aiofile/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiofile/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/aiofile/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiofile/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aiofiles/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiofiles/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/aiofiles/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiofiles/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/anyio/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/anyio/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/anyio/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/anyio/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected b/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected +++ b/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/baize/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/baize/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/baize/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/baize/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/bottle/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/bottle/ConceptsTest.expected index a74f2c23cda..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/bottle/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/bottle/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/bottle/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/bottle/InlineTaintTest.expected index a1a78355397..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/bottle/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/bottle/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/cherrypy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cherrypy/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/cherrypy/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cherrypy/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/gradio/source_test.expected b/python/ql/test/library-tests/frameworks/gradio/source_test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/gradio/source_test.expected +++ b/python/ql/test/library-tests/frameworks/gradio/source_test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected +++ b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/jsonpickle/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/jsonpickle/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/jsonpickle/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/jsonpickle/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/paramiko/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/paramiko/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/paramiko/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/paramiko/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pexpect/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pexpect/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/pexpect/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pexpect/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/psycopg/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/psycopg/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/psycopg/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/psycopg/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pyramid/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pyramid/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/pyramid/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pyramid/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/pyramid/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/pyramid/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/pyramid/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/pyramid/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/sanic/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/sanic/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/sanic/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/sanic/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/starlette/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/starlette/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/starlette/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/starlette/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/streamlit/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/streamlit/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/streamlit/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/streamlit/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/streamlit/rfs-test.expected b/python/ql/test/library-tests/frameworks/streamlit/rfs-test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/streamlit/rfs-test.expected +++ b/python/ql/test/library-tests/frameworks/streamlit/rfs-test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/torch/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/torch/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/torch/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/torch/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/urllib/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected index 366de37b867..020c338fd19 100644 --- a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected @@ -1,4 +1,3 @@ argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing testFailures -failures diff --git a/python/ql/test/library-tests/regex/SubstructureTests.expected b/python/ql/test/library-tests/regex/SubstructureTests.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/regex/SubstructureTests.expected +++ b/python/ql/test/library-tests/regex/SubstructureTests.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/library-tests/regexparser/Locations.expected b/python/ql/test/library-tests/regexparser/Locations.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/library-tests/regexparser/Locations.expected +++ b/python/ql/test/library-tests/regexparser/Locations.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected index 8ec8033d086..e69de29bb2d 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected index 9ce23b4c553..2fad7bb9a84 100644 --- a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected +++ b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected @@ -1,3 +1,2 @@ missingAnnotationOnSink testFailures -failures From 89d20fd0867c197634be7f28ee217d3158077d47 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 17:00:18 +0100 Subject: [PATCH 54/63] Java: Update expected test results --- .../all-platforms/default-parameter-mad-flow/test.expected | 2 -- .../test/library-tests/dataflow/callback-dispatch/test.expected | 2 -- .../dataflow/entrypoint-types/EntryPointTypesTest.expected | 2 -- java/ql/test/library-tests/dataflow/flowfeature/flow.expected | 2 -- java/ql/test/library-tests/dataflow/state/test.expected | 2 -- java/ql/test/library-tests/dataflow/taintsources/local.expected | 2 -- .../ql/test/library-tests/dataflow/taintsources/remote.expected | 2 -- .../library-tests/dataflow/taintsources/reversedns.expected | 2 -- java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected | 2 -- .../test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected | 2 -- .../frameworks/android/taint-database/flowSteps.expected | 2 -- .../frameworks/android/taint-database/sinks.expected | 2 -- .../library-tests/frameworks/guava/handwritten/flow.expected | 2 -- java/ql/test/library-tests/frameworks/jms/FlowTest.expected | 2 -- .../library-tests/frameworks/jms/RemoteSourcesTest.expected | 2 -- .../test/library-tests/frameworks/rabbitmq/SourceTest.expected | 2 -- .../neutrals/neutralsinks/NeutralSinksTest.expected | 2 -- java/ql/test/library-tests/xml/XMLTest.expected | 2 -- .../semmle/tests/PartialPathTraversalFromRemoteTest.expected | 2 -- .../query-tests/security/CWE-074/JndiInjectionTest.expected | 2 -- .../query-tests/security/CWE-074/XsltInjectionTest.expected | 2 -- .../test/query-tests/security/CWE-079/semmle/tests/XSS.expected | 2 -- .../security/CWE-089/semmle/examples/springjdbc.expected | 2 -- .../query-tests/security/CWE-094/ApkInstallationTest.expected | 2 -- .../query-tests/security/CWE-094/GroovyInjectionTest.expected | 2 -- .../query-tests/security/CWE-094/JexlInjectionTest.expected | 2 -- .../query-tests/security/CWE-094/MvelInjectionTest.expected | 2 -- .../query-tests/security/CWE-094/SpelInjectionTest.expected | 2 -- .../query-tests/security/CWE-094/TemplateInjectionTest.expected | 2 -- .../security/CWE-1204/StaticInitializationVectorTest.expected | 2 -- .../CWE-200/semmle/tests/SensitiveNotification/test.expected | 2 -- .../CWE-200/semmle/tests/SensitiveTextView/test.expected | 2 -- .../query-tests/security/CWE-273/UnsafeCertTrustTest.expected | 2 -- .../security/CWE-287/InsecureKeys/Test1/InsecureKeys.expected | 2 -- .../security/CWE-287/InsecureKeys/Test2/InsecureKeys.expected | 2 -- .../CWE-287/InsecureLocalAuth/InsecureLocalAuth.expected | 2 -- .../AndroidMissingCertificatePinning/Test1/test.expected | 2 -- .../AndroidMissingCertificatePinning/Test2/test.expected | 2 -- .../AndroidMissingCertificatePinning/Test3/test.expected | 2 -- .../AndroidMissingCertificatePinning/Test4/test.expected | 2 -- .../AndroidMissingCertificatePinning/Test5/test.expected | 2 -- .../CWE-295/ImproperWebVeiwCertificateValidation/test.expected | 2 -- .../InsecureTrustManager/InsecureTrustManagerTest.expected | 2 -- .../query-tests/security/CWE-297/InsecureJavaMailTest.expected | 2 -- .../CleartextStorageAndroidDatabaseTest.expected | 2 -- .../CleartextStorageAndroidFilesystemTest.expected | 2 -- .../CleartextStorage/CleartextStorageSharedPrefsTest.expected | 2 -- .../security/CWE-326/InsufficientKeySizeTest.expected | 2 -- .../security/CWE-330/InsecureRandomnessTest.expected | 2 -- .../security/CWE-347/MissingJWTSignatureCheckTest.expected | 2 -- .../security/CWE-352/SpringCsrfProtectionTest.expected | 2 -- .../CWE-470/FragmentInjectionInPreferenceActivityTest.expected | 2 -- .../DebuggableAttributeEnabledTest.expected | 2 -- .../query-tests/security/CWE-502/UnsafeDeserialization.expected | 2 -- .../query-tests/security/CWE-522/InsecureBasicAuthTest.expected | 2 -- .../query-tests/security/CWE-522/InsecureLdapAuthTest.expected | 2 -- .../security/CWE-524/SensitiveKeyboardCache.expected | 2 -- .../query-tests/security/CWE-643/XPathInjectionTest.expected | 2 -- .../test/query-tests/security/CWE-730/PolynomialReDoS.expected | 2 -- java/ql/test/query-tests/security/CWE-730/ReDoS.expected | 2 -- .../query-tests/security/CWE-730/RegexInjectionTest.expected | 2 -- .../security/CWE-749/UnsafeAndroidAccessTest.expected | 2 -- .../CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected | 2 -- .../semmle/tests/HardcodedCredentialsComparison.expected | 2 -- .../semmle/tests/HardcodedCredentialsSourceCall.expected | 2 -- .../CWE-798/semmle/tests/HardcodedPasswordField.expected | 2 -- .../CWE-807/semmle/tests/ConditionalBypassTest.expected | 2 -- .../query-tests/security/CWE-917/OgnlInjectionTest.expected | 2 -- .../test/query-tests/security/CWE-918/RequestForgery.expected | 2 -- .../security/CWE-925/ImproperIntentVerification.expected | 2 -- .../CWE-926/ImplicitlyExportedAndroidComponentTest.expected | 2 -- .../ContentProviderIncompletePermissionsTest.expected | 2 -- .../security/CWE-927/ImplicitPendingIntentsTest.expected | 2 -- .../security/CWE-927/SensitiveResultReceiver.expected | 2 -- 74 files changed, 148 deletions(-) diff --git a/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.expected b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.expected +++ b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected b/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected b/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected +++ b/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/dataflow/flowfeature/flow.expected b/java/ql/test/library-tests/dataflow/flowfeature/flow.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/test/library-tests/dataflow/flowfeature/flow.expected +++ b/java/ql/test/library-tests/dataflow/flowfeature/flow.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/library-tests/dataflow/state/test.expected b/java/ql/test/library-tests/dataflow/state/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/dataflow/state/test.expected +++ b/java/ql/test/library-tests/dataflow/state/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/dataflow/taintsources/local.expected b/java/ql/test/library-tests/dataflow/taintsources/local.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/local.expected +++ b/java/ql/test/library-tests/dataflow/taintsources/local.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/dataflow/taintsources/remote.expected b/java/ql/test/library-tests/dataflow/taintsources/remote.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/remote.expected +++ b/java/ql/test/library-tests/dataflow/taintsources/remote.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/dataflow/taintsources/reversedns.expected b/java/ql/test/library-tests/dataflow/taintsources/reversedns.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/reversedns.expected +++ b/java/ql/test/library-tests/dataflow/taintsources/reversedns.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected b/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected +++ b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected +++ b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected b/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected +++ b/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/jms/FlowTest.expected b/java/ql/test/library-tests/frameworks/jms/FlowTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/jms/FlowTest.expected +++ b/java/ql/test/library-tests/frameworks/jms/FlowTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected b/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected +++ b/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected b/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected +++ b/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected +++ b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/library-tests/xml/XMLTest.expected b/java/ql/test/library-tests/xml/XMLTest.expected index 191aad0a6e2..cbdfca1fc67 100644 --- a/java/ql/test/library-tests/xml/XMLTest.expected +++ b/java/ql/test/library-tests/xml/XMLTest.expected @@ -1,4 +1,2 @@ -testFailures | test.xml:4:5:4:32 | attribute=value | Unexpected result: hasXmlResult | | test.xml:5:29:5:52 | $ hasXmlResult | Missing result: hasXmlResult | -failures diff --git a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected +++ b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected +++ b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveNotification/test.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveNotification/test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveNotification/test.expected +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveNotification/test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected +++ b/java/ql/test/query-tests/security/CWE-200/semmle/tests/SensitiveTextView/test.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected +++ b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test1/InsecureKeys.expected b/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test1/InsecureKeys.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test1/InsecureKeys.expected +++ b/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test1/InsecureKeys.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test2/InsecureKeys.expected b/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test2/InsecureKeys.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test2/InsecureKeys.expected +++ b/java/ql/test/query-tests/security/CWE-287/InsecureKeys/Test2/InsecureKeys.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/query-tests/security/CWE-287/InsecureLocalAuth/InsecureLocalAuth.expected b/java/ql/test/query-tests/security/CWE-287/InsecureLocalAuth/InsecureLocalAuth.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-287/InsecureLocalAuth/InsecureLocalAuth.expected +++ b/java/ql/test/query-tests/security/CWE-287/InsecureLocalAuth/InsecureLocalAuth.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected b/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected +++ b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected +++ b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected +++ b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-330/InsecureRandomnessTest.expected b/java/ql/test/query-tests/security/CWE-330/InsecureRandomnessTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-330/InsecureRandomnessTest.expected +++ b/java/ql/test/query-tests/security/CWE-330/InsecureRandomnessTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected +++ b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-352/SpringCsrfProtectionTest.expected b/java/ql/test/query-tests/security/CWE-352/SpringCsrfProtectionTest.expected index a74f2c23cda..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-352/SpringCsrfProtectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-352/SpringCsrfProtectionTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected +++ b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected b/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected +++ b/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected +++ b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected +++ b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected +++ b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected b/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected +++ b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-730/ReDoS.expected b/java/ql/test/query-tests/security/CWE-730/ReDoS.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-730/ReDoS.expected +++ b/java/ql/test/query-tests/security/CWE-730/ReDoS.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected +++ b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected +++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected b/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected +++ b/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected b/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected +++ b/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected @@ -1,2 +0,0 @@ -failures -testFailures diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected index 8ec8033d086..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures diff --git a/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected b/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected index 48de9172b36..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected +++ b/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected @@ -1,2 +0,0 @@ -failures -testFailures From 3d8493757e6e4956b3843c6b720dd95d46c3cefa Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 3 Dec 2024 17:01:05 +0100 Subject: [PATCH 55/63] JS: Update expected test results --- .../test/library-tests/EndpointNaming/EndpointNaming.expected | 1 - .../library-tests/threat-models/sources/TestSources.expected | 2 -- 2 files changed, 3 deletions(-) diff --git a/javascript/ql/test/library-tests/EndpointNaming/EndpointNaming.expected b/javascript/ql/test/library-tests/EndpointNaming/EndpointNaming.expected index af5e8d62bb3..d2c34c887cc 100644 --- a/javascript/ql/test/library-tests/EndpointNaming/EndpointNaming.expected +++ b/javascript/ql/test/library-tests/EndpointNaming/EndpointNaming.expected @@ -5,4 +5,3 @@ ambiguousPreferredPredecessor | pack2/main.js:1:1:3:1 | def moduleImport("pack2").getMember("exports").getMember("MainClass").getInstance() | ambiguousSinkName ambiguousFunctionName -failures diff --git a/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected b/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected index 8ec8033d086..e69de29bb2d 100644 --- a/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected +++ b/javascript/ql/test/library-tests/threat-models/sources/TestSources.expected @@ -1,2 +0,0 @@ -testFailures -failures From cca27e4c772f579a2554ddefbed238ed6dec9788 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 15:29:49 +0100 Subject: [PATCH 56/63] Add change notes for all languages. --- .../2024-12-03-remove-dataflow-config-class-api.md | 4 ++++ .../2024-12-03-remove-dataflow-config-class-api.md | 4 ++++ .../2024-12-03-remove-dataflow-config-class-api.md | 4 ++++ .../2024-12-03-remove-dataflow-config-class-api.md | 4 ++++ .../2024-12-03-remove-dataflow-config-class-api.md | 4 ++++ .../2024-12-03-remove-dataflow-config-class-api.md | 4 ++++ .../2024-12-03-remove-dataflow-config-class-api.md | 4 ++++ 7 files changed, 28 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md create mode 100644 csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md create mode 100644 go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md create mode 100644 java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md create mode 100644 python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md create mode 100644 ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md create mode 100644 swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md diff --git a/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 00000000000..d09ec528c99 --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 00000000000..d09ec528c99 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 00000000000..d09ec528c99 --- /dev/null +++ b/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 00000000000..d09ec528c99 --- /dev/null +++ b/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 00000000000..d09ec528c99 --- /dev/null +++ b/python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 00000000000..d09ec528c99 --- /dev/null +++ b/ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 00000000000..d09ec528c99 --- /dev/null +++ b/swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. From a66de28d8e107e2e2c1b7db01ce2a3686a9e2bab Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 15:34:45 +0100 Subject: [PATCH 57/63] C++: Remove references to the deleted api. --- .../code/cpp/dataflow/RecursionPrevention.qll | 39 ------------------- .../src/Security/CWE/CWE-078/ExecTainted.ql | 1 - 2 files changed, 40 deletions(-) delete mode 100644 cpp/ql/lib/semmle/code/cpp/dataflow/RecursionPrevention.qll diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/RecursionPrevention.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/RecursionPrevention.qll deleted file mode 100644 index 2d8b52f8622..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/RecursionPrevention.qll +++ /dev/null @@ -1,39 +0,0 @@ -/** - * DEPRECATED: Recursion through `DataFlow::Configuration` is impossible in - * any supported tooling. There is no need for this module because it's - * impossible to accidentally depend on recursion through - * `DataFlow::Configuration` in current releases. - * - * When this module is imported, recursive use of `DataFlow::Configuration` is - * disallowed. Importing this module will guarantee the absence of such - * recursion, which is unsupported and will be unconditionally disallowed in a - * future release. - * - * Recursive use of `DataFlow{2..4}::Configuration` is always disallowed, so no - * import is needed for those. - */ - -import cpp -private import semmle.code.cpp.dataflow.DataFlow - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - * Four copies are available: `DataFlow` through `DataFlow4`. - */ -abstract private class ConfigurationRecursionPrevention extends DataFlow::Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - strictcount(DataFlow::Node n | this.isSource(n)) < 0 - or - strictcount(DataFlow::Node n | this.isSink(n)) < 0 - or - strictcount(DataFlow::Node n1, DataFlow::Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index 0686c4a707c..f6dd3b6f212 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -19,7 +19,6 @@ import semmle.code.cpp.security.Security import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.ir.dataflow.TaintTracking2 import semmle.code.cpp.security.FlowSources import semmle.code.cpp.models.implementations.Strcat import ExecTaint::PathGraph From dbb260dfd2da8c3c96aad19d7499cb1a5d9bf2a9 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 15:41:51 +0100 Subject: [PATCH 58/63] C#: Remove reference to the deleted api. --- .../Cryptography/NonCryptographicHashes.qll | 1 - .../semmle/code/csharp/frameworks/Format.qll | 1 - .../lib/semmle/code/csharp/frameworks/Sql.qll | 1 - .../code/csharp/frameworks/system/Xml.qll | 1 - .../csharp/security/dataflow/ReDoSQuery.qll | 1 - .../dataflow/UnsafeDeserializationQuery.qll | 1 - .../csharp/security/dataflow/XSSQuery.qll | 2 - .../csharp/security/xml/InsecureXMLQuery.qll | 2 - .../dataflow/flowsources/AuthCookie.qll | 55 ------------------- 9 files changed, 65 deletions(-) diff --git a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll index 0f22f772620..49dd011658d 100644 --- a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll +++ b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll @@ -8,7 +8,6 @@ import csharp private import DataFlow -private import semmle.code.csharp.dataflow.TaintTracking2 predicate maybeANonCryptographicHash( Callable callable, Variable v, Expr xor, Expr mul, LoopStmt loop diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index f0666b921b2..6cef58990b0 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -5,7 +5,6 @@ import csharp private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.Text -private import semmle.code.csharp.dataflow.DataFlow2 /** A method that formats a string, for example `string.Format()`. */ class FormatMethod extends Method { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll index b3b85299c69..75f72352deb 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll @@ -6,7 +6,6 @@ private import semmle.code.csharp.frameworks.system.data.SqlClient private import semmle.code.csharp.frameworks.EntityFramework private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.Dapper -private import semmle.code.csharp.dataflow.DataFlow4 /** An expression containing a SQL command. */ abstract class SqlExpr extends Expr { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll index 0644e75c3df..c0edf9e110e 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.DataFlow3 /** The `System.Xml` namespace. */ class SystemXmlNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll index 5addc03bd88..94dbf1d4cdc 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll @@ -4,7 +4,6 @@ */ import csharp -private import semmle.code.csharp.dataflow.DataFlow2 private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.text.RegularExpressions diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll index 009e1ab73c1..5d9d18dcbac 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll @@ -5,7 +5,6 @@ import csharp private import semmle.code.csharp.serialization.Deserializers -private import semmle.code.csharp.dataflow.TaintTracking2 private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll index 81029cc6572..2d687b51d67 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll @@ -7,8 +7,6 @@ import csharp private import XSSSinks private import semmle.code.csharp.security.Sanitizers private import semmle.code.csharp.security.dataflow.flowsources.FlowSources -private import semmle.code.csharp.dataflow.DataFlow2 -private import semmle.code.csharp.dataflow.TaintTracking2 /** * Holds if there is tainted flow from `source` to `sink` that may lead to a diff --git a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll index ba98888fa6f..1abeaf797b0 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll @@ -150,8 +150,6 @@ module XmlSettings { /** Provides predicates related to `System.Xml.XmlReader`. */ module XmlReader { - private import semmle.code.csharp.dataflow.DataFlow2 - private class InsecureXmlReaderCreate extends InsecureXmlProcessing, MethodCall { InsecureXmlReaderCreate() { this.getTarget().hasFullyQualifiedName("System.Xml.XmlReader", "Create") diff --git a/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll b/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll index 928cf3bdc4f..401944adcc4 100644 --- a/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll +++ b/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll @@ -114,61 +114,6 @@ Expr getAValueForProp(ObjectCreation create, Assignment a, string prop) { */ predicate isPropertySet(ObjectCreation oc, string prop) { exists(getAValueForProp(oc, _, prop)) } -/** - * Tracks if a callback used in `OnAppendCookie` sets a cookie property to `true`. - */ -abstract deprecated private class OnAppendCookieTrackingConfig extends DataFlow::Configuration { - bindingset[this] - OnAppendCookieTrackingConfig() { any() } - - /** - * Specifies the cookie property name to track. - */ - abstract string propertyName(); - - override predicate isSource(DataFlow::Node source) { - exists(PropertyWrite pw, Assignment delegateAssign, Callable c | - pw.getProperty().getName() = "OnAppendCookie" and - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreBuilderCookiePolicyOptions and - delegateAssign.getLValue() = pw and - ( - exists(LambdaExpr lambda | - delegateAssign.getRValue() = lambda and - lambda = c - ) - or - exists(DelegateCreation delegate | - delegateAssign.getRValue() = delegate and - delegate.getArgument().(CallableAccess).getTarget() = c - ) - ) and - c.getParameter(0) = source.asParameter() - ) - } - - override predicate isSink(DataFlow::Node sink) { - exists(PropertyWrite pw, Assignment a | - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieOptions and - pw.getProperty().getName() = this.propertyName() and - a.getLValue() = pw and - exists(Expr val | - DataFlow::localExprFlow(val, a.getRValue()) and - val.getValue() = "true" - ) and - sink.asExpr() = pw.getQualifier() - ) - } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - node2.asExpr() = - any(PropertyRead pr | - pr.getQualifier() = node1.asExpr() and - pr.getProperty().getDeclaringType() instanceof - MicrosoftAspNetCoreCookiePolicyAppendCookieContext - ) - } -} - private signature string propertyName(); /** From e846855bcad906665593ef954419b179eacd68b2 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 15:53:57 +0100 Subject: [PATCH 59/63] Go: Remove deprecated configuration classes referencing deleted api. --- go/ql/lib/go.qll | 2 - .../semmle/go/security/CleartextLogging.qll | 43 ----- .../IncorrectIntegerConversionLib.qll | 126 ------------ .../semmle/go/security/InsecureRandomness.qll | 19 -- .../semmle/go/security/OpenUrlRedirect.qll | 45 ----- go/ql/lib/semmle/go/security/ReflectedXss.qll | 18 -- .../lib/semmle/go/security/RequestForgery.qll | 30 --- go/ql/lib/semmle/go/security/SafeUrlFlow.qll | 29 --- go/ql/lib/semmle/go/security/SqlInjection.qll | 22 --- .../lib/semmle/go/security/StoredCommand.qll | 22 --- go/ql/lib/semmle/go/security/StoredXss.qll | 18 -- go/ql/lib/semmle/go/security/StringBreak.qll | 21 -- go/ql/lib/semmle/go/security/TaintedPath.qll | 18 -- .../semmle/go/security/UnsafeUnzipSymlink.qll | 40 ---- .../lib/semmle/go/security/XPathInjection.qll | 18 -- go/ql/lib/semmle/go/security/ZipSlip.qll | 18 -- go/ql/src/Security/CWE-640/EmailInjection.qll | 13 -- .../experimental/CWE-090/LDAPInjection.qll | 16 -- .../src/experimental/CWE-1004/AuthCookie.qll | 180 ------------------ .../WeakCryptoAlgorithmCustomizations.qll | 18 -- .../CWE-74/DsnInjectionCustomizations.qll | 22 --- .../CWE-807/SensitiveConditionBypass.qll | 27 --- go/ql/src/experimental/CWE-918/SSRF.qll | 30 --- 23 files changed, 795 deletions(-) diff --git a/go/ql/lib/go.qll b/go/ql/lib/go.qll index fb59790dcc5..8d3955e4dad 100644 --- a/go/ql/lib/go.qll +++ b/go/ql/lib/go.qll @@ -25,11 +25,9 @@ import semmle.go.controlflow.BasicBlocks import semmle.go.controlflow.ControlFlowGraph import semmle.go.controlflow.IR import semmle.go.dataflow.DataFlow -import semmle.go.dataflow.DataFlow2 import semmle.go.dataflow.GlobalValueNumbering import semmle.go.dataflow.SSA import semmle.go.dataflow.TaintTracking -import semmle.go.dataflow.TaintTracking2 import semmle.go.frameworks.Afero import semmle.go.frameworks.AwsLambda import semmle.go.frameworks.Beego diff --git a/go/ql/lib/semmle/go/security/CleartextLogging.qll b/go/ql/lib/semmle/go/security/CleartextLogging.qll index 7c29f0ba130..2e0c9665c4b 100644 --- a/go/ql/lib/semmle/go/security/CleartextLogging.qll +++ b/go/ql/lib/semmle/go/security/CleartextLogging.qll @@ -16,49 +16,6 @@ import go module CleartextLogging { import CleartextLoggingCustomizations::CleartextLogging - /** - * DEPRECATED: Use `Flow` instead. - * - * A data-flow tracking configuration for clear-text logging of sensitive information. - * - * This configuration identifies flows from `Source`s, which are sources of - * sensitive data, to `Sink`s, which is an abstract class representing all - * the places sensitive data may be stored in cleartext. Additional sources or sinks can be - * added either by extending the relevant class, or by subclassing this configuration itself, - * and amending the sources and sinks. - */ - deprecated class Configuration extends DataFlow::Configuration { - Configuration() { this = "CleartextLogging" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isBarrier(DataFlow::Node node) { - node instanceof Barrier - or - exists(DataFlow::CallNode call | node = call.getResult() | - call.getTarget() = Builtin::error().getType().getMethod("Error") - or - call.getTarget().(Method).hasQualifiedName("fmt", "Stringer", "String") - ) - } - - override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { - // A taint propagating data-flow edge through structs: a tainted write taints the entire struct. - exists(Write write | - write.writesField(trg.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, src) - ) - or - // taint steps that do not include flow through fields. Field reads would produce FPs due to - // the additional taint step above that taints whole structs from individual field writes. - TaintTracking::localTaintStep(src, trg) and - not TaintTracking::fieldReadStep(src, trg) and - // Also exclude protobuf field fetches, since they amount to single field reads. - not any(Protobuf::GetMethod gm).taintStep(src, trg) - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll index 68d874768ce..3c6cddc427f 100644 --- a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll +++ b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll @@ -53,132 +53,6 @@ int getIntTypeBitSize(File file, int architectureSpecificBitSize) { result = architectureSpecificBitSize } -/** - * Holds if converting from an integer types with size `sourceBitSize` to - * one with size `sinkBitSize` can produce unexpected values, where 0 means - * architecture-dependent. - * - * Architecture-dependent bit sizes can be 32 or 64. To catch flows that - * only manifest on 64-bit architectures we consider an - * architecture-dependent source bit size to be 64. To catch flows that - * only happen on 32-bit architectures we consider an - * architecture-dependent sink bit size to be 32. We exclude the case where - * both source and sink have architecture-dependent bit sizes. - */ -private predicate isIncorrectIntegerConversion(int sourceBitSize, int sinkBitSize) { - sourceBitSize in [16, 32, 64] and - sinkBitSize in [8, 16, 32] and - sourceBitSize > sinkBitSize - or - // Treat `sourceBitSize = 0` like `sourceBitSize = 64`, and exclude `sinkBitSize = 0` - sourceBitSize = 0 and - sinkBitSize in [8, 16, 32] - or - // Treat `sinkBitSize = 0` like `sinkBitSize = 32`, and exclude `sourceBitSize = 0` - sourceBitSize = 64 and - sinkBitSize = 0 -} - -/** - * DEPRECATED: use `Flow` instead. - * - * A taint-tracking configuration for reasoning about when an integer - * obtained from parsing a string flows to a type conversion to a smaller - * integer types, which could cause unexpected values. - */ -deprecated class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { - boolean sinkIsSigned; - int sourceBitSize; - int sinkBitSize; - - ConversionWithoutBoundsCheckConfig() { - sinkIsSigned in [true, false] and - isIncorrectIntegerConversion(sourceBitSize, sinkBitSize) and - this = "ConversionWithoutBoundsCheckConfig" + sourceBitSize + sinkIsSigned + sinkBitSize - } - - /** Gets the bit size of the source. */ - int getSourceBitSize() { result = sourceBitSize } - - override predicate isSource(DataFlow::Node source) { - exists( - DataFlow::CallNode c, IntegerParser::Range ip, int apparentBitSize, int effectiveBitSize - | - c.getTarget() = ip and source = c.getResult(0) - | - ( - apparentBitSize = ip.getTargetBitSize() - or - // If we are reading a variable, check if it is - // `strconv.IntSize`, and use 0 if it is. - exists(DataFlow::Node rawBitSize | rawBitSize = ip.getTargetBitSizeInput().getNode(c) | - if rawBitSize = any(Strconv::IntSize intSize).getARead() - then apparentBitSize = 0 - else apparentBitSize = rawBitSize.getIntValue() - ) - ) and - ( - if apparentBitSize = 0 - then effectiveBitSize = getIntTypeBitSize(source.getFile(), 0) - else effectiveBitSize = apparentBitSize - ) and - // `effectiveBitSize` could be any value between 0 and 64, but we - // can round it up to the nearest size of an integer type without - // changing behavior. - sourceBitSize = min(int b | b in [0, 8, 16, 32, 64] and b >= effectiveBitSize) - ) - } - - /** - * Holds if `sink` is a typecast to an integer type with size `bitSize` (where - * 0 represents architecture-dependent) and the expression being typecast is - * not also in a right-shift expression. We allow this case because it is - * a common pattern to serialise `byte(v)`, `byte(v >> 8)`, and so on. - */ - predicate isSinkWithBitSize(DataFlow::TypeCastNode sink, int bitSize) { - sink.asExpr() instanceof ConversionExpr and - exists(IntegerType integerType | sink.getResultType().getUnderlyingType() = integerType | - ( - bitSize = integerType.getSize() - or - not exists(integerType.getSize()) and - bitSize = getIntTypeBitSize(sink.getFile(), 0) - ) and - if integerType instanceof SignedIntegerType then sinkIsSigned = true else sinkIsSigned = false - ) and - not exists(ShrExpr shrExpr | - shrExpr.getLeftOperand().getGlobalValueNumber() = - sink.getOperand().asExpr().getGlobalValueNumber() or - shrExpr.getLeftOperand().(AndExpr).getAnOperand().getGlobalValueNumber() = - sink.getOperand().asExpr().getGlobalValueNumber() - ) - } - - override predicate isSink(DataFlow::Node sink) { - // We use the argument of the type conversion as the configuration sink so that we - // can sanitize the result of the conversion to prevent flow on to further sinks - // without needing to use `isSanitizerOut`, which doesn't work with flow states - // (and therefore the legacy `TaintTracking::Configuration` class). - this.isSinkWithBitSize(sink.getASuccessor(), sinkBitSize) - } - - override predicate isSanitizer(DataFlow::Node node) { - // To catch flows that only happen on 32-bit architectures we - // consider an architecture-dependent sink bit size to be 32. - exists(UpperBoundCheckGuard g, int bitSize | - if sinkBitSize != 0 then bitSize = sinkBitSize else bitSize = 32 - | - node = DataFlow::BarrierGuard::getABarrierNodeForGuard(g) and - if sinkIsSigned = true then g.isBoundFor(bitSize, 32) else g.isBoundFor(bitSize - 1, 32) - ) - or - exists(int bitSize | - isIncorrectIntegerConversion(sourceBitSize, bitSize) and - this.isSinkWithBitSize(node, bitSize) - ) - } -} - private int validBitSize() { result = [7, 8, 15, 16, 31, 32, 63, 64] } private newtype TArchitectureBitSize = diff --git a/go/ql/lib/semmle/go/security/InsecureRandomness.qll b/go/ql/lib/semmle/go/security/InsecureRandomness.qll index 675f0b4b9a2..83746f7b96e 100644 --- a/go/ql/lib/semmle/go/security/InsecureRandomness.qll +++ b/go/ql/lib/semmle/go/security/InsecureRandomness.qll @@ -16,25 +16,6 @@ import go module InsecureRandomness { import InsecureRandomnessCustomizations::InsecureRandomness - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about random values that are - * not cryptographically secure. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "InsecureRandomness" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { this.isSinkWithKind(sink, _) } - - /** Holds if `sink` is a sink for this configuration with kind `kind`. */ - predicate isSinkWithKind(Sink sink, string kind) { kind = sink.getKind() } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - } - /** Holds if `sink` is a sink for this configuration with kind `kind`. */ predicate isSinkWithKind(Sink sink, string kind) { kind = sink.getKind() } diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll index d3576f005b9..bfe47f260cd 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll @@ -17,51 +17,6 @@ import UrlConcatenation module OpenUrlRedirect { import OpenUrlRedirectCustomizations::OpenUrlRedirect - /** - * DEPRECATED: Use `Flow` instead. - * - * A data-flow configuration for reasoning about unvalidated URL redirections. - */ - deprecated class Configuration extends DataFlow::Configuration { - Configuration() { this = "OpenUrlRedirect" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isBarrier(DataFlow::Node node) { node instanceof Barrier } - - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - // taint steps that do not include flow through fields - TaintTracking::localTaintStep(pred, succ) and not TaintTracking::fieldReadStep(pred, succ) - or - // explicit extra taint steps for this query - any(AdditionalStep s).hasTaintStep(pred, succ) - or - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - or - // propagate out of most URL fields, but not `ForceQuery` and `Scheme` - exists(Field f, string fn | - f.hasQualifiedName("net/url", "URL", fn) and - not fn in ["ForceQuery", "Scheme"] - | - succ.(Read).readsField(pred, f) - ) - } - - override predicate isBarrierOut(DataFlow::Node node) { - // block propagation of this unsafe value when its host is overwritten - exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(node.getASuccessor(), f, _) - ) - or - hostnameSanitizingPrefixEdge(node, _) - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/ReflectedXss.qll b/go/ql/lib/semmle/go/security/ReflectedXss.qll index a605d78633d..1068c6fae3d 100644 --- a/go/ql/lib/semmle/go/security/ReflectedXss.qll +++ b/go/ql/lib/semmle/go/security/ReflectedXss.qll @@ -16,24 +16,6 @@ import go module ReflectedXss { import ReflectedXssCustomizations::ReflectedXss - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about XSS. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ReflectedXss" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/RequestForgery.qll b/go/ql/lib/semmle/go/security/RequestForgery.qll index 5f7139a1b44..bdf26a1f18f 100644 --- a/go/ql/lib/semmle/go/security/RequestForgery.qll +++ b/go/ql/lib/semmle/go/security/RequestForgery.qll @@ -16,36 +16,6 @@ import go module RequestForgery { import RequestForgeryCustomizations::RequestForgery - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about request forgery. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - - override predicate isSanitizerOut(DataFlow::Node node) { - super.isSanitizerOut(node) or - node instanceof SanitizerEdge - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll index f4d1a535bad..d74e2156a60 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll @@ -16,35 +16,6 @@ import go module SafeUrlFlow { import SafeUrlFlowCustomizations::SafeUrlFlow - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about safe URLs. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SafeUrlFlow" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - } - - override predicate isSanitizerOut(DataFlow::Node node) { - // block propagation of this safe value when its host is overwritten - exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(node.getASuccessor(), f, _) - ) - or - node instanceof SanitizerEdge - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/SqlInjection.qll b/go/ql/lib/semmle/go/security/SqlInjection.qll index 366a05cf3df..e24b30f40d3 100644 --- a/go/ql/lib/semmle/go/security/SqlInjection.qll +++ b/go/ql/lib/semmle/go/security/SqlInjection.qll @@ -13,28 +13,6 @@ import go module SqlInjection { import SqlInjectionCustomizations::SqlInjection - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about SQL-injection vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - NoSql::isAdditionalMongoTaintStep(pred, succ) - } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/StoredCommand.qll b/go/ql/lib/semmle/go/security/StoredCommand.qll index 4c21a292371..38555370cfc 100644 --- a/go/ql/lib/semmle/go/security/StoredCommand.qll +++ b/go/ql/lib/semmle/go/security/StoredCommand.qll @@ -16,28 +16,6 @@ import CommandInjectionCustomizations * injection vulnerabilities. */ module StoredCommand { - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about command-injection vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StoredCommand" } - - override predicate isSource(DataFlow::Node source) { - source instanceof StoredXss::Source and - // exclude file names, since those are not generally an issue - not source instanceof StoredXss::FileNameSource - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjection::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof CommandInjection::Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof StoredXss::Source and diff --git a/go/ql/lib/semmle/go/security/StoredXss.qll b/go/ql/lib/semmle/go/security/StoredXss.qll index 37e4b048910..2bf6bf24804 100644 --- a/go/ql/lib/semmle/go/security/StoredXss.qll +++ b/go/ql/lib/semmle/go/security/StoredXss.qll @@ -16,24 +16,6 @@ import go module StoredXss { import StoredXssCustomizations::StoredXss - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about XSS. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StoredXss" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/StringBreak.qll b/go/ql/lib/semmle/go/security/StringBreak.qll index fed3b9b1443..02b4c5b3313 100644 --- a/go/ql/lib/semmle/go/security/StringBreak.qll +++ b/go/ql/lib/semmle/go/security/StringBreak.qll @@ -13,27 +13,6 @@ import go module StringBreak { import StringBreakCustomizations::StringBreak - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about unsafe-quoting vulnerabilities, - * parameterized with the type of quote being tracked. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Quote quote; - - Configuration() { this = "StringBreak" + quote } - - /** Gets the type of quote being tracked by this configuration. */ - Quote getQuote() { result = quote } - - override predicate isSource(DataFlow::Node nd) { nd instanceof Source } - - override predicate isSink(DataFlow::Node nd) { quote = nd.(Sink).getQuote() } - - override predicate isSanitizer(DataFlow::Node nd) { quote = nd.(Sanitizer).getQuote() } - } - private module Config implements DataFlow::StateConfigSig { /** The flow state that we track is the type of quote used. */ class FlowState = Quote; diff --git a/go/ql/lib/semmle/go/security/TaintedPath.qll b/go/ql/lib/semmle/go/security/TaintedPath.qll index 26009554c24..674cda1157c 100644 --- a/go/ql/lib/semmle/go/security/TaintedPath.qll +++ b/go/ql/lib/semmle/go/security/TaintedPath.qll @@ -11,24 +11,6 @@ import go module TaintedPath { import TaintedPathCustomizations::TaintedPath - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about path-traversal vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TaintedPath" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll index 2b969ffc4d9..1d18ac5f639 100644 --- a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll +++ b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll @@ -13,24 +13,6 @@ import go module UnsafeUnzipSymlink { import UnsafeUnzipSymlinkCustomizations::UnsafeUnzipSymlink - /** - * DEPRECATED: Use copies of `EvalSymlinksConfig` and `EvalSymlinksFlow` instead. - * - * A taint-flow configuration tracking archive header fields flowing to a `path/filepath.EvalSymlinks` call. - */ - deprecated class EvalSymlinksConfiguration extends TaintTracking2::Configuration { - EvalSymlinksConfiguration() { this = "Archive header field symlinks resolved" } - - override predicate isSource(DataFlow::Node source) { source instanceof FilenameWithSymlinks } - - override predicate isSink(DataFlow::Node sink) { sink instanceof EvalSymlinksSink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof EvalSymlinksInvalidator - } - } - // Archive header field symlinks resolved private module EvalSymlinksConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof FilenameWithSymlinks } @@ -53,28 +35,6 @@ module UnsafeUnzipSymlink { EvalSymlinksFlow::flow(getASimilarReadNode(node), _) } - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-flow configuration tracking archive header fields flowing to an `os.Symlink` call, - * which never flow to a `path/filepath.EvalSymlinks` call. - */ - deprecated class SymlinkConfiguration extends TaintTracking::Configuration { - SymlinkConfiguration() { this = "Unsafe unzipping of symlinks" } - - override predicate isSource(DataFlow::Node source) { - source instanceof FilenameWithSymlinks and - not symlinksEvald(source) - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof SymlinkSink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof SymlinkSanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof FilenameWithSymlinks and diff --git a/go/ql/lib/semmle/go/security/XPathInjection.qll b/go/ql/lib/semmle/go/security/XPathInjection.qll index 2e374dfbf24..61bd00977da 100644 --- a/go/ql/lib/semmle/go/security/XPathInjection.qll +++ b/go/ql/lib/semmle/go/security/XPathInjection.qll @@ -13,24 +13,6 @@ import go module XPathInjection { import XPathInjectionCustomizations::XPathInjection - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about untrusted user input used in an XPath expression. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "XPathInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/ZipSlip.qll b/go/ql/lib/semmle/go/security/ZipSlip.qll index 4a7ba231f0f..f16daf84c3d 100644 --- a/go/ql/lib/semmle/go/security/ZipSlip.qll +++ b/go/ql/lib/semmle/go/security/ZipSlip.qll @@ -11,24 +11,6 @@ import go module ZipSlip { import ZipSlipCustomizations::ZipSlip - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about zip-slip vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ZipSlip" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/Security/CWE-640/EmailInjection.qll b/go/ql/src/Security/CWE-640/EmailInjection.qll index 479fe6dc055..35b7795ad55 100644 --- a/go/ql/src/Security/CWE-640/EmailInjection.qll +++ b/go/ql/src/Security/CWE-640/EmailInjection.qll @@ -16,19 +16,6 @@ import go module EmailInjection { import EmailInjectionCustomizations::EmailInjection - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about email-injection vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Email Injection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/experimental/CWE-090/LDAPInjection.qll b/go/ql/src/experimental/CWE-090/LDAPInjection.qll index 4e0a6e290da..fd138fa0645 100644 --- a/go/ql/src/experimental/CWE-090/LDAPInjection.qll +++ b/go/ql/src/experimental/CWE-090/LDAPInjection.qll @@ -95,22 +95,6 @@ private class LdapClientDNSink extends LdapSink { } } -/** - * DEPRECATED: Use `LdapInjectionFlow` instead. - * - * A taint-tracking configuration for reasoning about when a `ActiveThreatModelSource` - * flows into an argument or field that is vulnerable to LDAP injection. - */ -deprecated class LdapInjectionConfiguration extends TaintTracking::Configuration { - LdapInjectionConfiguration() { this = "Ldap injection" } - - override predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof LdapSink } - - override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer instanceof LdapSanitizer } -} - private module LdapInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } diff --git a/go/ql/src/experimental/CWE-1004/AuthCookie.qll b/go/ql/src/experimental/CWE-1004/AuthCookie.qll index c995a8b2f68..411da5a79fa 100644 --- a/go/ql/src/experimental/CWE-1004/AuthCookie.qll +++ b/go/ql/src/experimental/CWE-1004/AuthCookie.qll @@ -64,28 +64,6 @@ private class SetCookieSink extends DataFlow::Node { } } -/** - * DEPRECATED: Use `NameToNetHttpCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from sensitive names to - * `net/http.SetCookie`. - */ -deprecated class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration { - NameToNetHttpCookieTrackingConfiguration() { this = "NameToNetHttpCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } - - override predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(StructLit sl | - sl.getType() instanceof NetHttpCookieType and - getValueForFieldWrite(sl, "Name") = pred and - sl = succ.asExpr() - ) - } -} - private module NameToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } @@ -103,30 +81,6 @@ private module NameToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig /** Tracks taint flow from sensitive names to `net/http.SetCookie`. */ module NameToNetHttpCookieTrackingFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `BoolToNetHttpCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from `bool` assigned to - * `HttpOnly` that flows into `net/http.SetCookie`. - */ -deprecated class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration { - BoolToNetHttpCookieTrackingConfiguration() { this = "BoolToNetHttpCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { - source.getType().getUnderlyingType() instanceof BoolType - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(StructLit sl | - sl.getType() instanceof NetHttpCookieType and - getValueForFieldWrite(sl, "HttpOnly") = pred and - sl = succ.asExpr() - ) - } -} - private module BoolToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.getType().getUnderlyingType() instanceof BoolType @@ -149,29 +103,6 @@ private module BoolToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig */ module BoolToNetHttpCookieTrackingFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `BoolToGinSetCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from `HttpOnly` set to - * `false` to `gin-gonic/gin.Context.SetCookie`. - */ -deprecated class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration { - BoolToGinSetCookieTrackingConfiguration() { this = "BoolToGinSetCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { source.getBoolValue() = false } - - override predicate isSink(DataFlow::Node sink) { - exists(DataFlow::MethodCallNode mcn | - mcn.getTarget() instanceof GinContextSetCookieMethod and - mcn.getArgument(6) = sink and - exists(NameToGinSetCookieTrackingConfiguration cfg, DataFlow::Node nameArg | - cfg.hasFlowTo(nameArg) and - mcn.getArgument(0) = nameArg - ) - ) - } -} - private module BoolToGinSetCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.getBoolValue() = false } @@ -193,25 +124,6 @@ private module BoolToGinSetCookieTrackingConfig implements DataFlow::ConfigSig { */ module BoolToGinSetCookieTrackingFlow = DataFlow::Global; -/** - * DEPRECATED: Use `NameToGinSetCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from sensitive names to - * `gin-gonic/gin.Context.SetCookie`. - */ -deprecated private class NameToGinSetCookieTrackingConfiguration extends DataFlow2::Configuration { - NameToGinSetCookieTrackingConfiguration() { this = "NameToGinSetCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } - - override predicate isSink(DataFlow::Node sink) { - exists(DataFlow::MethodCallNode mcn | - mcn.getTarget() instanceof GinContextSetCookieMethod and - mcn.getArgument(0) = sink - ) - } -} - private module NameToGinSetCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } @@ -251,39 +163,6 @@ private class GorillaStoreSaveSink extends DataFlow::Node { } } -/** - * DEPRECATED: Use `GorillaCookieStoreSaveTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from gorilla cookie store - * creation to `gorilla/sessions.Session.Save`. - */ -deprecated class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuration { - GorillaCookieStoreSaveTrackingConfiguration() { - this = "GorillaCookieStoreSaveTrackingConfiguration" - } - - override predicate isSource(DataFlow::Node source) { - source - .(DataFlow::CallNode) - .getTarget() - .hasQualifiedName(package("github.com/gorilla/sessions", ""), "NewCookieStore") - } - - override predicate isSink(DataFlow::Node sink) { - sink instanceof GorillaSessionSaveSink or - sink instanceof GorillaStoreSaveSink - } - - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(DataFlow::MethodCallNode cn | - cn.getTarget() - .hasQualifiedName(package("github.com/gorilla/sessions", ""), "CookieStore", "Get") and - pred = cn.getReceiver() and - succ = cn.getResult(0) - ) - } -} - private module GorillaCookieStoreSaveTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source @@ -313,34 +192,6 @@ private module GorillaCookieStoreSaveTrackingConfig implements DataFlow::ConfigS */ module GorillaCookieStoreSaveTrackingFlow = DataFlow::Global; -/** - * DEPRECATED: Use `GorillaSessionOptionsTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from session options to - * `gorilla/sessions.Session.Save`. - */ -deprecated class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration { - GorillaSessionOptionsTrackingConfiguration() { - this = "GorillaSessionOptionsTrackingConfiguration" - } - - override predicate isSource(DataFlow::Node source) { - exists(StructLit sl | - sl.getType().hasQualifiedName(package("github.com/gorilla/sessions", ""), "Options") and - source.asExpr() = sl - ) - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base | - w.writesField(base, f, pred) and - succ = base - ) - } -} - private module GorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { exists(StructLit sl | @@ -366,37 +217,6 @@ private module GorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSi module GorillaSessionOptionsTrackingFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `BoolToGorillaSessionOptionsTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from a `bool` assigned to - * `HttpOnly` to `gorilla/sessions.Session.Save`. - */ -deprecated class BoolToGorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration -{ - BoolToGorillaSessionOptionsTrackingConfiguration() { - this = "BoolToGorillaSessionOptionsTrackingConfiguration" - } - - override predicate isSource(DataFlow::Node source) { - source.getType().getUnderlyingType() instanceof BoolType - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(StructLit sl | - getValueForFieldWrite(sl, "HttpOnly") = pred and - sl = succ.asExpr() - ) - or - exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base | - w.writesField(base, f, pred) and - succ = base - ) - } -} - private module BoolToGorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.getType().getUnderlyingType() instanceof BoolType diff --git a/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll b/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll index 61a55bdd32b..1d64d731f50 100644 --- a/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll +++ b/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll @@ -48,24 +48,6 @@ module WeakCryptoAlgorithm { } } - /** - * DEPRECATED: Use `Flow` instead. - * - * A configuration depicting taint flow from sensitive information to weak cryptographic algorithms. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "WeakCryptoAlgorithm" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll b/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll index 5417ddf4f3e..2c320855072 100644 --- a/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll +++ b/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll @@ -6,28 +6,6 @@ import semmle.go.dataflow.barrierguardutil.RegexpCheck /** A source for `DsnInjection` taint-flow configuration. */ abstract class Source extends DataFlow::Node { } -/** - * DEPRECATED: Use `DsnInjectionFlow` instead. - * - * A taint-tracking configuration to reason about Data Source Name injection vulnerabilities. - */ -deprecated class DsnInjection extends TaintTracking::Configuration { - DsnInjection() { this = "DsnInjection" } - - override predicate isSource(DataFlow::Node node) { node instanceof Source } - - override predicate isSink(DataFlow::Node node) { - exists(DataFlow::CallNode c | - c.getTarget().hasQualifiedName("database/sql", "Open") and - c.getArgument(0).getStringValue() = "mysql" - | - node = c.getArgument(1) - ) - } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof RegexpCheckBarrier } -} - private module DsnInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll b/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll index 0d4bdfb1dd0..2f2ca94fa87 100644 --- a/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll +++ b/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll @@ -42,33 +42,6 @@ private class ConstComparisonExpr extends ComparisonExpr { } } -/** - * DEPRECATED: Use `Flow` instead. - * - * A data-flow configuration for reasoning about - * user-controlled bypassing of sensitive actions. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Condtional Expression Check Bypass" } - - override predicate isSource(DataFlow::Node source) { - source instanceof ActiveThreatModelSource - or - exists(DataFlow::FieldReadNode f | - f.getField().hasQualifiedName("net/http", "Request", "Host") - | - source = f - ) - } - - override predicate isSink(DataFlow::Node sink) { - exists(ConstComparisonExpr c | - c.getAnOperand() = sink.asExpr() and - not c.isPotentialFalsePositive() - ) - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index 42b017ac487..b1374da8a5f 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -15,36 +15,6 @@ module ServerSideRequestForgery { private import semmle.go.dataflow.barrierguardutil.RegexpCheck private import semmle.go.dataflow.Properties - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about request forgery. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SSRF" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - - override predicate isSanitizerOut(DataFlow::Node node) { - super.isSanitizerOut(node) or - node instanceof SanitizerEdge - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } From b12a1c078c6e5d40f1be499ca003adf759b9291a Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 16:04:34 +0100 Subject: [PATCH 60/63] Java: Delete deprecated extension points referencing deleted api. --- .../semmle/code/java/frameworks/JsonIo.qll | 2 - .../AndroidIntentRedirectionQuery.qll | 2 - .../security/CleartextStorageCookieQuery.qll | 1 - .../HardcodedCredentialsSourceCallQuery.qll | 2 - .../java/security/ImplicitPendingIntents.qll | 33 +----------- .../code/java/security/TemplateInjection.qll | 52 +------------------ .../security/UnsafeDeserializationQuery.qll | 1 - .../semmle/code/java/security/XmlParsers.qll | 2 - 8 files changed, 4 insertions(+), 91 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll index d40e7ebf81e..85f3a5ef06b 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll @@ -5,8 +5,6 @@ import java import semmle.code.java.Maps import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow2 -private import semmle.code.java.dataflow.DataFlow2 /** * The class `com.cedarsoftware.util.io.JsonReader`. diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll index 109300458d2..7625f9d7da4 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll @@ -2,9 +2,7 @@ import java import semmle.code.java.dataflow.FlowSources -deprecated import semmle.code.java.dataflow.DataFlow2 import semmle.code.java.dataflow.TaintTracking -deprecated import semmle.code.java.dataflow.TaintTracking3 import semmle.code.java.security.AndroidIntentRedirection /** A taint tracking configuration for tainted Intents being used to start Android components. */ diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index a36a4754584..1f262ad57d6 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -2,7 +2,6 @@ import java import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow3 import semmle.code.java.security.CleartextStorageQuery private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.FlowSources diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll index 2192c5c70de..06d7869ce99 100644 --- a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll @@ -4,8 +4,6 @@ import java import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow2 -private import semmle.code.java.dataflow.DataFlow2 import HardcodedCredentials /** diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index a5d8f256b03..650527e88e4 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -26,24 +26,10 @@ class NoState extends PendingIntentState, TNoState { } /** A source for an implicit `PendingIntent` flow. */ -abstract class ImplicitPendingIntentSource extends ApiSourceNode { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this source has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { state = "" } -} +abstract class ImplicitPendingIntentSource extends ApiSourceNode { } /** A sink that sends an implicit and mutable `PendingIntent` to a third party. */ -abstract class ImplicitPendingIntentSink extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this sink has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { state = "" } -} +abstract class ImplicitPendingIntentSink extends DataFlow::Node { } /** * A unit class for adding additional taint steps. @@ -62,21 +48,6 @@ class ImplicitPendingIntentAdditionalTaintStep extends Unit { * Holds if the step from `node1` to `node2` creates a mutable `PendingIntent`. */ predicate mutablePendingIntentCreation(DataFlow::Node node1, DataFlow::Node node2) { none() } - - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * Use `mutablePendingIntentCreation` instead. - * - * Holds if the step from `node1` to `node2` should be considered a taint - * step for flows related to the use of implicit `PendingIntent`s. This step is only applicable - * in `state1` and updates the flow state to `state2`. - */ - deprecated predicate step( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } } private class IntentCreationSource extends ImplicitPendingIntentSource { diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll index a74f4db8030..0b703780a03 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll @@ -9,30 +9,12 @@ private import semmle.code.java.security.Sanitizers /** * A source for server-side template injection (SST) vulnerabilities. */ -abstract class TemplateInjectionSource extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this source has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { - state instanceof DataFlow::FlowStateEmpty - } -} +abstract class TemplateInjectionSource extends DataFlow::Node { } /** * A sink for server-side template injection (SST) vulnerabilities. */ -abstract class TemplateInjectionSink extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this sink has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { - state instanceof DataFlow::FlowStateEmpty - } -} +abstract class TemplateInjectionSink extends DataFlow::Node { } /** * A unit class for adding additional taint steps. @@ -46,20 +28,6 @@ class TemplateInjectionAdditionalTaintStep extends Unit { * step for flows related to server-side template injection (SST) vulnerabilities. */ predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if the step from `node1` to `node2` should be considered a taint - * step for flows related toserver-side template injection (SST) vulnerabilities. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - deprecated predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } } /** @@ -67,22 +35,6 @@ class TemplateInjectionAdditionalTaintStep extends Unit { */ abstract class TemplateInjectionSanitizer extends DataFlow::Node { } -/** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * A sanitizer for server-side template injection (SST) vulnerabilities. - * This sanitizer is only applicable when `TemplateInjectionSanitizerWithState::hasState` - * holds for the flow state. - */ -abstract deprecated class TemplateInjectionSanitizerWithState extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this sanitizer has the specified `state`. - */ - abstract deprecated predicate hasState(DataFlow::FlowState state); -} - private class DefaultTemplateInjectionSource extends TemplateInjectionSource instanceof ActiveThreatModelSource { } diff --git a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll index 9a627d54c5a..cb76ee37c7b 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll @@ -4,7 +4,6 @@ import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.FlowSinks -private import semmle.code.java.dataflow.TaintTracking2 private import semmle.code.java.dispatch.VirtualDispatch private import semmle.code.java.frameworks.Kryo private import semmle.code.java.frameworks.XStream diff --git a/java/ql/lib/semmle/code/java/security/XmlParsers.qll b/java/ql/lib/semmle/code/java/security/XmlParsers.qll index 4a5b7121e60..fc0b52b6f78 100644 --- a/java/ql/lib/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/lib/semmle/code/java/security/XmlParsers.qll @@ -2,8 +2,6 @@ import java import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow3 -private import semmle.code.java.dataflow.DataFlow3 private import semmle.code.java.dataflow.RangeUtils private module Frameworks { From f38602e9fe99f37e1128208980d7c5b70d3ae85f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 16:07:56 +0100 Subject: [PATCH 61/63] Java: Update references to deleted aliases. --- .../CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll | 8 ++++---- .../Security/CWE/CWE-625/PermissiveDotRegexQuery.qll | 6 +++--- .../semmle/code/java/security/SpringUrlRedirect.qll | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll b/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll index 8e545a5e8f0..5972db67495 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll @@ -95,7 +95,7 @@ private class ProduceCiphertextCall extends ProduceCryptoCall { } /** Holds if `fromNode` to `toNode` is a dataflow step that updates a cryptographic operation. */ -private predicate updateCryptoOperationStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { +private predicate updateCryptoOperationStep(DataFlow::Node fromNode, DataFlow::Node toNode) { exists(MethodCall call, Method m | m = call.getMethod() and call.getQualifier() = toNode.asExpr() and @@ -111,7 +111,7 @@ private predicate updateCryptoOperationStep(DataFlow2::Node fromNode, DataFlow2: } /** Holds if `fromNode` to `toNode` is a dataflow step that creates a hash. */ -private predicate createMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { +private predicate createMessageDigestStep(DataFlow::Node fromNode, DataFlow::Node toNode) { exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType().hasQualifiedName("java.security", "MessageDigest") and m.hasStringSignature("digest()") and @@ -135,7 +135,7 @@ private predicate createMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::N } /** Holds if `fromNode` to `toNode` is a dataflow step that updates a hash. */ -private predicate updateMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { +private predicate updateMessageDigestStep(DataFlow::Node fromNode, DataFlow::Node toNode) { exists(MethodCall ma, Method m | m = ma.getMethod() | m.hasQualifiedName("java.security", "MessageDigest", "update") and ma.getArgument(0) = fromNode.asExpr() and @@ -154,7 +154,7 @@ private module UserInputInCryptoOperationConfig implements DataFlow::ConfigSig { exists(ProduceCryptoCall call | call.getQualifier() = sink.asExpr()) } - predicate isAdditionalFlowStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { updateCryptoOperationStep(fromNode, toNode) or createMessageDigestStep(fromNode, toNode) diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll index 925fd5632a3..5f015732cb3 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll @@ -94,11 +94,11 @@ private class CompileRegexSink extends DataFlow::ExprNode { * A data flow configuration for regular expressions that include permissive dots. */ private module PermissiveDotRegexConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow2::Node src) { src.asExpr() instanceof PermissiveDotStr } + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof PermissiveDotStr } - predicate isSink(DataFlow2::Node sink) { sink instanceof CompileRegexSink } + predicate isSink(DataFlow::Node sink) { sink instanceof CompileRegexSink } - predicate isBarrier(DataFlow2::Node node) { + predicate isBarrier(DataFlow::Node node) { exists( MethodCall ma, Field f // Pattern.compile(PATTERN, Pattern.DOTALL) | diff --git a/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll b/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll index d437c8fa3cc..c068dfbb7e3 100644 --- a/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll +++ b/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll @@ -53,7 +53,7 @@ private class SpringViewUrlRedirectSink extends SpringUrlRedirectSink { ) or exists(MethodCall ma, RedirectAppendCall rac | - DataFlow2::localExprFlow(rac.getQualifier(), ma.getQualifier()) and + DataFlow::localExprFlow(rac.getQualifier(), ma.getQualifier()) and ma.getMethod().hasName("append") and ma.getArgument(0) = this.asExpr() and any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) From 8a5fc97b06ce2ac93d6027c6d72f1e6c19ad862a Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 16:16:55 +0100 Subject: [PATCH 62/63] Python: Remove deprecated configuration classes referencing deleted api. --- .../dataflow/CleartextLoggingQuery.qll | 19 ------- .../dataflow/CleartextStorageQuery.qll | 19 ------- .../security/dataflow/CodeInjectionQuery.qll | 15 ------ .../dataflow/CommandInjectionQuery.qll | 15 ------ .../security/dataflow/LdapInjectionQuery.qll | 32 ------------ .../security/dataflow/LogInjectionQuery.qll | 15 ------ .../dataflow/PamAuthorizationQuery.qll | 29 ----------- .../security/dataflow/PathInjectionQuery.qll | 51 ------------------- .../dataflow/PolynomialReDoSQuery.qll | 15 ------ .../security/dataflow/ReflectedXssQuery.qll | 15 ------ .../security/dataflow/RegexInjectionQuery.qll | 15 ------ .../ServerSideRequestForgeryQuery.qll | 43 ---------------- .../security/dataflow/SqlInjectionQuery.qll | 15 ------ .../dataflow/StackTraceExposureQuery.qll | 24 --------- .../python/security/dataflow/TarSlipQuery.qll | 15 ------ .../dataflow/UnsafeDeserializationQuery.qll | 15 ------ .../UnsafeShellCommandConstructionQuery.qll | 23 --------- .../security/dataflow/UrlRedirectQuery.qll | 28 ---------- .../WeakSensitiveDataHashingQuery.qll | 51 ------------------- .../python/security/dataflow/XmlBombQuery.qll | 18 ------- .../security/dataflow/XpathInjectionQuery.qll | 15 ------ .../python/security/dataflow/XxeQuery.qll | 18 ------- .../CWE-020-ExternalAPIs/ExternalAPIs.qll | 13 ----- .../ModificationOfParameterWithDefault.qll | 31 ----------- .../dataflow/DataflowQueryTest.qll | 12 ----- 25 files changed, 561 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll index 0b0cb046820..03b1db49d17 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll @@ -15,25 +15,6 @@ private import semmle.python.dataflow.new.BarrierGuards private import semmle.python.dataflow.new.SensitiveDataSources import CleartextLoggingCustomizations::CleartextLogging -/** - * DEPRECATED: Use `CleartextLoggingFlow` module instead. - * - * A taint-tracking configuration for detecting "Clear-text logging of sensitive information". - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextLogging" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } -} - private module CleartextLoggingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll index ef9c8c13b56..7ee85230c84 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll @@ -15,25 +15,6 @@ private import semmle.python.dataflow.new.BarrierGuards private import semmle.python.dataflow.new.SensitiveDataSources import CleartextStorageCustomizations::CleartextStorage -/** - * DEPRECATED: Use `CleartextStorageFlow` module instead. - * - * A taint-tracking configuration for detecting "Clear-text storage of sensitive information". - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextStorage" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } -} - private module CleartextStorageConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll index ecb0435fec8..486d06a6b21 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import CodeInjectionCustomizations::CodeInjection -/** - * DEPRECATED: Use `CodeInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "code injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CodeInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module CodeInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll index 8874a12132f..18bcbe8cdd5 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import CommandInjectionCustomizations::CommandInjection -/** - * DEPRECATED: Use `CommandInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "command injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CommandInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - /** * A taint-tracking configuration for detecting "command injection" vulnerabilities. */ diff --git a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll index 9dd24bceddb..527c1cbfe43 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll @@ -13,22 +13,6 @@ import semmle.python.dataflow.new.TaintTracking import semmle.python.dataflow.new.RemoteFlowSources import LdapInjectionCustomizations::LdapInjection -/** - * DEPRECATED: Use `LdapInjectionDnFlow` module instead. - * - * A taint-tracking configuration for detecting LDAP injection vulnerabilities - * via the distinguished name (DN) parameter of an LDAP search. - */ -deprecated class DnConfiguration extends TaintTracking::Configuration { - DnConfiguration() { this = "LdapDnInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof DnSink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof DnSanitizer } -} - private module LdapInjectionDnConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -40,22 +24,6 @@ private module LdapInjectionDnConfig implements DataFlow::ConfigSig { /** Global taint-tracking for detecting "LDAP injection via the distinguished name (DN) parameter" vulnerabilities. */ module LdapInjectionDnFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `LdapInjectionFilterFlow` module instead. - * - * A taint-tracking configuration for detecting LDAP injection vulnerabilities - * via the filter parameter of an LDAP search. - */ -deprecated class FilterConfiguration extends TaintTracking::Configuration { - FilterConfiguration() { this = "LdapFilterInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof FilterSink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof FilterSanitizer } -} - private module LdapInjectionFilterConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll index 780c27bb213..7204accbdcf 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import LogInjectionCustomizations::LogInjection -/** - * DEPRECATED: Use `LogInjectionFlow` module instead. - * - * A taint-tracking configuration for tracking untrusted user input used in log entries. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "LogInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module LogInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll index 4b150299b31..eb83d0bf84f 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll @@ -11,35 +11,6 @@ import semmle.python.ApiGraphs import semmle.python.dataflow.new.TaintTracking import PamAuthorizationCustomizations::PamAuthorizationCustomizations -/** - * DEPRECATED: Use `PamAuthorizationFlow` module instead. - * - * A taint-tracking configuration for detecting "PAM Authorization" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PamAuthorization" } - - override predicate isSource(DataFlow::Node node) { node instanceof Source } - - override predicate isSink(DataFlow::Node node) { node instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - // Models flow from a remotely supplied username field to a PAM `handle`. - // `retval = pam_start(service, username, byref(conv), byref(handle))` - exists(API::CallNode pamStart, DataFlow::Node handle, API::CallNode pointer | - pointer = API::moduleImport("ctypes").getMember(["pointer", "byref"]).getACall() and - pamStart = libPam().getMember("pam_start").getACall() and - pointer = pamStart.getArg(3) and - handle = pointer.getArg(0) and - pamStart.getArg(1) = node1 and - handle = node2 - ) - or - // Flow from handle to the authenticate call in the final step - exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c) - } -} - private module PamAuthorizationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll index 2cd6ba2a6f4..b3081fd9996 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll @@ -12,57 +12,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import PathInjectionCustomizations::PathInjection -/** - * DEPRECATED: Use `PathInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "path injection" vulnerabilities. - * - * This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`, - * to track the requirement that a file path must be first normalized and then checked - * before it is safe to use. - * - * At sources, paths are assumed not normalized. At normalization points, they change - * state to `NormalizedUnchecked` after which they can be made safe by an appropriate - * check of the prefix. - * - * Such checks are ineffective in the `NotNormalized` state. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PathInjection" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source instanceof Source and state instanceof NotNormalized - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - sink instanceof Sink and - ( - state instanceof NotNormalized or - state instanceof NormalizedUnchecked - ) - } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - override predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { - // Block `NotNormalized` paths here, since they change state to `NormalizedUnchecked` - node instanceof Path::PathNormalization and - state instanceof NotNormalized - or - node instanceof Path::SafeAccessCheck and - state instanceof NormalizedUnchecked - } - - override predicate isAdditionalTaintStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - nodeFrom = nodeTo.(Path::PathNormalization).getPathArg() and - stateFrom instanceof NotNormalized and - stateTo instanceof NormalizedUnchecked - } -} - abstract private class NormalizationState extends string { bindingset[this] NormalizationState() { any() } diff --git a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll index 3ca67fff82e..4e082aac26e 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import PolynomialReDoSCustomizations::PolynomialReDoS -/** - * DEPRECATED: Use `PolynomialReDoSFlow` module instead. - * - * A taint-tracking configuration for detecting "polynomial regular expression denial of service (ReDoS)" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PolynomialReDoS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module PolynomialReDoSConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll index d67c5e3cb39..5f5b2dd58df 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import ReflectedXSSCustomizations::ReflectedXss -/** - * DEPRECATED: Use `ReflectedXssFlow` module instead. - * - * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ReflectedXSS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module ReflectedXssConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll index d79b76a8685..ae21270a63e 100644 --- a/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll @@ -12,21 +12,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import RegexInjectionCustomizations::RegexInjection -/** - * DEPRECATED: Use `RegexInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RegexInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module RegexInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll index d0bfa24cf5e..4cae5a301b1 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll @@ -12,31 +12,6 @@ import semmle.python.dataflow.new.TaintTracking import semmle.python.Concepts import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery -/** - * DEPRECATED: Use `FullServerSideRequestForgeryFlow` module instead. - * - * A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities. - * - * This configuration has a sanitizer to limit results to cases where attacker has full control of URL. - * See `PartialServerSideRequestForgery` for a variant without this requirement. - * - * You should use the `fullyControlledRequest` to only select results where all - * URL parts are fully controlled. - */ -deprecated class FullServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { - FullServerSideRequestForgeryConfiguration() { this = "FullServerSideRequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer - or - node instanceof FullUrlControlSanitizer - } -} - /** * This configuration has a sanitizer to limit results to cases where attacker has full control of URL. * See `PartialServerSideRequestForgery` for a variant without this requirement. @@ -73,24 +48,6 @@ predicate fullyControlledRequest(Http::Client::Request request) { ) } -/** - * DEPRECATED: Use `PartialServerSideRequestForgeryFlow` module instead. - * - * A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities. - * - * This configuration has results, even when the attacker does not have full control over the URL. - * See `FullServerSideRequestForgeryConfiguration`, and the `fullyControlledRequest` predicate. - */ -deprecated class PartialServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { - PartialServerSideRequestForgeryConfiguration() { this = "PartialServerSideRequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - /** * This configuration has results, even when the attacker does not have full control over the URL. * See `FullServerSideRequestForgeryConfiguration`, and the `fullyControlledRequest` predicate. diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll index 877e30f5090..a63590643f3 100644 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import SqlInjectionCustomizations::SqlInjection -/** - * DEPRECATED: Use `SqlInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "SQL injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module SqlInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll index 9980aa76ea3..57ef6d7ebb2 100644 --- a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll @@ -11,30 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import StackTraceExposureCustomizations::StackTraceExposure -/** - * DEPRECATED: Use `StackTraceExposureFlow` module instead. - * - * A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StackTraceExposure" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - // A stack trace is accessible as the `__traceback__` attribute of a caught exception. - // see https://docs.python.org/3/reference/datamodel.html#traceback-objects - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::AttrRead attr | attr.getAttributeName() = "__traceback__" | - nodeFrom = attr.getObject() and - nodeTo = attr - ) - } -} - private module StackTraceExposureConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll index 7bb008f1afb..162bfcd74cc 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import TarSlipCustomizations::TarSlip -/** - * DEPRECATED: Use `TarSlipFlow` module instead. - * - * A taint-tracking configuration for detecting "tar slip" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TarSlip" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module TarSlipConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll index bd067213fb5..dd6925b7998 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import UnsafeDeserializationCustomizations::UnsafeDeserialization -/** - * DEPRECATED: Use `UnsafeDeserializationFlow` module instead. - * - * A taint-tracking configuration for detecting "code execution from deserialization" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeDeserialization" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module UnsafeDeserializationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll index 6d292a88b6c..51341cfe6cd 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll @@ -13,29 +13,6 @@ private import semmle.python.dataflow.new.TaintTracking private import CommandInjectionCustomizations::CommandInjection as CommandInjection private import semmle.python.dataflow.new.BarrierGuards -/** - * DEPRECATED: Use `UnsafeShellCommandConstructionFlow` module instead. - * - * A taint-tracking configuration for detecting shell command constructed from library input vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeShellCommandConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer or - node instanceof CommandInjection::Sanitizer // using all sanitizers from `py/command-injection` - } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - /** * A taint-tracking configuration for detecting "shell command constructed from library input" vulnerabilities. */ diff --git a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll index 5b44cd988ad..a9526f33ad3 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll @@ -11,34 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import UrlRedirectCustomizations::UrlRedirect as UrlRedirect -/** - * DEPRECATED: Use `UrlRedirectFlow` module instead. - * - * A taint-tracking configuration for detecting "URL redirection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UrlRedirect" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source instanceof UrlRedirect::Source and state instanceof UrlRedirect::MayContainBackslashes - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - sink instanceof UrlRedirect::Sink and state instanceof UrlRedirect::FlowState - } - - override predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { - node.(UrlRedirect::Sanitizer).sanitizes(state) - } - - override predicate isAdditionalTaintStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - any(UrlRedirect::AdditionalFlowStep a).step(nodeFrom, stateFrom, nodeTo, stateTo) - } -} - private module UrlRedirectConfig implements DataFlow::StateConfigSig { class FlowState = UrlRedirect::FlowState; diff --git a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll index 9e2803b3369..04d8846d7d0 100644 --- a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll @@ -23,30 +23,6 @@ private import semmle.python.dataflow.new.SensitiveDataSources module NormalHashFunction { import WeakSensitiveDataHashingCustomizations::NormalHashFunction - /** - * DEPRECATED: Use `Flow` module instead. - * - * A taint-tracking configuration for detecting use of a broken or weak - * cryptographic hashing algorithm on sensitive data. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "NormalHashFunction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - sensitiveDataExtraStepForCalls(node1, node2) - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -73,33 +49,6 @@ module NormalHashFunction { module ComputationallyExpensiveHashFunction { import WeakSensitiveDataHashingCustomizations::ComputationallyExpensiveHashFunction - /** - * DEPRECATED: Use `Flow` module instead. - * - * A taint-tracking configuration for detecting use of a broken or weak - * cryptographic hashing algorithm on passwords. - * - * Passwords has stricter requirements on the hashing algorithm used (must be - * computationally expensive to prevent brute-force attacks). - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ComputationallyExpensiveHashFunction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - sensitiveDataExtraStepForCalls(node1, node2) - } - } - /** * Passwords has stricter requirements on the hashing algorithm used (must be * computationally expensive to prevent brute-force attacks). diff --git a/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll index dcf3939bc78..e69e8ad63c6 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll @@ -11,24 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import XmlBombCustomizations::XmlBomb -/** - * DEPRECATED: Use `XmlBombFlow` module instead. - * - * A taint-tracking configuration for detecting "XML bomb" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "XmlBomb" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} - private module XmlBombConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll index f8a21aedba5..2a15669f6ff 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import XpathInjectionCustomizations::XpathInjection -/** - * DEPRECATED: Use `XpathInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Xpath Injection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module XpathInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll index 8d85d275f1e..da7c34a5bac 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll @@ -11,24 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import XxeCustomizations::Xxe -/** - * DEPRECATED: Use `XxeFlow` module instead. - * - * A taint-tracking configuration for detecting "XML External Entity (XXE)" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Xxe" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} - private module XxeConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll index a65569510df..d2b47c9a6a7 100644 --- a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll +++ b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll @@ -167,19 +167,6 @@ class ExternalApiDataNode extends DataFlow::Node { } } -/** - * DEPRECATED: Use `XmlBombFlow` module instead. - * - * A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. - */ -deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { - UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } - - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } -} - private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } diff --git a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll index 68194309e1d..290087f6a71 100644 --- a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll +++ b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll @@ -16,37 +16,6 @@ private import semmle.python.ApiGraphs module ModificationOfParameterWithDefault { import ModificationOfParameterWithDefaultCustomizations::ModificationOfParameterWithDefault - /** - * DEPRECATED: Use `Flow` module instead. - * - * A data-flow configuration for detecting modifications of a parameters default value. - */ - deprecated class Configuration extends DataFlow::Configuration { - /** Record whether the default value being tracked is non-empty. */ - boolean nonEmptyDefault; - - Configuration() { - nonEmptyDefault in [true, false] and - this = "ModificationOfParameterWithDefault:" + nonEmptyDefault.toString() - } - - override predicate isSource(DataFlow::Node source) { - source.(Source).isNonEmpty() = nonEmptyDefault - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isBarrier(DataFlow::Node node) { - // if we are tracking a non-empty default, then it is ok to modify empty values, - // so our tracking ends at those. - nonEmptyDefault = true and node instanceof MustBeEmpty - or - // if we are tracking a empty default, then it is ok to modify non-empty values, - // so our tracking ends at those. - nonEmptyDefault = false and node instanceof MustBeNonEmpty - } - } - private module Config implements DataFlow::StateConfigSig { class FlowState = boolean; diff --git a/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll b/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll index 19af6cbf807..e9f13aaaa47 100644 --- a/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll +++ b/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll @@ -103,15 +103,3 @@ module FromTaintTrackingStateConfig { import MakeQueryTest } - -deprecated signature class LegacyConfiguration extends DataFlow::Configuration; - -deprecated module FromLegacyConfiguration { - module Impl implements QueryTestSig { - predicate isSink(DataFlow::Node sink) { any(C c).isSink(sink) or any(C c).isSink(sink, _) } - - predicate flowTo(DataFlow::Node sink) { any(C c).hasFlowTo(sink) } - } - - import MakeQueryTest -} From 8c99ad4fcb20cae05efee127e4685fc0e013d9fa Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 3 Dec 2024 19:38:47 +0100 Subject: [PATCH 63/63] Ruby: Remove deprecated configuration classes referencing deleted api. --- .../UnicodeBypassValidationQuery.qll | 50 ----------------- .../codeql/ruby/experimental/ZipSlipQuery.qll | 29 ---------- .../ruby/security/CleartextLoggingQuery.qll | 22 -------- .../ruby/security/CleartextStorageQuery.qll | 22 -------- .../security/CodeInjectionCustomizations.qll | 43 --------------- .../ruby/security/CodeInjectionQuery.qll | 28 ---------- .../ruby/security/CommandInjectionQuery.qll | 18 ------- .../ruby/security/ConditionalBypassQuery.qll | 17 ------ ...dedDataInterpretedAsCodeCustomizations.qll | 29 ---------- .../HardcodedDataInterpretedAsCodeQuery.qll | 33 ------------ .../ruby/security/HttpToFileAccessQuery.qll | 16 ------ .../ruby/security/ImproperLdapAuthQuery.qll | 14 ----- .../InsecureDownloadCustomizations.qll | 53 ------------------- .../ruby/security/LogInjectionQuery.qll | 14 ----- .../ruby/security/PathInjectionQuery.qll | 17 ------ .../ruby/security/ReflectedXSSQuery.qll | 26 --------- .../ruby/security/SensitiveGetQueryQuery.qll | 21 -------- .../ServerSideRequestForgeryQuery.qll | 19 ------- .../ruby/security/SqlInjectionQuery.qll | 14 ----- .../ruby/security/StackTraceExposureQuery.qll | 14 ----- .../security/TaintedFormatStringQuery.qll | 16 ------ .../ruby/security/TemplateInjectionQuery.qll | 14 ----- .../security/UnsafeCodeConstructionQuery.qll | 22 -------- .../security/UnsafeDeserializationQuery.qll | 19 ------- .../security/UnsafeHtmlConstructionQuery.qll | 19 ------- .../UnsafeShellCommandConstructionQuery.qll | 23 -------- .../codeql/ruby/security/UrlRedirectQuery.qll | 18 ------- .../regexp/MissingFullAnchorQuery.qll | 15 ------ .../security/regexp/PolynomialReDoSQuery.qll | 24 --------- .../security/regexp/RegExpInjectionQuery.qll | 14 ----- 30 files changed, 683 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll b/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll index 26011c8d918..7a5be05ac30 100644 --- a/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll @@ -9,22 +9,6 @@ private import codeql.ruby.TaintTracking private import codeql.ruby.ApiGraphs import UnicodeBypassValidationCustomizations::UnicodeBypassValidation -/** - * A state signifying that a logical validation has not been performed. - * DEPRECATED: Use `PreValidationState()` - */ -deprecated class PreValidation extends DataFlow::FlowState { - PreValidation() { this = "PreValidation" } -} - -/** - * A state signifying that a logical validation has been performed. - * DEPRECATED: Use `PostValidationState()` - */ -deprecated class PostValidation extends DataFlow::FlowState { - PostValidation() { this = "PostValidation" } -} - /** * A state signifying if a logical validation has been performed or not. */ @@ -34,40 +18,6 @@ private newtype ValidationState = // A state signifying that a logical validation has been performed. PostValidationState() -/** - * A taint-tracking configuration for detecting "Unicode transformation mishandling" vulnerabilities. - * - * This configuration uses two flow states, `PreValidation` and `PostValidation`, - * to track the requirement that a logical validation has been performed before the Unicode Transformation. - * DEPRECATED: Use `UnicodeBypassValidationFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnicodeBypassValidation" } - - private ValidationState convertState(DataFlow::FlowState state) { - state instanceof PreValidation and result = PreValidationState() - or - state instanceof PostValidation and result = PostValidationState() - } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - UnicodeBypassValidationConfig::isSource(source, this.convertState(state)) - } - - override predicate isAdditionalTaintStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - UnicodeBypassValidationConfig::isAdditionalFlowStep(nodeFrom, this.convertState(stateFrom), - nodeTo, this.convertState(stateTo)) - } - - /* A Unicode Tranformation (Unicode tranformation) is considered a sink when the algorithm used is either NFC or NFKC. */ - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - UnicodeBypassValidationConfig::isSink(sink, this.convertState(state)) - } -} - /** * A taint-tracking configuration for detecting "Unicode transformation mishandling" vulnerabilities. * diff --git a/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll b/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll index f1a00b21d92..cb6dfc931bd 100644 --- a/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll +++ b/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll @@ -9,35 +9,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import codeql.ruby.ApiGraphs -/** - * A taint-tracking configuration for reasoning about zip slip - * vulnerabilities. - * DEPRECATED: Use `ZipSlipFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ZipSlip" } - - override predicate isSource(DataFlow::Node source) { source instanceof ZipSlip::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof ZipSlip::Sink } - - /** - * This should actually be - * `and cn = API::getTopLevelMember("Gem").getMember("Package").getMember("TarReader").getMember("Entry").getAMethodCall("full_name")` and similar for other classes - * but I couldn't make it work so there's only check for the method name called on the entry. It is `full_name` for `Gem::Package::TarReader::Entry` and `Zlib` - * and `name` for `Zip::File` - */ - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::CallNode cn | - cn.getReceiver() = nodeFrom and - cn.getMethodName() in ["full_name", "name"] and - cn = nodeTo - ) - } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof ZipSlip::Sanitizer } -} - private module ZipSlipConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ZipSlip::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll b/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll index 2f321939ec2..38dc08731f4 100644 --- a/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll @@ -12,28 +12,6 @@ private import codeql.ruby.TaintTracking import CleartextLoggingCustomizations::CleartextLogging private import CleartextLoggingCustomizations::CleartextLogging as CL -/** - * A taint-tracking configuration for detecting "Clear-text logging of sensitive information". - * DEPRECATED: Use `CleartextLoggingFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextLogging" } - - override predicate isSource(DataFlow::Node source) { source instanceof CL::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof CL::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof CL::Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - CL::isAdditionalTaintStep(nodeFrom, nodeTo) - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof CL::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll b/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll index 2a1a45bfb0b..60dfd216609 100644 --- a/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll @@ -11,28 +11,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import CleartextStorageCustomizations::CleartextStorage as CS -/** - * A taint-tracking configuration for detecting "Clear-text storage of sensitive information". - * DEPRECATED: Use `CleartextStorageFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextStorage" } - - override predicate isSource(DataFlow::Node source) { source instanceof CS::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof CS::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof CS::Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - CS::isAdditionalTaintStep(nodeFrom, nodeTo) - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof CS::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll index 8103ddf0c64..fe08d83d6fb 100644 --- a/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll @@ -14,18 +14,6 @@ private import codeql.ruby.frameworks.data.internal.ApiGraphModels module CodeInjection { /** Flow states used to distinguish whether an attacker controls the entire string. */ module FlowState { - /** - * Flow state used for normal tainted data, where an attacker might only control a substring. - * DEPRECATED: Use `SubString()` - */ - deprecated DataFlow::FlowState substring() { result = "substring" } - - /** - * Flow state used for data that is entirely controlled by the attacker. - * DEPRECATED: Use `Full()` - */ - deprecated DataFlow::FlowState full() { result = "full" } - private newtype TState = TFull() or TSubString() @@ -62,14 +50,6 @@ module CodeInjection { * A data flow source for "Code injection" vulnerabilities. */ abstract class Source extends DataFlow::Node { - /** - * Gets a flow state for which this is a source. - * DEPRECATED: Use `getAState()` - */ - deprecated DataFlow::FlowState getAFlowState() { - result = [FlowState::substring(), FlowState::full()] - } - /** Gets a flow state for which this is a source. */ FlowState::State getAState() { result instanceof FlowState::SubString or result instanceof FlowState::Full @@ -80,14 +60,6 @@ module CodeInjection { * A data flow sink for "Code injection" vulnerabilities. */ abstract class Sink extends DataFlow::Node { - /** - * Holds if this sink is safe for an attacker that only controls a substring. - * DEPRECATED: Use `getAState()` - */ - deprecated DataFlow::FlowState getAFlowState() { - result = [FlowState::substring(), FlowState::full()] - } - /** Holds if this sink is safe for an attacker that only controls a substring. */ FlowState::State getAState() { any() } } @@ -96,13 +68,6 @@ module CodeInjection { * A sanitizer for "Code injection" vulnerabilities. */ abstract class Sanitizer extends DataFlow::Node { - /** - * Gets a flow state for which this is a sanitizer. - * Sanitizes all states if the result is empty. - * DEPRECATED: Use `getAState()` - */ - deprecated DataFlow::FlowState getAFlowState() { none() } - /** * Gets a flow state for which this is a sanitizer. * Sanitizes all states if the result is empty. @@ -123,12 +88,6 @@ module CodeInjection { CodeExecutionAsSink() { this = c.getCode() } - deprecated override DataFlow::FlowState getAFlowState() { - if c.runsArbitraryCode() - then result = [FlowState::substring(), FlowState::full()] // If it runs arbitrary code then it's always vulnerable. - else result = FlowState::full() // If it "just" loads something, then it's only vulnerable if the attacker controls the entire string. - } - override FlowState::State getAState() { if c.runsArbitraryCode() then any() // If it runs arbitrary code then it's always vulnerable. @@ -153,8 +112,6 @@ module CodeInjection { ) } - deprecated override DataFlow::FlowState getAFlowState() { result = FlowState::full() } - override FlowState::State getAState() { result instanceof FlowState::Full } } diff --git a/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll index 6641bbe2c34..9394601c5ed 100644 --- a/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll @@ -11,34 +11,6 @@ import codeql.ruby.TaintTracking import CodeInjectionCustomizations::CodeInjection import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting "Code injection" vulnerabilities. - * DEPRECATED: Use `CodeInjectionFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CodeInjection" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - state = source.(Source).getAFlowState() - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - state = sink.(Sink).getAFlowState() - } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer and not exists(node.(Sanitizer).getAFlowState()) - or - node instanceof StringConstCompareBarrier - or - node instanceof StringConstArrayInclusionCallBarrier - } - - override predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { - node.(Sanitizer).getAFlowState() = state - } -} - private module Config implements DataFlow::StateConfigSig { class FlowState = FlowState::State; diff --git a/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll index 4111d6c5d4a..74d00b25479 100644 --- a/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll @@ -13,24 +13,6 @@ import CommandInjectionCustomizations::CommandInjection import codeql.ruby.DataFlow import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for reasoning about command-injection vulnerabilities. - * DEPRECATED: Use `CommandInjectionFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CommandInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer or - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll b/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll index 2c4d3ede0f5..fa7e829d684 100644 --- a/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll @@ -11,23 +11,6 @@ private import codeql.ruby.TaintTracking private import codeql.ruby.security.SensitiveActions import ConditionalBypassCustomizations::ConditionalBypass -/** - * A taint tracking configuration for bypass of sensitive action guards. - * DEPRECATED: Use `ConditionalBypassFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ConditionalBypass" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll index daba69f6ca2..6d4d411baa1 100644 --- a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll @@ -19,18 +19,6 @@ module HardcodedDataInterpretedAsCode { * Flow states used to distinguish value-preserving flow from taint flow. */ module FlowState { - /** - * Flow state used to track value-preserving flow. - * DEPRECATED: Use `Data()` - */ - deprecated DataFlow::FlowState data() { result = "data" } - - /** - * Flow state used to tainted data (non-value preserving flow). - * DEPRECATED: Use `Taint()` - */ - deprecated DataFlow::FlowState taint() { result = "taint" } - /** * Flow states used to distinguish value-preserving flow from taint flow. */ @@ -45,12 +33,6 @@ module HardcodedDataInterpretedAsCode { * A data flow source for hard-coded data. */ abstract class Source extends DataFlow::Node { - /** - * Gets a flow label for which this is a source. - * DEPRECATED: Use `getALabel()` - */ - deprecated DataFlow::FlowState getLabel() { result = FlowState::data() } - /** * Gets a flow label for which this is a source. */ @@ -64,17 +46,6 @@ module HardcodedDataInterpretedAsCode { /** Gets a description of what kind of sink this is. */ abstract string getKind(); - /** - * Gets a flow label for which this is a sink. - * DEPRECATED: Use `getALabel()` - */ - deprecated DataFlow::FlowState getLabel() { - // We want to ignore value-flow and only consider taint-flow, since the - // source is just a hex string, and evaluating that directly will just - // cause a syntax error. - result = FlowState::taint() - } - /** * Gets a flow label for which this is a sink. */ diff --git a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll index a3e58f43e43..3fdd6ffc2a4 100644 --- a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll @@ -12,39 +12,6 @@ private import codeql.ruby.TaintTracking private import codeql.ruby.dataflow.internal.TaintTrackingPrivate import HardcodedDataInterpretedAsCodeCustomizations::HardcodedDataInterpretedAsCode -/** - * A taint-tracking configuration for reasoning about hard-coded data - * being interpreted as code. - * - * DEPRECATED: Use `HardcodedDataInterpretedAsCodeFlow` instead - */ -deprecated class Configuration extends DataFlow::Configuration { - Configuration() { this = "HardcodedDataInterpretedAsCode" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState label) { - source.(Source).getLabel() = label - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState label) { - sink.(Sink).getLabel() = label - } - - override predicate isBarrier(DataFlow::Node node) { - super.isBarrier(node) or - node instanceof Sanitizer - } - - override predicate isAdditionalFlowStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - defaultAdditionalTaintStep(nodeFrom, nodeTo, _) and - // This is a taint step, so the flow state becomes `taint`. - stateFrom = [FlowState::data(), FlowState::taint()] and - stateTo = FlowState::taint() - } -} - private module Config implements DataFlow::StateConfigSig { class FlowState = FlowState::State; diff --git a/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll b/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll index 9b3d7635c87..6a2eb63198a 100644 --- a/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll @@ -23,19 +23,3 @@ module HttpToFileAccessConfig implements DataFlow::ConfigSig { * Taint tracking for writing user-controlled data to files. */ module HttpToFileAccessFlow = TaintTracking::Global; - -/** - * DEPRECATED. Use the `HttpToFileAccessFlow` module instead. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "HttpToFileAccess" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} diff --git a/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll b/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll index 81a85f596c9..bddc6d2c3c4 100644 --- a/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll @@ -7,20 +7,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import ImproperLdapAuthCustomizations::ImproperLdapAuth -/** - * A taint-tracking configuration for detecting improper LDAP authentication vulnerabilities. - * DEPRECATED: Use `ImproperLdapAuthFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ImproperLdapAuth" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module ImproperLdapAuthConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll index 0ac51d38ed6..59fb2391c7e 100644 --- a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll @@ -19,12 +19,6 @@ module InsecureDownload { * A data flow source for download of sensitive file through insecure connection. */ abstract class Source extends DataFlow::Node { - /** - * Gets a flow-label for this source. - * DEPRECATED: Use `getAFlowLabel()` - */ - abstract deprecated DataFlow::FlowState getALabel(); - /** * Gets a flow-label for this source. */ @@ -40,12 +34,6 @@ module InsecureDownload { */ abstract DataFlow::Node getDownloadCall(); - /** - * Gets a flow-label where this sink is vulnerable. - * DEPRECATED: Use `getAFlowLabel()` - */ - abstract deprecated DataFlow::FlowState getALabel(); - /** * Gets a flow-label where this sink is vulnerable. */ @@ -61,30 +49,6 @@ module InsecureDownload { * Flow-labels for reasoning about download of sensitive file through insecure connection. */ module Label { - /** - * A flow-label for a URL that is downloaded over an insecure connection. - * DEPRECATED: Use `InsecureState()` - */ - deprecated class Insecure extends DataFlow::FlowState { - Insecure() { this = "insecure" } - } - - /** - * A flow-label for a URL that is sensitive. - * DEPRECATED: Use `SensitiveState()` - */ - deprecated class Sensitive extends DataFlow::FlowState { - Sensitive() { this = "sensitive" } - } - - /** - * A flow-label for file URLs that are both sensitive and downloaded over an insecure connection. - * DEPRECATED: Use `SensitiveInsecureState()` - */ - deprecated class SensitiveInsecure extends DataFlow::FlowState { - SensitiveInsecure() { this = "sensitiveInsecure" } - } - /** * Flow-labels for reasoning about download of sensitive file through insecure connection. */ @@ -114,13 +78,6 @@ module InsecureDownload { * seen as a source for downloads of sensitive files through an insecure connection. */ class InsecureFileUrl extends Source, InsecureUrl { - deprecated override DataFlow::FlowState getALabel() { - result instanceof Label::Insecure - or - hasUnsafeExtension(str) and - result instanceof Label::SensitiveInsecure - } - override Label::State getAFlowLabel() { result = Label::InsecureState() or @@ -136,8 +93,6 @@ module InsecureDownload { class SensitiveFileName extends Source { SensitiveFileName() { hasUnsafeExtension(this.asExpr().getConstantValue().getString()) } - deprecated override DataFlow::FlowState getALabel() { result instanceof Label::Sensitive } - override Label::State getAFlowLabel() { result = Label::SensitiveState() } } @@ -180,12 +135,6 @@ module InsecureDownload { override DataFlow::Node getDownloadCall() { result = req } - deprecated override DataFlow::FlowState getALabel() { - result instanceof Label::SensitiveInsecure - or - any(req.getAUrlPart()) instanceof InsecureUrl and result instanceof Label::Sensitive - } - override Label::State getAFlowLabel() { result = Label::SensitiveInsecureState() or @@ -232,8 +181,6 @@ module InsecureDownload { ) } - deprecated override DataFlow::FlowState getALabel() { result instanceof Label::Insecure } - override Label::State getAFlowLabel() { result = Label::InsecureState() } override DataFlow::Node getDownloadCall() { result = request } diff --git a/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll index a2fce6ae06b..648f9496ea1 100644 --- a/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll @@ -25,20 +25,6 @@ abstract class Sink extends DataFlow::Node { } */ abstract class Sanitizer extends DataFlow::Node { } -/** - * A taint-tracking configuration for untrusted user input used in log entries. - * DEPRECATED: Use `LogInjectionFlow` - */ -deprecated class LogInjectionConfiguration extends TaintTracking::Configuration { - LogInjectionConfiguration() { this = "LogInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - /** * A source of remote user controlled input. */ diff --git a/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll index 1c48d54e424..55329c50717 100644 --- a/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll @@ -12,23 +12,6 @@ private import codeql.ruby.Concepts private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking -/** - * A taint-tracking configuration for reasoning about path injection - * vulnerabilities. - * DEPRECATED: Use `PathInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PathInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof PathInjection::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof PathInjection::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Path::PathSanitization or node instanceof PathInjection::Sanitizer - } -} - private module PathInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof PathInjection::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll b/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll index 964e75d39dc..d1618a94904 100644 --- a/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll @@ -10,32 +10,6 @@ private import codeql.ruby.AST import codeql.ruby.DataFlow import codeql.ruby.TaintTracking -/** - * Provides a taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - * DEPRECATED: Use `ReflectedXssFlow` - */ -deprecated module ReflectedXss { - import XSS::ReflectedXss - - /** - * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - * DEPRECATED: Use `ReflectedXssFlow` - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ReflectedXSS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - isAdditionalXssTaintStep(node1, node2) - } - } -} - private module ReflectedXssConfig implements DataFlow::ConfigSig { private import XSS::ReflectedXss as RX diff --git a/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll b/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll index d18b6949f10..d3fe93fa764 100644 --- a/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll @@ -10,27 +10,6 @@ private import ruby private import codeql.ruby.TaintTracking -/** - * Provides a taint-tracking configuration for detecting flow of query string - * data to sensitive actions in GET query request handlers. - * DEPRECATED: Use `SensitiveGetQueryFlow` - */ -deprecated module SensitiveGetQuery { - import SensitiveGetQueryCustomizations::SensitiveGetQuery - - /** - * A taint-tracking configuration for reasoning about use of sensitive data - * from a GET request query string. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SensitiveGetQuery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - } -} - private module SensitiveGetQueryConfig implements DataFlow::ConfigSig { import SensitiveGetQueryCustomizations::SensitiveGetQuery diff --git a/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll b/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll index 319bbc30d5d..2e8aed1c0b8 100644 --- a/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll @@ -12,25 +12,6 @@ import codeql.ruby.TaintTracking import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting - * "Server side request forgery" vulnerabilities. - * DEPRECATED: Use `ServerSideRequestForgeryFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ServerSideRequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer or - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } -} - private module ServerSideRequestForgeryConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll index 9225552a840..40a9b603bf4 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll @@ -7,20 +7,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking import SqlInjectionCustomizations::SqlInjection -/** - * A taint-tracking configuration for detecting SQL injection vulnerabilities. - * DEPRECATED: Use `SqlInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjectionConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module SqlInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll index b07c3d584da..8342c382cdb 100644 --- a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll @@ -11,20 +11,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import StackTraceExposureCustomizations::StackTraceExposure -/** - * A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities. - * DEPRECATED: Use `StackTraceExposureFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StackTraceExposure" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module StackTraceExposureConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll index b10088af82e..1231921649e 100644 --- a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll @@ -25,19 +25,3 @@ module TaintedFormatStringConfig implements DataFlow::ConfigSig { * Taint-tracking for format injections. */ module TaintedFormatStringFlow = TaintTracking::Global; - -/** - * DEPRECATED. Use the `TaintedFormatStringFlow` module instead. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TaintedFormatString" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} diff --git a/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll index 8cc26e189aa..3e361091549 100644 --- a/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll @@ -7,20 +7,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking import TemplateInjectionCustomizations::TemplateInjection -/** - * A taint-tracking configuration for detecting Server Side Template Injections vulnerabilities. - * DEPRECATED: Use `TemplateInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TemplateInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module TemplateInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll index 32cc9a4f821..06dc8797832 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll @@ -12,28 +12,6 @@ import UnsafeCodeConstructionCustomizations::UnsafeCodeConstruction private import codeql.ruby.TaintTracking private import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting code constructed from library input vulnerabilities. - * DEPRECATED: Use `UnsafeCodeConstructionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeShellCommandConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - private module UnsafeCodeConstructionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll index 0c6e97f1fa0..ad7749d68aa 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll @@ -11,25 +11,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking import UnsafeDeserializationCustomizations -/** - * A taint-tracking configuration for reasoning about unsafe deserialization. - * DEPRECATED: Use `UnsafeDeserializationFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeDeserialization" } - - override predicate isSource(DataFlow::Node source) { - source instanceof UnsafeDeserialization::Source - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof UnsafeDeserialization::Sanitizer - } -} - private module UnsafeDeserializationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof UnsafeDeserialization::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll index 9d655a6d16a..44e008cfa8b 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll @@ -12,25 +12,6 @@ import UnsafeHtmlConstructionCustomizations::UnsafeHtmlConstruction private import codeql.ruby.TaintTracking private import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting unsafe HTML construction. - * DEPRECATED: Use `UnsafeHtmlConstructionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeHtmlConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - private module UnsafeHtmlConstructionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll index b4e0b8b6bb5..6e3ac947a51 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll @@ -13,29 +13,6 @@ private import codeql.ruby.TaintTracking private import CommandInjectionCustomizations::CommandInjection as CommandInjection private import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting shell command constructed from library input vulnerabilities. - * DEPRECATED: Use `UnsafeShellCommandConstructionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeShellCommandConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof CommandInjection::Sanitizer or // using all sanitizers from `rb/command-injection` - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - private module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll b/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll index 37334445aa7..6169de81269 100644 --- a/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll @@ -12,24 +12,6 @@ import codeql.ruby.TaintTracking import UrlRedirectCustomizations import UrlRedirectCustomizations::UrlRedirect -/** - * A taint-tracking configuration for detecting "URL redirection" vulnerabilities. - * DEPRECATED: Use `UrlRedirectFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UrlRedirect" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - UrlRedirect::isAdditionalTaintStep(node1, node2) - } -} - private module UrlRedirectConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll b/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll index 19ac3600fa1..febfa0712d9 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll @@ -11,21 +11,6 @@ import ruby import codeql.ruby.TaintTracking import MissingFullAnchorCustomizations::MissingFullAnchor -/** - * A taint tracking configuration for reasoning about - * missing full-anchored regular expressions. - * DEPRECATED: Use `MissingFullAnchorFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "MissingFullAnchor" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module MissingFullAnchorConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll b/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll index 934f8812019..98a42fcf5e7 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll @@ -10,30 +10,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking -/** - * Provides a taint-tracking configuration for detecting polynomial regular - * expression denial of service vulnerabilities. - * DEPRECATED: Use `PolynomialReDoSFlow` - */ -deprecated module PolynomialReDoS { - import PolynomialReDoSCustomizations::PolynomialReDoS - - /** - * A taint-tracking configuration for detecting polynomial regular expression - * denial of service vulnerabilities. - * DEPRECATED: Use `PolynomialReDoSFlow` - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PolynomialReDoS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - } -} - private module PolynomialReDoSConfig implements DataFlow::ConfigSig { private import PolynomialReDoSCustomizations::PolynomialReDoS diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll index 353c13a3c2d..3e6f6f83ef8 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll @@ -11,20 +11,6 @@ import codeql.ruby.TaintTracking import RegExpInjectionCustomizations import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting regexp injection vulnerabilities. - * DEPRECATED: Use `RegExpInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RegExpInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof RegExpInjection::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof RegExpInjection::Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof RegExpInjection::Sanitizer } -} - private module RegExpInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RegExpInjection::Source }