From fe9feb900d8351b380c716c837b7500d9477e808 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 17:29:26 +0000 Subject: [PATCH 001/213] C++: We will need all these types. --- .../dataflow/taint-tests/atl.cpp | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp new file mode 100644 index 000000000000..58a00385c33c --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -0,0 +1,65 @@ +namespace { + template T source(); + template T* indirect_source(); + void sink(...); +} + +typedef unsigned int UINT; +typedef long LONG; +typedef void* LPVOID; +typedef void* PVOID; +typedef bool BOOL; +typedef char* PSTR, *LPSTR; +typedef const char* LPCTSTR; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef void* HANDLE; +typedef LONG HRESULT; +typedef unsigned long ULONG; +typedef const char* LPCSTR; +typedef wchar_t OLECHAR; +typedef OLECHAR* LPOLESTR; +typedef const LPOLESTR LPCOLESTR; +typedef OLECHAR* BSTR; +typedef wchar_t* LPWSTR, *PWSTR; +typedef BSTR* LPBSTR; +typedef unsigned short USHORT; +typedef char *LPTSTR; +struct __POSITION { int unused; };typedef __POSITION* POSITION; +typedef WORD ATL_URL_PORT; + +enum ATL_URL_SCHEME{ + ATL_URL_SCHEME_UNKNOWN = -1, + ATL_URL_SCHEME_FTP = 0, + ATL_URL_SCHEME_GOPHER = 1, + ATL_URL_SCHEME_HTTP = 2, + ATL_URL_SCHEME_HTTPS = 3, + ATL_URL_SCHEME_FILE = 4, + ATL_URL_SCHEME_NEWS = 5, + ATL_URL_SCHEME_MAILTO = 6, + ATL_URL_SCHEME_SOCKS = 7 +}; + +using HINSTANCE = void*; +using size_t = decltype(sizeof(int)); +using SIZE_T = size_t; + +#define NULL nullptr + +typedef struct tagSAFEARRAYBOUND { + ULONG cElements; + LONG lLbound; +} SAFEARRAYBOUND, *LPSAFEARRAYBOUND; + +typedef struct tagVARIANT { + /* ... */ +} VARIANT; + +typedef struct tagSAFEARRAY { + USHORT cDims; + USHORT fFeatures; + ULONG cbElements; + ULONG cLocks; + PVOID pvData; + SAFEARRAYBOUND rgsabound[1]; +} SAFEARRAY, *LPSAFEARRAY; From 16e5fa34d17ae874926ac8aa8c6b8d983e547aa1 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 17:30:31 +0000 Subject: [PATCH 002/213] C++: Add failing tests with U_STRINGorID. --- .../dataflow/external-models/flow.expected | 10 ++++----- .../external-models/validatemodels.expected | 21 +++++++++++++++++++ .../dataflow/taint-tests/atl.cpp | 21 +++++++++++++++++++ .../dataflow/taint-tests/localTaint.expected | 7 +++++++ 4 files changed, 54 insertions(+), 5 deletions(-) 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 a3d09178f2c3..d1e895f2eafb 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:644 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:642 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:643 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:819 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:817 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:818 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:643 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:818 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:644 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:819 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index 2e0a493585c6..b02760131065 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -1,8 +1,27 @@ +| Dubious member name "operator +=" in summary model. | +| Dubious member name "operator BSTR" in summary model. | +| Dubious member name "operator LPCSTR" in summary model. | +| Dubious member name "operator LPSAFEARRAY" in summary model. | +| Dubious member name "operator LPSTR" in summary model. | +| Dubious member name "operator LPWSTR" in summary model. | +| Dubious member name "operator PCXSTR" in summary model. | +| Dubious member name "operator StringType&" in summary model. | +| Dubious member name "operator T*" in summary model. | +| Dubious member name "operator const StringType&" in summary model. | +| Dubious member name "operator&" in summary model. | | Dubious member name "operator*" in summary model. | +| Dubious member name "operator+=" in summary model. | | Dubious member name "operator->" in summary model. | | Dubious member name "operator=" in summary model. | | Dubious member name "operator[]" in summary model. | +| Dubious signature "(CRegKey&)" in summary model. | +| Dubious signature "(DWORD&,LPCTSTR)" in summary model. | | Dubious signature "(InputIterator,InputIterator,const Allocator &)" in summary model. | +| Dubious signature "(const CComBSTR&)" in summary model. | +| Dubious signature "(const CComSafeArray&)" in summary model. | +| Dubious signature "(const SAFEARRAY&)" in summary model. | +| Dubious signature "(const SAFEARRAY*)" in summary model. | +| Dubious signature "(const SAFEARRAYBOUND*, UINT)" in summary model. | | Dubious signature "(const deque &)" in summary model. | | Dubious signature "(const deque &,const Allocator &)" in summary model. | | Dubious signature "(const forward_list &)" in summary model. | @@ -25,3 +44,5 @@ | Dubious signature "(size_type,const T &,const Allocator &)" in summary model. | | Dubious signature "(vector &&)" in summary model. | | Dubious signature "(vector &&,const Allocator &)" in summary model. | +| Dubious signature "operator HKEY" in summary model. | +| Dubious signature "operator=" in summary model. | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 58a00385c33c..54e8c65f4c76 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -63,3 +63,24 @@ typedef struct tagSAFEARRAY { PVOID pvData; SAFEARRAYBOUND rgsabound[1]; } SAFEARRAY, *LPSAFEARRAY; + +struct _U_STRINGorID { + _U_STRINGorID(UINT nID); + _U_STRINGorID(LPCTSTR lpString); + + LPCTSTR m_lpstr; +}; + +void test__U_STRINGorID() { + { + UINT x = source(); + _U_STRINGorID u(x); + sink(u.m_lpstr); // $ MISSING: ir + } + + { + LPCTSTR y = indirect_source(); + _U_STRINGorID u(y); + sink(u.m_lpstr); // $ MISSING: ir + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index b5ddf84747ae..7809703f9c80 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -140,6 +140,13 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT | | arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | | | arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT | +| atl.cpp:32:30:32:30 | 1 | atl.cpp:32:29:32:30 | - ... | TAINT | +| atl.cpp:76:14:76:25 | call to source | atl.cpp:77:21:77:21 | x | | +| atl.cpp:77:21:77:21 | x | atl.cpp:77:21:77:22 | call to _U_STRINGorID | TAINT | +| atl.cpp:77:21:77:22 | call to _U_STRINGorID | atl.cpp:78:10:78:10 | u | | +| atl.cpp:82:17:82:43 | call to indirect_source | atl.cpp:83:21:83:21 | y | | +| atl.cpp:83:21:83:21 | y | atl.cpp:83:21:83:22 | call to _U_STRINGorID | TAINT | +| atl.cpp:83:21:83:22 | call to _U_STRINGorID | atl.cpp:84:10:84:10 | u | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From bf36f00bb0d2c6f75b698628611314abee7c4c39 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 17:50:30 +0000 Subject: [PATCH 003/213] C++: Add model. Observe that flow still fails. --- cpp/ql/lib/ext/CA2CAEX.model.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 cpp/ql/lib/ext/CA2CAEX.model.yml diff --git a/cpp/ql/lib/ext/CA2CAEX.model.yml b/cpp/ql/lib/ext/CA2CAEX.model.yml new file mode 100644 index 000000000000..f199d1fddead --- /dev/null +++ b/cpp/ql/lib/ext/CA2CAEX.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "_U_STRINGorID", True, "_U_STRINGorID", "(UINT)", "", "Argument[0]", "Argument[-1].Field[*m_lpstr]", "value", "manual"] + - ["", "_U_STRINGorID", True, "_U_STRINGorID", "(LPCTSTR)", "", "Argument[*0]", "Argument[-1].Field[*m_lpstr]", "value", "manual"] From f688470324a5e4e5432c260fee776831e16cf886 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 17:53:24 +0000 Subject: [PATCH 004/213] C++: Since isConstructedFrom only holds for templates we need to explicitly handle the case where the function (or class) is not a template. --- .../semmle/code/cpp/dataflow/ExternalFlow.qll | 20 +++++++++++++++---- .../dataflow/taint-tests/atl.cpp | 4 ++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index 49610b7c85b6..ec25b08856c8 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -434,18 +434,30 @@ private predicate elementSpec( summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) } +private predicate isClassConstructedFrom(Class c, Class templateClass) { + c.isConstructedFrom(templateClass) + or + not any(Class c_).isConstructedFrom(templateClass) and c = templateClass +} + +private predicate isFunctionConstructedFrom(Function f, Function templateFunc) { + f.isConstructedFrom(templateFunc) + or + not any(Function f_).isConstructedFrom(templateFunc) and f = templateFunc +} + /** Gets the fully templated version of `f`. */ private Function getFullyTemplatedFunction(Function f) { not f.isFromUninstantiatedTemplate(_) and ( exists(Class c, Class templateClass, int i | - c.isConstructedFrom(templateClass) and + isClassConstructedFrom(c, templateClass) and f = c.getAMember(i) and result = templateClass.getCanonicalMember(i) ) or not exists(f.getDeclaringType()) and - f.isConstructedFrom(result) + isFunctionConstructedFrom(f, result) ) } @@ -489,7 +501,7 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) { // If there is a declaring type then we start by expanding the function templates exists(Class template | - f.getDeclaringType().isConstructedFrom(template) and + isClassConstructedFrom(f.getDeclaringType(), template) and remaining = template.getNumberOfTemplateArguments() and result = getTypeNameWithoutFunctionTemplates(f, n, 0) ) @@ -501,7 +513,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining or exists(string mid, TemplateParameter tp, Class template | mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and - f.getDeclaringType().isConstructedFrom(template) and + isClassConstructedFrom(f.getDeclaringType(), template) and tp = template.getTemplateArgument(remaining) and result = mid.replaceAll(tp.getName(), "class:" + remaining.toString()) ) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 54e8c65f4c76..c0507d3032d3 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -75,12 +75,12 @@ void test__U_STRINGorID() { { UINT x = source(); _U_STRINGorID u(x); - sink(u.m_lpstr); // $ MISSING: ir + sink(u.m_lpstr); // $ ir } { LPCTSTR y = indirect_source(); _U_STRINGorID u(y); - sink(u.m_lpstr); // $ MISSING: ir + sink(u.m_lpstr); // $ ir } } From 749602c98216cc08223d55a9f00443517279af9a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 17:54:54 +0000 Subject: [PATCH 005/213] C++: Add failing tests with CA2AEX and friends. --- .../dataflow/taint-tests/atl.cpp | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index c0507d3032d3..d05a2f22a01f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -84,3 +84,85 @@ void test__U_STRINGorID() { sink(u.m_lpstr); // $ ir } } + +template +struct CA2AEX { + LPSTR m_psz; + char m_szBuffer[t_nBufferLength]; + + CA2AEX(LPCSTR psz, UINT nCodePage); + CA2AEX(LPCSTR psz); + + ~CA2AEX(); + + operator LPSTR() const throw(); +}; + +void test_CA2AEX() { + { + LPSTR x = indirect_source(); + CA2AEX<128> a(x); + sink(static_cast(a)); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + sink(a.m_szBuffer); // $ MISSING: ir + } + + { + LPSTR x = indirect_source(); + CA2AEX<128> a(x, 0); + sink(static_cast(a)); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + sink(a.m_szBuffer); // $ MISSING: ir + } +} + +template +struct CA2CAEX { + CA2CAEX(LPCSTR psz, UINT nCodePage) ; + CA2CAEX(LPCSTR psz) ; + ~CA2CAEX() throw(); + operator LPCSTR() const throw(); + LPCSTR m_psz; +}; + +void test_CA2CAEX() { + LPCSTR x = indirect_source(); + { + CA2CAEX<128> a(x); + sink(static_cast(a)); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + } + { + CA2CAEX<128> a(x, 0); + sink(static_cast(a)); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + } +} + +template +struct CA2WEX { + CA2WEX(LPCSTR psz, UINT nCodePage) ; + CA2WEX(LPCSTR psz) ; + ~CA2WEX() throw(); + operator LPWSTR() const throw(); + LPWSTR m_psz; + wchar_t m_szBuffer[t_nBufferLength]; +}; + +void test_CA2WEX() { + LPCSTR x = indirect_source(); + { + CA2WEX<128> a(x); + sink(static_cast(a)); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + } + { + CA2WEX<128> a(x, 0); + sink(static_cast(a)); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ MISSING: ir + } +} From 763b991408c56341c4643dd117c0c7682dd2abd6 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 17:56:32 +0000 Subject: [PATCH 006/213] C++: Add models. --- cpp/ql/lib/ext/CA2CAEX.model.yml | 11 +++++++++++ cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../code/cpp/models/implementations/CA2AEX.qll | 17 +++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/CA2AEX.qll diff --git a/cpp/ql/lib/ext/CA2CAEX.model.yml b/cpp/ql/lib/ext/CA2CAEX.model.yml index f199d1fddead..ee1d53a537cb 100644 --- a/cpp/ql/lib/ext/CA2CAEX.model.yml +++ b/cpp/ql/lib/ext/CA2CAEX.model.yml @@ -5,3 +5,14 @@ extensions: data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance - ["", "_U_STRINGorID", True, "_U_STRINGorID", "(UINT)", "", "Argument[0]", "Argument[-1].Field[*m_lpstr]", "value", "manual"] - ["", "_U_STRINGorID", True, "_U_STRINGorID", "(LPCTSTR)", "", "Argument[*0]", "Argument[-1].Field[*m_lpstr]", "value", "manual"] + - ["", "CA2AEX", True, "CA2AEX", "", "", "Argument[*0]", "Argument[-1].Field[*m_psz]", "value", "manual"] + - ["", "CA2AEX", True, "CA2AEX", "", "", "Argument[*0]", "Argument[-1].Field[m_szBuffer]", "value", "manual"] + - ["", "CA2AEX", True, "operator LPSTR", "", "", "Argument[-1].Field[*m_psz]", "ReturnValue[*]", "value", "manual"] + - ["", "CA2AEX", True, "CA2AEX", "", "", "Argument[*0]", "Argument[-1].Field[m_szBuffer]", "value", "manual"] + - ["", "CA2AEX", True, "operator LPSTR", "", "", "Argument[-1].Field[m_szBuffer]", "ReturnValue[*]", "value", "manual"] + - ["", "CA2CAEX", True, "CA2CAEX", "", "", "Argument[*0]", "Argument[-1].Field[*m_psz]", "value", "manual"] + - ["", "CA2CAEX", True, "operator LPCSTR", "", "", "Argument[-1].Field[*m_psz]", "ReturnValue[*]", "value", "manual"] + - ["", "CA2WEX", True, "CA2WEX", "", "", "Argument[*0]", "Argument[-1].Field[*m_psz]", "value", "manual"] + - ["", "CA2WEX", True, "operator LPWSTR", "", "", "Argument[-1].Field[*m_psz]", "ReturnValue[*]", "value", "manual"] + - ["", "CA2WEX", True, "CA2WEX", "", "", "Argument[*0]", "Argument[-1].Field[m_szBuffer]", "value", "manual"] + - ["", "CA2WEX", True, "operator LPWSTR", "", "", "Argument[-1].Field[m_szBuffer]", "ReturnValue[*]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index f6776a623ffe..bb63416eaefa 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -50,3 +50,4 @@ private import implementations.System private import implementations.StructuredExceptionHandling private import implementations.ZMQ private import implementations.Win32CommandExecution +private import implementations.CA2AEX diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/CA2AEX.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/CA2AEX.qll new file mode 100644 index 000000000000..595b6e3bb3eb --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/CA2AEX.qll @@ -0,0 +1,17 @@ +private import cpp +private import semmle.code.cpp.ir.dataflow.FlowSteps +private import semmle.code.cpp.dataflow.new.DataFlow + +/** + * The `CA2AEX` (and related) classes from the Windows Active Template library. + */ +class Ca2Aex extends Class { + Ca2Aex() { this.hasGlobalName(["CA2AEX", "CA2CAEX", "CA2WEX"]) } +} + +private class Ca2AexTaintInheritingContent extends TaintInheritingContent, DataFlow::FieldContent { + Ca2AexTaintInheritingContent() { + // The two members m_psz and m_szBuffer + this.getField().getDeclaringType() instanceof Ca2Aex + } +} From 2c7d0dec7d4384a47a49448e1387c7bdd0e9abf0 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 18:01:33 +0000 Subject: [PATCH 007/213] C++: Accept test changes. --- .../dataflow/taint-tests/atl.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index d05a2f22a01f..5f0f12b31f8e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -103,16 +103,16 @@ void test_CA2AEX() { LPSTR x = indirect_source(); CA2AEX<128> a(x); sink(static_cast(a)); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir - sink(a.m_szBuffer); // $ MISSING: ir + sink(a.m_psz); // $ ir + sink(a.m_szBuffer); // $ ir } { LPSTR x = indirect_source(); CA2AEX<128> a(x, 0); sink(static_cast(a)); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir - sink(a.m_szBuffer); // $ MISSING: ir + sink(a.m_psz); // $ ir + sink(a.m_szBuffer); // $ ir } } @@ -130,14 +130,14 @@ void test_CA2CAEX() { { CA2CAEX<128> a(x); sink(static_cast(a)); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ ir + sink(a.m_psz); // $ ir } { CA2CAEX<128> a(x, 0); sink(static_cast(a)); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ ir + sink(a.m_psz); // $ ir } } @@ -156,13 +156,13 @@ void test_CA2WEX() { { CA2WEX<128> a(x); sink(static_cast(a)); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ ir + sink(a.m_psz); // $ ir } { CA2WEX<128> a(x, 0); sink(static_cast(a)); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir - sink(a.m_psz); // $ MISSING: ir + sink(a.m_psz); // $ ir + sink(a.m_psz); // $ ir } } From c00f84d74a0f209b4e25c2d080e0758845914940 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 18:03:30 +0000 Subject: [PATCH 008/213] C++: Work around the 'wrong' function name for conversion operators. --- .../semmle/code/cpp/dataflow/ExternalFlow.qll | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index ec25b08856c8..ac10651b5519 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -754,6 +754,22 @@ private predicate elementSpecMatchesSignature( signatureMatches(func, signature, type, name, 0) } +/** + * Holds when `method` has name `nameWithoutArgs`, and gets the enclosing + * class of `method`. Unlike `method.getClassAndName` this predicate does + * not strip typedefs from the name when `method` is an `ConversionOperator`. + */ +bindingset[nameWithoutArgs] +pragma[inline_late] +private Class getClassAndNameImpl(Function method, string nameWithoutArgs) { + exists(string memberName | result = method.getClassAndName(memberName) | + nameWithoutArgs = "operator " + method.(ConversionOperator).getDestType() + or + not method instanceof ConversionOperator and + memberName = nameWithoutArgs + ) +} + /** * Holds if `classWithMethod` has `method` named `name` (excluding any * template parameters). @@ -763,7 +779,7 @@ pragma[inline_late] private predicate hasClassAndName(Class classWithMethod, Function method, string name) { exists(string nameWithoutArgs | parseAngles(name, nameWithoutArgs, _, "") and - classWithMethod = method.getClassAndName(nameWithoutArgs) + classWithMethod = getClassAndNameImpl(method, nameWithoutArgs) ) } From 4f2cd81f9e7956999ba2407adad3c9ef9fd64ce3 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 26 Nov 2024 18:04:59 +0000 Subject: [PATCH 009/213] C++: Accept test changes. --- .../test/library-tests/dataflow/taint-tests/atl.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 5f0f12b31f8e..7396d4fce9ad 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -102,7 +102,7 @@ void test_CA2AEX() { { LPSTR x = indirect_source(); CA2AEX<128> a(x); - sink(static_cast(a)); // $ MISSING: ir + sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_szBuffer); // $ ir } @@ -110,7 +110,7 @@ void test_CA2AEX() { { LPSTR x = indirect_source(); CA2AEX<128> a(x, 0); - sink(static_cast(a)); // $ MISSING: ir + sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_szBuffer); // $ ir } @@ -129,13 +129,13 @@ void test_CA2CAEX() { LPCSTR x = indirect_source(); { CA2CAEX<128> a(x); - sink(static_cast(a)); // $ MISSING: ir + sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } { CA2CAEX<128> a(x, 0); - sink(static_cast(a)); // $ MISSING: ir + sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } @@ -155,13 +155,13 @@ void test_CA2WEX() { LPCSTR x = indirect_source(); { CA2WEX<128> a(x); - sink(static_cast(a)); // $ MISSING: ir + sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } { CA2WEX<128> a(x, 0); - sink(static_cast(a)); // $ MISSING: ir + sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } From 1cd426e9f96af085c4e33e66a1dbe49eb33c6fae Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 11:31:53 +0000 Subject: [PATCH 010/213] C++: Add failing tests with 'CAtlArray'. --- .../dataflow/taint-tests/atl.cpp | 83 ++++++++++ .../dataflow/taint-tests/localTaint.expected | 145 ++++++++++++++++++ 2 files changed, 228 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 7396d4fce9ad..c26966c908e4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -166,3 +166,86 @@ void test_CA2WEX() { sink(a.m_psz); // $ ir } } + +template +struct CElementTraitsBase { + typedef const T& INARGTYPE; + typedef T& OUTARGTYPE; + + static void CopyElements(T* pDest, const T* pSrc, size_t nElements); + static void RelocateElements(T* pDest, T* pSrc, size_t nElements); +}; + +template +struct CDefaultElementTraits : public CElementTraitsBase {}; + +template +struct CElementTraits : public CDefaultElementTraits {}; + +template> +struct CAtlArray { + using INARGTYPE = typename ETraits::INARGTYPE; + using OUTARGTYPE = typename ETraits::OUTARGTYPE; + + CAtlArray() throw(); + ~CAtlArray() throw(); + + size_t Add(INARGTYPE element); + size_t Add(); + size_t Append(const CAtlArray& aSrc); + void Copy(const CAtlArray& aSrc); + const E& GetAt(size_t iElement) const throw(); + E& GetAt(size_t iElement) throw(); + size_t GetCount() const throw(); + E* GetData() throw(); + const E* GetData() const throw(); + void InsertArrayAt(size_t iStart, const CAtlArray* paNew); + void InsertAt(size_t iElement, INARGTYPE element, size_t nCount); + bool IsEmpty() const throw(); + void RemoveAll() throw(); + void RemoveAt(size_t iElement, size_t nCount); + void SetAt(size_t iElement, INARGTYPE element); + void SetAtGrow(size_t iElement, INARGTYPE element); + bool SetCount(size_t nNewSize, int nGrowBy); + E& operator[](size_t ielement) throw(); + const E& operator[](size_t ielement) const throw(); +}; + +void test_CAtlArray() { + int x = source(); + + { + CAtlArray a; + a.Add(x); + sink(a[0]); // $ MISSING: ir + a.Add(0); + sink(a[0]); // $ MISSING: ir + + CAtlArray a2; + sink(a2[0]); + a2.Append(a); + sink(a2[0]); // $ MISSING: ir + + CAtlArray a3; + sink(a3[0]); + a3.Copy(a2); + sink(a3[0]); // $ MISSING: ir + + sink(a3.GetAt(0)); // $ MISSING: ir + sink(*a3.GetData()); // $ MISSING: ir + + CAtlArray a4; + sink(a4.GetAt(0)); + a4.InsertArrayAt(0, &a3); + sink(a4.GetAt(0)); // $ MISSING: ir + } + { + CAtlArray a5; + a5.InsertAt(0, source(), 1); + sink(a5[0]); // $ MISSING: ir + + CAtlArray a6; + a6.SetAtGrow(0, source()); + sink(a6[0]); // $ MISSING: ir + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 7809703f9c80..cd0b25deb453 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -147,6 +147,151 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:82:17:82:43 | call to indirect_source | atl.cpp:83:21:83:21 | y | | | atl.cpp:83:21:83:21 | y | atl.cpp:83:21:83:22 | call to _U_STRINGorID | TAINT | | atl.cpp:83:21:83:22 | call to _U_STRINGorID | atl.cpp:84:10:84:10 | u | | +| atl.cpp:103:15:103:35 | call to indirect_source | atl.cpp:104:19:104:19 | x | | +| atl.cpp:104:19:104:19 | x | atl.cpp:104:19:104:20 | call to CA2AEX | TAINT | +| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:105:29:105:29 | a | | +| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:106:10:106:10 | a | | +| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:107:10:107:10 | a | | +| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:108:3:108:3 | a | | +| atl.cpp:105:29:105:29 | ref arg a | atl.cpp:106:10:106:10 | a | | +| atl.cpp:105:29:105:29 | ref arg a | atl.cpp:107:10:107:10 | a | | +| atl.cpp:105:29:105:29 | ref arg a | atl.cpp:108:3:108:3 | a | | +| atl.cpp:106:10:106:10 | a [post update] | atl.cpp:107:10:107:10 | a | | +| atl.cpp:106:10:106:10 | a [post update] | atl.cpp:108:3:108:3 | a | | +| atl.cpp:107:10:107:10 | a [post update] | atl.cpp:108:3:108:3 | a | | +| atl.cpp:111:15:111:35 | call to indirect_source | atl.cpp:112:19:112:19 | x | | +| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:113:29:113:29 | a | | +| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:114:10:114:10 | a | | +| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:115:10:115:10 | a | | +| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:116:3:116:3 | a | | +| atl.cpp:113:29:113:29 | ref arg a | atl.cpp:114:10:114:10 | a | | +| atl.cpp:113:29:113:29 | ref arg a | atl.cpp:115:10:115:10 | a | | +| atl.cpp:113:29:113:29 | ref arg a | atl.cpp:116:3:116:3 | a | | +| atl.cpp:114:10:114:10 | a [post update] | atl.cpp:115:10:115:10 | a | | +| atl.cpp:114:10:114:10 | a [post update] | atl.cpp:116:3:116:3 | a | | +| atl.cpp:115:10:115:10 | a [post update] | atl.cpp:116:3:116:3 | a | | +| atl.cpp:129:14:129:34 | call to indirect_source | atl.cpp:131:20:131:20 | x | | +| atl.cpp:129:14:129:34 | call to indirect_source | atl.cpp:137:20:137:20 | x | | +| atl.cpp:131:20:131:20 | x | atl.cpp:131:20:131:21 | call to CA2CAEX | TAINT | +| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:132:30:132:30 | a | | +| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:133:10:133:10 | a | | +| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:134:10:134:10 | a | | +| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:135:3:135:3 | a | | +| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:138:30:138:30 | a | | +| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:139:10:139:10 | a | | +| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:140:10:140:10 | a | | +| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:141:3:141:3 | a | | +| atl.cpp:155:14:155:34 | call to indirect_source | atl.cpp:157:19:157:19 | x | | +| atl.cpp:155:14:155:34 | call to indirect_source | atl.cpp:163:19:163:19 | x | | +| atl.cpp:157:19:157:19 | x | atl.cpp:157:19:157:20 | call to CA2WEX | TAINT | +| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:158:30:158:30 | a | | +| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:159:10:159:10 | a | | +| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:160:10:160:10 | a | | +| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:161:3:161:3 | a | | +| atl.cpp:158:30:158:30 | ref arg a | atl.cpp:159:10:159:10 | a | | +| atl.cpp:158:30:158:30 | ref arg a | atl.cpp:160:10:160:10 | a | | +| atl.cpp:158:30:158:30 | ref arg a | atl.cpp:161:3:161:3 | a | | +| atl.cpp:159:10:159:10 | a [post update] | atl.cpp:160:10:160:10 | a | | +| atl.cpp:159:10:159:10 | a [post update] | atl.cpp:161:3:161:3 | a | | +| atl.cpp:159:12:159:16 | ref arg m_psz | atl.cpp:160:12:160:16 | m_psz | | +| atl.cpp:160:10:160:10 | a [post update] | atl.cpp:161:3:161:3 | a | | +| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:164:30:164:30 | a | | +| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:165:10:165:10 | a | | +| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:166:10:166:10 | a | | +| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:167:3:167:3 | a | | +| atl.cpp:164:30:164:30 | ref arg a | atl.cpp:165:10:165:10 | a | | +| atl.cpp:164:30:164:30 | ref arg a | atl.cpp:166:10:166:10 | a | | +| atl.cpp:164:30:164:30 | ref arg a | atl.cpp:167:3:167:3 | a | | +| atl.cpp:165:10:165:10 | a [post update] | atl.cpp:166:10:166:10 | a | | +| atl.cpp:165:10:165:10 | a [post update] | atl.cpp:167:3:167:3 | a | | +| atl.cpp:165:12:165:16 | ref arg m_psz | atl.cpp:166:12:166:16 | m_psz | | +| atl.cpp:166:10:166:10 | a [post update] | atl.cpp:167:3:167:3 | a | | +| atl.cpp:215:11:215:21 | call to source | atl.cpp:219:11:219:11 | x | | +| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:219:5:219:5 | a | | +| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:220:10:220:10 | a | | +| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:221:5:221:5 | a | | +| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:222:10:222:10 | a | | +| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:226:15:226:15 | a | | +| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:241:3:241:3 | a | | +| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:220:10:220:10 | a | | +| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:221:5:221:5 | a | | +| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:222:10:222:10 | a | | +| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:226:15:226:15 | a | | +| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:241:3:241:3 | a | | +| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:221:5:221:5 | a | | +| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:222:10:222:10 | a | | +| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:226:15:226:15 | a | | +| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:241:3:241:3 | a | | +| atl.cpp:221:5:221:5 | ref arg a | atl.cpp:222:10:222:10 | a | | +| atl.cpp:221:5:221:5 | ref arg a | atl.cpp:226:15:226:15 | a | | +| atl.cpp:221:5:221:5 | ref arg a | atl.cpp:241:3:241:3 | a | | +| atl.cpp:222:10:222:10 | ref arg a | atl.cpp:226:15:226:15 | a | | +| atl.cpp:222:10:222:10 | ref arg a | atl.cpp:241:3:241:3 | a | | +| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:225:10:225:11 | a2 | | +| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:226:5:226:6 | a2 | | +| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:227:10:227:11 | a2 | | +| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:231:13:231:14 | a2 | | +| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:241:3:241:3 | a2 | | +| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:226:5:226:6 | a2 | | +| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:227:10:227:11 | a2 | | +| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:231:13:231:14 | a2 | | +| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:241:3:241:3 | a2 | | +| atl.cpp:226:5:226:6 | ref arg a2 | atl.cpp:227:10:227:11 | a2 | | +| atl.cpp:226:5:226:6 | ref arg a2 | atl.cpp:231:13:231:14 | a2 | | +| atl.cpp:226:5:226:6 | ref arg a2 | atl.cpp:241:3:241:3 | a2 | | +| atl.cpp:227:10:227:11 | ref arg a2 | atl.cpp:231:13:231:14 | a2 | | +| atl.cpp:227:10:227:11 | ref arg a2 | atl.cpp:241:3:241:3 | a2 | | +| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:230:10:230:11 | a3 | | +| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:231:5:231:6 | a3 | | +| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:232:10:232:11 | a3 | | +| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:234:10:234:11 | a3 | | +| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:235:11:235:12 | a3 | | +| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:239:26:239:27 | a3 | | +| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:241:3:241:3 | a3 | | +| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:231:5:231:6 | a3 | | +| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:232:10:232:11 | a3 | | +| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:234:10:234:11 | a3 | | +| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | +| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | +| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | +| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:232:10:232:11 | a3 | | +| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:234:10:234:11 | a3 | | +| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | +| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | +| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | +| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:234:10:234:11 | a3 | | +| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | +| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | +| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | +| atl.cpp:234:10:234:11 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | +| atl.cpp:234:10:234:11 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | +| atl.cpp:234:10:234:11 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | +| atl.cpp:235:11:235:12 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | +| atl.cpp:235:11:235:12 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | +| atl.cpp:235:14:235:20 | call to GetData | atl.cpp:235:10:235:22 | * ... | TAINT | +| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:238:10:238:11 | a4 | | +| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:239:5:239:6 | a4 | | +| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:240:10:240:11 | a4 | | +| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:241:3:241:3 | a4 | | +| atl.cpp:238:10:238:11 | ref arg a4 | atl.cpp:239:5:239:6 | a4 | | +| atl.cpp:238:10:238:11 | ref arg a4 | atl.cpp:240:10:240:11 | a4 | | +| atl.cpp:238:10:238:11 | ref arg a4 | atl.cpp:241:3:241:3 | a4 | | +| atl.cpp:239:5:239:6 | ref arg a4 | atl.cpp:240:10:240:11 | a4 | | +| atl.cpp:239:5:239:6 | ref arg a4 | atl.cpp:241:3:241:3 | a4 | | +| atl.cpp:239:26:239:27 | a3 | atl.cpp:239:25:239:27 | & ... | | +| atl.cpp:240:10:240:11 | ref arg a4 | atl.cpp:241:3:241:3 | a4 | | +| atl.cpp:243:20:243:21 | call to CAtlArray | atl.cpp:244:5:244:6 | a5 | | +| atl.cpp:243:20:243:21 | call to CAtlArray | atl.cpp:245:10:245:11 | a5 | | +| atl.cpp:243:20:243:21 | call to CAtlArray | atl.cpp:250:3:250:3 | a5 | | +| atl.cpp:244:5:244:6 | ref arg a5 | atl.cpp:245:10:245:11 | a5 | | +| atl.cpp:244:5:244:6 | ref arg a5 | atl.cpp:250:3:250:3 | a5 | | +| atl.cpp:245:10:245:11 | ref arg a5 | atl.cpp:250:3:250:3 | a5 | | +| atl.cpp:247:20:247:21 | call to CAtlArray | atl.cpp:248:5:248:6 | a6 | | +| atl.cpp:247:20:247:21 | call to CAtlArray | atl.cpp:249:10:249:11 | a6 | | +| atl.cpp:247:20:247:21 | call to CAtlArray | atl.cpp:250:3:250:3 | a6 | | +| atl.cpp:248:5:248:6 | ref arg a6 | atl.cpp:249:10:249:11 | a6 | | +| atl.cpp:248:5:248:6 | ref arg a6 | atl.cpp:250:3:250:3 | a6 | | +| atl.cpp:249:10:249:11 | ref arg a6 | atl.cpp:250:3:250:3 | a6 | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 0f8df1cd9f3843704d43be4efadd71440c98c4f4 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 11:34:42 +0000 Subject: [PATCH 011/213] C++: Add MaD model for 'CAtlArray'. --- cpp/ql/lib/ext/CAtlArray.model.yml | 15 +++++++++++++++ .../library-tests/dataflow/taint-tests/atl.cpp | 18 +++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 cpp/ql/lib/ext/CAtlArray.model.yml diff --git a/cpp/ql/lib/ext/CAtlArray.model.yml b/cpp/ql/lib/ext/CAtlArray.model.yml new file mode 100644 index 000000000000..29afc0c99598 --- /dev/null +++ b/cpp/ql/lib/ext/CAtlArray.model.yml @@ -0,0 +1,15 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CAtlArray", True, "Add", "", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlArray", True, "Append", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlArray", True, "Copy", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlArray", True, "GetAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CAtlArray", True, "GetData", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CAtlArray", True, "InsertArrayAt", "", "", "Argument[*1].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlArray", True, "InsertAt", "", "", "Argument[@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlArray", True, "SetAt", "", "", "Argument[@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlArray", True, "SetAtGrow", "", "", "Argument[@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlArray", True, "operator[]", "", "", "Argument[-1].Element[@]", "ReturnValue[*]", "value", "manual"] diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index c26966c908e4..4b3f1438d8d4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -217,35 +217,35 @@ void test_CAtlArray() { { CAtlArray a; a.Add(x); - sink(a[0]); // $ MISSING: ir + sink(a[0]); // $ ir a.Add(0); - sink(a[0]); // $ MISSING: ir + sink(a[0]); // $ ir CAtlArray a2; sink(a2[0]); a2.Append(a); - sink(a2[0]); // $ MISSING: ir + sink(a2[0]); // $ ir CAtlArray a3; sink(a3[0]); a3.Copy(a2); - sink(a3[0]); // $ MISSING: ir + sink(a3[0]); // $ ir - sink(a3.GetAt(0)); // $ MISSING: ir - sink(*a3.GetData()); // $ MISSING: ir + sink(a3.GetAt(0)); // $ ir + sink(*a3.GetData()); // $ ir CAtlArray a4; sink(a4.GetAt(0)); a4.InsertArrayAt(0, &a3); - sink(a4.GetAt(0)); // $ MISSING: ir + sink(a4.GetAt(0)); // $ ir } { CAtlArray a5; a5.InsertAt(0, source(), 1); - sink(a5[0]); // $ MISSING: ir + sink(a5[0]); // $ ir CAtlArray a6; a6.SetAtGrow(0, source()); - sink(a6[0]); // $ MISSING: ir + sink(a6[0]); // $ ir } } From c604a93d1611b2ef7be1e5196262ea2ac27559eb Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 11:37:08 +0000 Subject: [PATCH 012/213] C++: Add failing tests with 'CAtlList'. --- .../dataflow/taint-tests/atl.cpp | 147 ++++++++++++ .../dataflow/taint-tests/localTaint.expected | 214 ++++++++++++++++++ 2 files changed, 361 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 4b3f1438d8d4..b1231c13c485 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -249,3 +249,150 @@ void test_CAtlArray() { sink(a6[0]); // $ ir } } + +template> +struct CAtlList { + using INARGTYPE = typename ETraits::INARGTYPE; + CAtlList(UINT nBlockSize) throw(); + ~CAtlList() throw(); + POSITION AddHead(); + POSITION AddHead(INARGTYPE element); + void AddHeadList(const CAtlList* plNew); + POSITION AddTail(); + POSITION AddTail(INARGTYPE element); + void AddTailList(const CAtlList* plNew); + POSITION Find(INARGTYPE element, POSITION posStartAfter) const throw(); + POSITION FindIndex(size_t iElement) const throw(); + E& GetAt(POSITION pos) throw(); + const E& GetAt(POSITION pos) const throw(); + size_t GetCount() const throw(); + E& GetHead() throw(); + const E& GetHead() const throw(); + POSITION GetHeadPosition() const throw(); + E& GetNext(POSITION& pos) throw(); + const E& GetNext(POSITION& pos) const throw(); + E& GetPrev(POSITION& pos) throw(); + const E& GetPrev(POSITION& pos) const throw(); + E& GetTail() throw(); + const E& GetTail() const throw(); + POSITION GetTailPosition() const throw(); + POSITION InsertAfter(POSITION pos, INARGTYPE element); + POSITION InsertBefore(POSITION pos, INARGTYPE element); + bool IsEmpty() const throw(); + void MoveToHead(POSITION pos) throw(); + void MoveToTail(POSITION pos) throw(); + void RemoveAll() throw(); + void RemoveAt(POSITION pos) throw(); + E RemoveHead(); + void RemoveHeadNoReturn() throw(); + E RemoveTail(); + void RemoveTailNoReturn() throw(); + void SetAt(POSITION pos, INARGTYPE element); + void SwapElements(POSITION pos1, POSITION pos2) throw(); +}; + +void test_CAtlList() { + int x = source(); + { + CAtlList list(10); + sink(list.GetHead()); + list.AddHead(x); + sink(list.GetHead()); // $ MISSING: ir + + CAtlList list2(10); + list2.AddHeadList(&list); + sink(list2.GetHead()); // $ MISSING: ir + + CAtlList list3(10); + list3.AddTail(x); + sink(list3.GetHead()); // $ MISSING: ir + + CAtlList list4(10); + list4.AddTailList(&list3); + sink(list4.GetHead()); // $ MISSING: ir + + { + CAtlList list5(10); + auto pos = list5.Find(x, list5.GetHeadPosition()); + sink(list5.GetAt(pos)); // $ MISSING: ir + } + + { + CAtlList list6(10); + list6.AddHead(x); + auto pos = list6.FindIndex(0); + sink(list6.GetAt(pos)); // $ MISSING: ir + } + + { + CAtlList list7(10); + auto pos = list7.GetTailPosition(); + list7.InsertAfter(pos, x); + sink(list7.GetHead()); // $ MISSING: ir + } + + { + CAtlList list8(10); + auto pos = list8.GetTailPosition(); + list8.InsertBefore(pos, x); + sink(list8.GetHead()); // $ MISSING: ir + } + { + CAtlList list9(10); + list9.SetAt(list9.GetHeadPosition(), x); + sink(list9.GetHead()); // $ MISSING: ir + } + } + + int* p = indirect_source(); + { + CAtlList list(10); + sink(list.GetHead()); + list.AddHead(x); + sink(list.GetHead()); // $ MISSING: ir + + CAtlList list2(10); + list2.AddHeadList(&list); + sink(list2.GetHead()); // $ MISSING: ir + + CAtlList list3(10); + list3.AddTail(x); + sink(list3.GetHead()); // $ MISSING: ir + + CAtlList list4(10); + list4.AddTailList(&list3); + sink(list4.GetHead()); // $ MISSING: ir + + { + CAtlList list5(10); + auto pos = list5.Find(x, list5.GetHeadPosition()); + sink(list5.GetAt(pos)); // $ MISSING: ir + } + + { + CAtlList list6(10); + list6.AddHead(x); + auto pos = list6.FindIndex(0); + sink(list6.GetAt(pos)); // $ MISSING: ir + } + + { + CAtlList list7(10); + auto pos = list7.GetTailPosition(); + list7.InsertAfter(pos, x); + sink(list7.GetHead()); // $ MISSING: ir + } + + { + CAtlList list8(10); + auto pos = list8.GetTailPosition(); + list8.InsertBefore(pos, x); + sink(list8.GetHead()); // $ MISSING: ir + } + { + CAtlList list9(10); + list9.SetAt(list9.GetHeadPosition(), x); + sink(list9.GetHead()); // $ MISSING: ir + } + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index cd0b25deb453..5c7da7123ad4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -292,6 +292,220 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:248:5:248:6 | ref arg a6 | atl.cpp:249:10:249:11 | a6 | | | atl.cpp:248:5:248:6 | ref arg a6 | atl.cpp:250:3:250:3 | a6 | | | atl.cpp:249:10:249:11 | ref arg a6 | atl.cpp:250:3:250:3 | a6 | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:299:18:299:18 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:307:19:307:19 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:316:29:316:29 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:322:21:322:21 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:330:30:330:30 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:337:31:337:31 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:342:44:342:44 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:351:18:351:18 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:359:19:359:19 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:368:29:368:29 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:374:21:374:21 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:382:30:382:30 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:389:31:389:31 | x | | +| atl.cpp:295:11:295:21 | call to source | atl.cpp:394:44:394:44 | x | | +| atl.cpp:297:24:297:25 | 10 | atl.cpp:297:24:297:26 | call to CAtlList | TAINT | +| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:298:10:298:13 | list | | +| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:299:5:299:8 | list | | +| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:300:10:300:13 | list | | +| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:303:24:303:27 | list | | +| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:345:3:345:3 | list | | +| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:299:5:299:8 | list | | +| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:300:10:300:13 | list | | +| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:303:24:303:27 | list | | +| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:345:3:345:3 | list | | +| atl.cpp:299:5:299:8 | ref arg list | atl.cpp:300:10:300:13 | list | | +| atl.cpp:299:5:299:8 | ref arg list | atl.cpp:303:24:303:27 | list | | +| atl.cpp:299:5:299:8 | ref arg list | atl.cpp:345:3:345:3 | list | | +| atl.cpp:300:10:300:13 | ref arg list | atl.cpp:303:24:303:27 | list | | +| atl.cpp:300:10:300:13 | ref arg list | atl.cpp:345:3:345:3 | list | | +| atl.cpp:302:25:302:26 | 10 | atl.cpp:302:25:302:27 | call to CAtlList | TAINT | +| atl.cpp:302:25:302:27 | call to CAtlList | atl.cpp:303:5:303:9 | list2 | | +| atl.cpp:302:25:302:27 | call to CAtlList | atl.cpp:304:10:304:14 | list2 | | +| atl.cpp:302:25:302:27 | call to CAtlList | atl.cpp:345:3:345:3 | list2 | | +| atl.cpp:303:5:303:9 | ref arg list2 | atl.cpp:304:10:304:14 | list2 | | +| atl.cpp:303:5:303:9 | ref arg list2 | atl.cpp:345:3:345:3 | list2 | | +| atl.cpp:303:24:303:27 | list | atl.cpp:303:23:303:27 | & ... | | +| atl.cpp:304:10:304:14 | ref arg list2 | atl.cpp:345:3:345:3 | list2 | | +| atl.cpp:306:25:306:26 | 10 | atl.cpp:306:25:306:27 | call to CAtlList | TAINT | +| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:307:5:307:9 | list3 | | +| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:308:10:308:14 | list3 | | +| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:311:24:311:28 | list3 | | +| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:345:3:345:3 | list3 | | +| atl.cpp:307:5:307:9 | ref arg list3 | atl.cpp:308:10:308:14 | list3 | | +| atl.cpp:307:5:307:9 | ref arg list3 | atl.cpp:311:24:311:28 | list3 | | +| atl.cpp:307:5:307:9 | ref arg list3 | atl.cpp:345:3:345:3 | list3 | | +| atl.cpp:308:10:308:14 | ref arg list3 | atl.cpp:311:24:311:28 | list3 | | +| atl.cpp:308:10:308:14 | ref arg list3 | atl.cpp:345:3:345:3 | list3 | | +| atl.cpp:310:25:310:26 | 10 | atl.cpp:310:25:310:27 | call to CAtlList | TAINT | +| atl.cpp:310:25:310:27 | call to CAtlList | atl.cpp:311:5:311:9 | list4 | | +| atl.cpp:310:25:310:27 | call to CAtlList | atl.cpp:312:10:312:14 | list4 | | +| atl.cpp:310:25:310:27 | call to CAtlList | atl.cpp:345:3:345:3 | list4 | | +| atl.cpp:311:5:311:9 | ref arg list4 | atl.cpp:312:10:312:14 | list4 | | +| atl.cpp:311:5:311:9 | ref arg list4 | atl.cpp:345:3:345:3 | list4 | | +| atl.cpp:311:24:311:28 | list3 | atl.cpp:311:23:311:28 | & ... | | +| atl.cpp:312:10:312:14 | ref arg list4 | atl.cpp:345:3:345:3 | list4 | | +| atl.cpp:315:27:315:28 | 10 | atl.cpp:315:27:315:29 | call to CAtlList | TAINT | +| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:316:18:316:22 | list5 | | +| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:316:32:316:36 | list5 | | +| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:317:12:317:16 | list5 | | +| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:318:5:318:5 | list5 | | +| atl.cpp:316:18:316:22 | ref arg list5 | atl.cpp:317:12:317:16 | list5 | | +| atl.cpp:316:18:316:22 | ref arg list5 | atl.cpp:318:5:318:5 | list5 | | +| atl.cpp:316:24:316:27 | call to Find | atl.cpp:317:24:317:26 | pos | | +| atl.cpp:316:32:316:36 | ref arg list5 | atl.cpp:316:18:316:22 | list5 | | +| atl.cpp:316:32:316:36 | ref arg list5 | atl.cpp:317:12:317:16 | list5 | | +| atl.cpp:316:32:316:36 | ref arg list5 | atl.cpp:318:5:318:5 | list5 | | +| atl.cpp:317:12:317:16 | ref arg list5 | atl.cpp:318:5:318:5 | list5 | | +| atl.cpp:321:27:321:28 | 10 | atl.cpp:321:27:321:29 | call to CAtlList | TAINT | +| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:322:7:322:11 | list6 | | +| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:323:18:323:22 | list6 | | +| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:324:12:324:16 | list6 | | +| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:325:5:325:5 | list6 | | +| atl.cpp:322:7:322:11 | ref arg list6 | atl.cpp:323:18:323:22 | list6 | | +| atl.cpp:322:7:322:11 | ref arg list6 | atl.cpp:324:12:324:16 | list6 | | +| atl.cpp:322:7:322:11 | ref arg list6 | atl.cpp:325:5:325:5 | list6 | | +| atl.cpp:323:18:323:22 | ref arg list6 | atl.cpp:324:12:324:16 | list6 | | +| atl.cpp:323:18:323:22 | ref arg list6 | atl.cpp:325:5:325:5 | list6 | | +| atl.cpp:323:24:323:32 | call to FindIndex | atl.cpp:324:24:324:26 | pos | | +| atl.cpp:324:12:324:16 | ref arg list6 | atl.cpp:325:5:325:5 | list6 | | +| atl.cpp:328:27:328:28 | 10 | atl.cpp:328:27:328:29 | call to CAtlList | TAINT | +| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:329:18:329:22 | list7 | | +| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:330:7:330:11 | list7 | | +| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:331:12:331:16 | list7 | | +| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:332:5:332:5 | list7 | | +| atl.cpp:329:18:329:22 | ref arg list7 | atl.cpp:330:7:330:11 | list7 | | +| atl.cpp:329:18:329:22 | ref arg list7 | atl.cpp:331:12:331:16 | list7 | | +| atl.cpp:329:18:329:22 | ref arg list7 | atl.cpp:332:5:332:5 | list7 | | +| atl.cpp:329:24:329:38 | call to GetTailPosition | atl.cpp:330:25:330:27 | pos | | +| atl.cpp:330:7:330:11 | ref arg list7 | atl.cpp:331:12:331:16 | list7 | | +| atl.cpp:330:7:330:11 | ref arg list7 | atl.cpp:332:5:332:5 | list7 | | +| atl.cpp:331:12:331:16 | ref arg list7 | atl.cpp:332:5:332:5 | list7 | | +| atl.cpp:335:27:335:28 | 10 | atl.cpp:335:27:335:29 | call to CAtlList | TAINT | +| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:336:18:336:22 | list8 | | +| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:337:7:337:11 | list8 | | +| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:338:12:338:16 | list8 | | +| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:339:5:339:5 | list8 | | +| atl.cpp:336:18:336:22 | ref arg list8 | atl.cpp:337:7:337:11 | list8 | | +| atl.cpp:336:18:336:22 | ref arg list8 | atl.cpp:338:12:338:16 | list8 | | +| atl.cpp:336:18:336:22 | ref arg list8 | atl.cpp:339:5:339:5 | list8 | | +| atl.cpp:336:24:336:38 | call to GetTailPosition | atl.cpp:337:26:337:28 | pos | | +| atl.cpp:337:7:337:11 | ref arg list8 | atl.cpp:338:12:338:16 | list8 | | +| atl.cpp:337:7:337:11 | ref arg list8 | atl.cpp:339:5:339:5 | list8 | | +| atl.cpp:338:12:338:16 | ref arg list8 | atl.cpp:339:5:339:5 | list8 | | +| atl.cpp:341:27:341:28 | 10 | atl.cpp:341:27:341:29 | call to CAtlList | TAINT | +| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:342:7:342:11 | list9 | | +| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:342:19:342:23 | list9 | | +| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:343:12:343:16 | list9 | | +| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:344:5:344:5 | list9 | | +| atl.cpp:342:7:342:11 | ref arg list9 | atl.cpp:343:12:343:16 | list9 | | +| atl.cpp:342:7:342:11 | ref arg list9 | atl.cpp:344:5:344:5 | list9 | | +| atl.cpp:342:19:342:23 | ref arg list9 | atl.cpp:342:7:342:11 | list9 | | +| atl.cpp:342:19:342:23 | ref arg list9 | atl.cpp:343:12:343:16 | list9 | | +| atl.cpp:342:19:342:23 | ref arg list9 | atl.cpp:344:5:344:5 | list9 | | +| atl.cpp:343:12:343:16 | ref arg list9 | atl.cpp:344:5:344:5 | list9 | | +| atl.cpp:349:24:349:25 | 10 | atl.cpp:349:24:349:26 | call to CAtlList | TAINT | +| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:350:10:350:13 | list | | +| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:351:5:351:8 | list | | +| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:352:10:352:13 | list | | +| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:355:24:355:27 | list | | +| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:397:3:397:3 | list | | +| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:351:5:351:8 | list | | +| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:352:10:352:13 | list | | +| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:355:24:355:27 | list | | +| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:397:3:397:3 | list | | +| atl.cpp:351:5:351:8 | ref arg list | atl.cpp:352:10:352:13 | list | | +| atl.cpp:351:5:351:8 | ref arg list | atl.cpp:355:24:355:27 | list | | +| atl.cpp:351:5:351:8 | ref arg list | atl.cpp:397:3:397:3 | list | | +| atl.cpp:352:10:352:13 | ref arg list | atl.cpp:355:24:355:27 | list | | +| atl.cpp:352:10:352:13 | ref arg list | atl.cpp:397:3:397:3 | list | | +| atl.cpp:354:25:354:26 | 10 | atl.cpp:354:25:354:27 | call to CAtlList | TAINT | +| atl.cpp:354:25:354:27 | call to CAtlList | atl.cpp:355:5:355:9 | list2 | | +| atl.cpp:354:25:354:27 | call to CAtlList | atl.cpp:356:10:356:14 | list2 | | +| atl.cpp:354:25:354:27 | call to CAtlList | atl.cpp:397:3:397:3 | list2 | | +| atl.cpp:355:5:355:9 | ref arg list2 | atl.cpp:356:10:356:14 | list2 | | +| atl.cpp:355:5:355:9 | ref arg list2 | atl.cpp:397:3:397:3 | list2 | | +| atl.cpp:355:24:355:27 | list | atl.cpp:355:23:355:27 | & ... | | +| atl.cpp:356:10:356:14 | ref arg list2 | atl.cpp:397:3:397:3 | list2 | | +| atl.cpp:358:25:358:26 | 10 | atl.cpp:358:25:358:27 | call to CAtlList | TAINT | +| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:359:5:359:9 | list3 | | +| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:360:10:360:14 | list3 | | +| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:363:24:363:28 | list3 | | +| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:397:3:397:3 | list3 | | +| atl.cpp:359:5:359:9 | ref arg list3 | atl.cpp:360:10:360:14 | list3 | | +| atl.cpp:359:5:359:9 | ref arg list3 | atl.cpp:363:24:363:28 | list3 | | +| atl.cpp:359:5:359:9 | ref arg list3 | atl.cpp:397:3:397:3 | list3 | | +| atl.cpp:360:10:360:14 | ref arg list3 | atl.cpp:363:24:363:28 | list3 | | +| atl.cpp:360:10:360:14 | ref arg list3 | atl.cpp:397:3:397:3 | list3 | | +| atl.cpp:362:25:362:26 | 10 | atl.cpp:362:25:362:27 | call to CAtlList | TAINT | +| atl.cpp:362:25:362:27 | call to CAtlList | atl.cpp:363:5:363:9 | list4 | | +| atl.cpp:362:25:362:27 | call to CAtlList | atl.cpp:364:10:364:14 | list4 | | +| atl.cpp:362:25:362:27 | call to CAtlList | atl.cpp:397:3:397:3 | list4 | | +| atl.cpp:363:5:363:9 | ref arg list4 | atl.cpp:364:10:364:14 | list4 | | +| atl.cpp:363:5:363:9 | ref arg list4 | atl.cpp:397:3:397:3 | list4 | | +| atl.cpp:363:24:363:28 | list3 | atl.cpp:363:23:363:28 | & ... | | +| atl.cpp:364:10:364:14 | ref arg list4 | atl.cpp:397:3:397:3 | list4 | | +| atl.cpp:367:27:367:28 | 10 | atl.cpp:367:27:367:29 | call to CAtlList | TAINT | +| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:368:18:368:22 | list5 | | +| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:368:32:368:36 | list5 | | +| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:369:12:369:16 | list5 | | +| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:370:5:370:5 | list5 | | +| atl.cpp:368:18:368:22 | ref arg list5 | atl.cpp:369:12:369:16 | list5 | | +| atl.cpp:368:18:368:22 | ref arg list5 | atl.cpp:370:5:370:5 | list5 | | +| atl.cpp:368:24:368:27 | call to Find | atl.cpp:369:24:369:26 | pos | | +| atl.cpp:368:32:368:36 | ref arg list5 | atl.cpp:368:18:368:22 | list5 | | +| atl.cpp:368:32:368:36 | ref arg list5 | atl.cpp:369:12:369:16 | list5 | | +| atl.cpp:368:32:368:36 | ref arg list5 | atl.cpp:370:5:370:5 | list5 | | +| atl.cpp:369:12:369:16 | ref arg list5 | atl.cpp:370:5:370:5 | list5 | | +| atl.cpp:373:27:373:28 | 10 | atl.cpp:373:27:373:29 | call to CAtlList | TAINT | +| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:374:7:374:11 | list6 | | +| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:375:18:375:22 | list6 | | +| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:376:12:376:16 | list6 | | +| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:377:5:377:5 | list6 | | +| atl.cpp:374:7:374:11 | ref arg list6 | atl.cpp:375:18:375:22 | list6 | | +| atl.cpp:374:7:374:11 | ref arg list6 | atl.cpp:376:12:376:16 | list6 | | +| atl.cpp:374:7:374:11 | ref arg list6 | atl.cpp:377:5:377:5 | list6 | | +| atl.cpp:375:18:375:22 | ref arg list6 | atl.cpp:376:12:376:16 | list6 | | +| atl.cpp:375:18:375:22 | ref arg list6 | atl.cpp:377:5:377:5 | list6 | | +| atl.cpp:375:24:375:32 | call to FindIndex | atl.cpp:376:24:376:26 | pos | | +| atl.cpp:376:12:376:16 | ref arg list6 | atl.cpp:377:5:377:5 | list6 | | +| atl.cpp:380:27:380:28 | 10 | atl.cpp:380:27:380:29 | call to CAtlList | TAINT | +| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:381:18:381:22 | list7 | | +| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:382:7:382:11 | list7 | | +| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:383:12:383:16 | list7 | | +| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:384:5:384:5 | list7 | | +| atl.cpp:381:18:381:22 | ref arg list7 | atl.cpp:382:7:382:11 | list7 | | +| atl.cpp:381:18:381:22 | ref arg list7 | atl.cpp:383:12:383:16 | list7 | | +| atl.cpp:381:18:381:22 | ref arg list7 | atl.cpp:384:5:384:5 | list7 | | +| atl.cpp:381:24:381:38 | call to GetTailPosition | atl.cpp:382:25:382:27 | pos | | +| atl.cpp:382:7:382:11 | ref arg list7 | atl.cpp:383:12:383:16 | list7 | | +| atl.cpp:382:7:382:11 | ref arg list7 | atl.cpp:384:5:384:5 | list7 | | +| atl.cpp:383:12:383:16 | ref arg list7 | atl.cpp:384:5:384:5 | list7 | | +| atl.cpp:387:27:387:28 | 10 | atl.cpp:387:27:387:29 | call to CAtlList | TAINT | +| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:388:18:388:22 | list8 | | +| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:389:7:389:11 | list8 | | +| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:390:12:390:16 | list8 | | +| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:391:5:391:5 | list8 | | +| atl.cpp:388:18:388:22 | ref arg list8 | atl.cpp:389:7:389:11 | list8 | | +| atl.cpp:388:18:388:22 | ref arg list8 | atl.cpp:390:12:390:16 | list8 | | +| atl.cpp:388:18:388:22 | ref arg list8 | atl.cpp:391:5:391:5 | list8 | | +| atl.cpp:388:24:388:38 | call to GetTailPosition | atl.cpp:389:26:389:28 | pos | | +| atl.cpp:389:7:389:11 | ref arg list8 | atl.cpp:390:12:390:16 | list8 | | +| atl.cpp:389:7:389:11 | ref arg list8 | atl.cpp:391:5:391:5 | list8 | | +| atl.cpp:390:12:390:16 | ref arg list8 | atl.cpp:391:5:391:5 | list8 | | +| atl.cpp:393:27:393:28 | 10 | atl.cpp:393:27:393:29 | call to CAtlList | TAINT | +| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:394:7:394:11 | list9 | | +| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:394:19:394:23 | list9 | | +| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:395:12:395:16 | list9 | | +| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:396:5:396:5 | list9 | | +| atl.cpp:394:7:394:11 | ref arg list9 | atl.cpp:395:12:395:16 | list9 | | +| atl.cpp:394:7:394:11 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | +| atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:394:7:394:11 | list9 | | +| atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:395:12:395:16 | list9 | | +| atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | +| atl.cpp:395:12:395:16 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 2b8ef5a8c8c0c464ef97b1cc4c76107a416e85cc Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 11:39:26 +0000 Subject: [PATCH 013/213] C++: Add MaD model for 'CAtlList'. --- cpp/ql/lib/ext/CAtlList.model.yml | 25 +++++++++++++++ .../dataflow/taint-tests/atl.cpp | 32 +++++++++---------- 2 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 cpp/ql/lib/ext/CAtlList.model.yml diff --git a/cpp/ql/lib/ext/CAtlList.model.yml b/cpp/ql/lib/ext/CAtlList.model.yml new file mode 100644 index 000000000000..eb59fb8417ed --- /dev/null +++ b/cpp/ql/lib/ext/CAtlList.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CAtlList", True, "AddHead", "", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlList", True, "AddHeadList", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlList", True, "AddTail", "", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlList", True, "AddTailList", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlList", True, "FindIndex", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["", "CAtlList", True, "GetAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CAtlList", True, "GetAt", "", "", "Argument[0]", "ReturnValue[*@]", "taint", "manual"] + - ["", "CAtlList", True, "GetHead", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CAtlList", True, "GetHeadPosition", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CAtlList", True, "GetNext", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CAtlList", True, "GetPrev", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CAtlList", True, "GetTail", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CAtlList", True, "GetTailPosition", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CAtlList", True, "InsertAfter", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlList", True, "InsertAfter", "", "", "Argument[*@1]", "ReturnValue", "taint", "manual"] + - ["", "CAtlList", True, "InsertBefore", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CAtlList", True, "InsertBefore", "", "", "Argument[*@1]", "ReturnValue", "taint", "manual"] + - ["", "CAtlList", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "taint", "manual"] + - ["", "CAtlList", True, "SwapElements", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["", "CAtlList", True, "SwapElements", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index b1231c13c485..fe7a5513ce7c 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -297,19 +297,19 @@ void test_CAtlList() { CAtlList list(10); sink(list.GetHead()); list.AddHead(x); - sink(list.GetHead()); // $ MISSING: ir + sink(list.GetHead()); // $ ir CAtlList list2(10); list2.AddHeadList(&list); - sink(list2.GetHead()); // $ MISSING: ir + sink(list2.GetHead()); // $ ir CAtlList list3(10); list3.AddTail(x); - sink(list3.GetHead()); // $ MISSING: ir + sink(list3.GetHead()); // $ ir CAtlList list4(10); list4.AddTailList(&list3); - sink(list4.GetHead()); // $ MISSING: ir + sink(list4.GetHead()); // $ ir { CAtlList list5(10); @@ -321,26 +321,26 @@ void test_CAtlList() { CAtlList list6(10); list6.AddHead(x); auto pos = list6.FindIndex(0); - sink(list6.GetAt(pos)); // $ MISSING: ir + sink(list6.GetAt(pos)); // $ ir } { CAtlList list7(10); auto pos = list7.GetTailPosition(); list7.InsertAfter(pos, x); - sink(list7.GetHead()); // $ MISSING: ir + sink(list7.GetHead()); // $ ir } { CAtlList list8(10); auto pos = list8.GetTailPosition(); list8.InsertBefore(pos, x); - sink(list8.GetHead()); // $ MISSING: ir + sink(list8.GetHead()); // $ ir } { CAtlList list9(10); list9.SetAt(list9.GetHeadPosition(), x); - sink(list9.GetHead()); // $ MISSING: ir + sink(list9.GetHead()); // $ ir } } @@ -349,19 +349,19 @@ void test_CAtlList() { CAtlList list(10); sink(list.GetHead()); list.AddHead(x); - sink(list.GetHead()); // $ MISSING: ir + sink(list.GetHead()); // $ ir CAtlList list2(10); list2.AddHeadList(&list); - sink(list2.GetHead()); // $ MISSING: ir + sink(list2.GetHead()); // $ ir CAtlList list3(10); list3.AddTail(x); - sink(list3.GetHead()); // $ MISSING: ir + sink(list3.GetHead()); // $ ir CAtlList list4(10); list4.AddTailList(&list3); - sink(list4.GetHead()); // $ MISSING: ir + sink(list4.GetHead()); // $ ir { CAtlList list5(10); @@ -373,26 +373,26 @@ void test_CAtlList() { CAtlList list6(10); list6.AddHead(x); auto pos = list6.FindIndex(0); - sink(list6.GetAt(pos)); // $ MISSING: ir + sink(list6.GetAt(pos)); // $ ir } { CAtlList list7(10); auto pos = list7.GetTailPosition(); list7.InsertAfter(pos, x); - sink(list7.GetHead()); // $ MISSING: ir + sink(list7.GetHead()); // $ ir } { CAtlList list8(10); auto pos = list8.GetTailPosition(); list8.InsertBefore(pos, x); - sink(list8.GetHead()); // $ MISSING: ir + sink(list8.GetHead()); // $ ir } { CAtlList list9(10); list9.SetAt(list9.GetHeadPosition(), x); - sink(list9.GetHead()); // $ MISSING: ir + sink(list9.GetHead()); // $ ir } } } From 68ee8da574f56f160d61371f6eac44801c2ae2ad Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 12:04:29 +0000 Subject: [PATCH 014/213] C++: Add failing tests with 'CComBSTR'. --- .../dataflow/taint-tests/atl.cpp | 129 +++++++++++++++++ .../dataflow/taint-tests/localTaint.expected | 130 ++++++++++++++++++ 2 files changed, 259 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index fe7a5513ce7c..0eb636082e22 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -396,3 +396,132 @@ void test_CAtlList() { } } } + +struct IUnknown { }; + +struct ISequentialStream : public IUnknown { }; + +struct IStream : public ISequentialStream { }; + +struct CComBSTR { + CComBSTR() throw(); + CComBSTR(const CComBSTR& src); + CComBSTR(int nSize); + CComBSTR(int nSize, LPCOLESTR sz); + CComBSTR(int nSize, LPCSTR sz); + CComBSTR(LPCOLESTR pSrc); + CComBSTR(LPCSTR pSrc); + CComBSTR(CComBSTR&& src) throw(); + ~CComBSTR(); + + HRESULT Append(const CComBSTR& bstrSrc) throw(); + HRESULT Append(wchar_t ch) throw(); + HRESULT Append(char ch) throw(); + HRESULT Append(LPCOLESTR lpsz) throw(); + HRESULT Append(LPCSTR lpsz) throw(); + HRESULT Append(LPCOLESTR lpsz, int nLen) throw(); + HRESULT AppendBSTR(BSTR p) throw(); + HRESULT AppendBytes(const char* lpsz, int nLen) throw(); + HRESULT ArrayToBSTR(const SAFEARRAY* pSrc) throw(); + HRESULT AssignBSTR(const BSTR bstrSrc) throw(); + void Attach(BSTR src) throw(); + HRESULT BSTRToArray(LPSAFEARRAY ppArray) throw(); + unsigned int ByteLength() const throw(); + BSTR Copy() const throw(); + HRESULT CopyTo(BSTR* pbstr) throw(); + + HRESULT CopyTo(VARIANT* pvarDest) throw(); + BSTR Detach() throw(); + void Empty() throw(); + unsigned int Length() const throw(); + bool LoadString(HINSTANCE hInst, UINT nID) throw(); + bool LoadString(UINT nID) throw(); + HRESULT ReadFromStream(IStream* pStream) throw(); + HRESULT ToUpper() throw(); + HRESULT WriteToStream(IStream* pStream) throw(); + + operator BSTR() const throw(); + BSTR* operator&() throw(); + + CComBSTR& operator+= (const CComBSTR& bstrSrc); + CComBSTR& operator+= (const LPCOLESTR pszSrc); + + BSTR m_str; +}; + +LPSAFEARRAY getSafeArray() { + SAFEARRAY* safe = new SAFEARRAY; + safe->pvData = indirect_source(); + return safe; +} + +void test_CComBSTR() { + char* x = indirect_source(); + { + CComBSTR b(x); + sink(b.m_str); // $ MISSING: ir + + CComBSTR b2(b); + sink(b2.m_str); // $ MISSING: ir + } + { + CComBSTR b(10, x); + sink(b.m_str); // $ MISSING: ir + } + { + CComBSTR b(x); + + CComBSTR b2; + sink(b2.m_str); + b2 += b; + sink(b2.m_str); // $ MISSING: ir + + CComBSTR b3; + b3 += x; + sink(b3.m_str); // $ MISSING: ir + sink(static_cast(b3)); // $ MISSING: ir + sink(**&b3); // $ MISSING: ir + + CComBSTR b4; + b4.Append(source()); + sink(b4.m_str); // $ MISSING: ir + + CComBSTR b5; + b5.AppendBSTR(b4.m_str); + sink(b5.m_str); // $ MISSING: ir + + CComBSTR b6; + b6.AppendBytes(x, 10); + sink(b6.m_str); // $ MISSING: ir + + CComBSTR b7; + b7.ArrayToBSTR(getSafeArray()); + sink(b7.m_str); // $ MISSING: ir + + CComBSTR b8; + b8.AssignBSTR(b7.m_str); + sink(b8.m_str); // $ MISSING: ir + + CComBSTR b9; + SAFEARRAY safe; + b9.Append(source()); + b9.BSTRToArray(&safe); + sink(safe.pvData); // $ MISSING: ir + + sink(b9.Copy()); // $ MISSING: ir + } + + wchar_t* w = indirect_source(); + { + CComBSTR b(w); + sink(b.m_str); // $ MISSING: ir + + CComBSTR b2; + b2.Attach(w); + sink(b2.m_str); // $ MISSING: ir + } + { + CComBSTR b(10, w); + sink(b.m_str); // $ MISSING: ir + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 5c7da7123ad4..becba8e527b8 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -506,6 +506,136 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:395:12:395:16 | list9 | | | atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | | atl.cpp:395:12:395:16 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | +| atl.cpp:453:21:453:33 | new | atl.cpp:454:3:454:6 | safe | | +| atl.cpp:453:21:453:33 | new | atl.cpp:455:10:455:13 | safe | | +| atl.cpp:454:3:454:6 | safe [post update] | atl.cpp:455:10:455:13 | safe | | +| atl.cpp:454:3:454:40 | ... = ... | atl.cpp:454:9:454:14 | pvData [post update] | | +| atl.cpp:454:18:454:38 | call to indirect_source | atl.cpp:454:3:454:40 | ... = ... | | +| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:461:16:461:16 | x | | +| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:468:20:468:20 | x | | +| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:472:16:472:16 | x | | +| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:480:11:480:11 | x | | +| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:494:20:494:20 | x | | +| atl.cpp:461:16:461:16 | x | atl.cpp:461:16:461:17 | call to CComBSTR | TAINT | +| atl.cpp:461:16:461:17 | call to CComBSTR | atl.cpp:462:10:462:10 | b | | +| atl.cpp:461:16:461:17 | call to CComBSTR | atl.cpp:464:17:464:17 | b | | +| atl.cpp:461:16:461:17 | call to CComBSTR | atl.cpp:466:3:466:3 | b | | +| atl.cpp:462:10:462:10 | b [post update] | atl.cpp:464:17:464:17 | b | | +| atl.cpp:462:10:462:10 | b [post update] | atl.cpp:466:3:466:3 | b | | +| atl.cpp:462:12:462:16 | ref arg m_str | atl.cpp:465:13:465:17 | m_str | | +| atl.cpp:464:17:464:17 | b | atl.cpp:464:17:464:18 | call to CComBSTR | | +| atl.cpp:464:17:464:18 | call to CComBSTR | atl.cpp:465:10:465:11 | b2 | | +| atl.cpp:464:17:464:18 | call to CComBSTR | atl.cpp:466:3:466:3 | b2 | | +| atl.cpp:465:10:465:11 | b2 [post update] | atl.cpp:466:3:466:3 | b2 | | +| atl.cpp:468:16:468:21 | call to CComBSTR | atl.cpp:469:10:469:10 | b | | +| atl.cpp:468:16:468:21 | call to CComBSTR | atl.cpp:470:3:470:3 | b | | +| atl.cpp:469:10:469:10 | b [post update] | atl.cpp:470:3:470:3 | b | | +| atl.cpp:472:16:472:16 | x | atl.cpp:472:16:472:17 | call to CComBSTR | TAINT | +| atl.cpp:472:16:472:17 | call to CComBSTR | atl.cpp:476:11:476:11 | b | | +| atl.cpp:472:16:472:17 | call to CComBSTR | atl.cpp:512:3:512:3 | b | | +| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:475:10:475:11 | b2 | | +| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:476:5:476:6 | b2 | | +| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:477:10:477:11 | b2 | | +| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b2 | | +| atl.cpp:475:10:475:11 | b2 [post update] | atl.cpp:476:5:476:6 | b2 | | +| atl.cpp:475:10:475:11 | b2 [post update] | atl.cpp:477:10:477:11 | b2 | | +| atl.cpp:475:10:475:11 | b2 [post update] | atl.cpp:512:3:512:3 | b2 | | +| atl.cpp:475:13:475:17 | ref arg m_str | atl.cpp:477:13:477:17 | m_str | | +| atl.cpp:476:5:476:6 | ref arg b2 | atl.cpp:477:10:477:11 | b2 | | +| atl.cpp:476:5:476:6 | ref arg b2 | atl.cpp:512:3:512:3 | b2 | | +| atl.cpp:477:10:477:11 | b2 [post update] | atl.cpp:512:3:512:3 | b2 | | +| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:480:5:480:6 | b3 | | +| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:481:10:481:11 | b3 | | +| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:482:28:482:29 | b3 | | +| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:483:13:483:14 | b3 | | +| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b3 | | +| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:481:10:481:11 | b3 | | +| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:482:28:482:29 | b3 | | +| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:483:13:483:14 | b3 | | +| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:512:3:512:3 | b3 | | +| atl.cpp:480:11:480:11 | x | atl.cpp:480:11:480:11 | call to CComBSTR | TAINT | +| atl.cpp:481:10:481:11 | b3 [post update] | atl.cpp:482:28:482:29 | b3 | | +| atl.cpp:481:10:481:11 | b3 [post update] | atl.cpp:483:13:483:14 | b3 | | +| atl.cpp:481:10:481:11 | b3 [post update] | atl.cpp:512:3:512:3 | b3 | | +| atl.cpp:482:28:482:29 | ref arg b3 | atl.cpp:483:13:483:14 | b3 | | +| atl.cpp:482:28:482:29 | ref arg b3 | atl.cpp:512:3:512:3 | b3 | | +| atl.cpp:483:11:483:14 | * ... | atl.cpp:483:10:483:14 | * ... | TAINT | +| atl.cpp:483:12:483:12 | call to operator& | atl.cpp:483:11:483:14 | * ... | TAINT | +| atl.cpp:483:13:483:14 | ref arg b3 | atl.cpp:512:3:512:3 | b3 | | +| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:486:5:486:6 | b4 | | +| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:487:10:487:11 | b4 | | +| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:490:19:490:20 | b4 | | +| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b4 | | +| atl.cpp:486:5:486:6 | ref arg b4 | atl.cpp:487:10:487:11 | b4 | | +| atl.cpp:486:5:486:6 | ref arg b4 | atl.cpp:490:19:490:20 | b4 | | +| atl.cpp:486:5:486:6 | ref arg b4 | atl.cpp:512:3:512:3 | b4 | | +| atl.cpp:487:10:487:11 | b4 [post update] | atl.cpp:490:19:490:20 | b4 | | +| atl.cpp:487:10:487:11 | b4 [post update] | atl.cpp:512:3:512:3 | b4 | | +| atl.cpp:487:13:487:17 | ref arg m_str | atl.cpp:490:22:490:26 | m_str | | +| atl.cpp:489:14:489:15 | call to CComBSTR | atl.cpp:490:5:490:6 | b5 | | +| atl.cpp:489:14:489:15 | call to CComBSTR | atl.cpp:491:10:491:11 | b5 | | +| atl.cpp:489:14:489:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b5 | | +| atl.cpp:490:5:490:6 | ref arg b5 | atl.cpp:491:10:491:11 | b5 | | +| atl.cpp:490:5:490:6 | ref arg b5 | atl.cpp:512:3:512:3 | b5 | | +| atl.cpp:490:19:490:20 | b4 [post update] | atl.cpp:512:3:512:3 | b4 | | +| atl.cpp:491:10:491:11 | b5 [post update] | atl.cpp:512:3:512:3 | b5 | | +| atl.cpp:493:14:493:15 | call to CComBSTR | atl.cpp:494:5:494:6 | b6 | | +| atl.cpp:493:14:493:15 | call to CComBSTR | atl.cpp:495:10:495:11 | b6 | | +| atl.cpp:493:14:493:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b6 | | +| atl.cpp:494:5:494:6 | ref arg b6 | atl.cpp:495:10:495:11 | b6 | | +| atl.cpp:494:5:494:6 | ref arg b6 | atl.cpp:512:3:512:3 | b6 | | +| atl.cpp:495:10:495:11 | b6 [post update] | atl.cpp:512:3:512:3 | b6 | | +| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:498:5:498:6 | b7 | | +| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:499:10:499:11 | b7 | | +| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:502:19:502:20 | b7 | | +| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b7 | | +| atl.cpp:498:5:498:6 | ref arg b7 | atl.cpp:499:10:499:11 | b7 | | +| atl.cpp:498:5:498:6 | ref arg b7 | atl.cpp:502:19:502:20 | b7 | | +| atl.cpp:498:5:498:6 | ref arg b7 | atl.cpp:512:3:512:3 | b7 | | +| atl.cpp:499:10:499:11 | b7 [post update] | atl.cpp:502:19:502:20 | b7 | | +| atl.cpp:499:10:499:11 | b7 [post update] | atl.cpp:512:3:512:3 | b7 | | +| atl.cpp:499:13:499:17 | ref arg m_str | atl.cpp:502:22:502:26 | m_str | | +| atl.cpp:501:14:501:15 | call to CComBSTR | atl.cpp:502:5:502:6 | b8 | | +| atl.cpp:501:14:501:15 | call to CComBSTR | atl.cpp:503:10:503:11 | b8 | | +| atl.cpp:501:14:501:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b8 | | +| atl.cpp:502:5:502:6 | ref arg b8 | atl.cpp:503:10:503:11 | b8 | | +| atl.cpp:502:5:502:6 | ref arg b8 | atl.cpp:512:3:512:3 | b8 | | +| atl.cpp:502:19:502:20 | b7 [post update] | atl.cpp:512:3:512:3 | b7 | | +| atl.cpp:503:10:503:11 | b8 [post update] | atl.cpp:512:3:512:3 | b8 | | +| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:507:5:507:6 | b9 | | +| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:508:5:508:6 | b9 | | +| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:511:10:511:11 | b9 | | +| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b9 | | +| atl.cpp:506:15:506:18 | safe | atl.cpp:508:21:508:24 | safe | | +| atl.cpp:506:15:506:18 | safe | atl.cpp:509:10:509:13 | safe | | +| atl.cpp:507:5:507:6 | ref arg b9 | atl.cpp:508:5:508:6 | b9 | | +| atl.cpp:507:5:507:6 | ref arg b9 | atl.cpp:511:10:511:11 | b9 | | +| atl.cpp:507:5:507:6 | ref arg b9 | atl.cpp:512:3:512:3 | b9 | | +| atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:511:10:511:11 | b9 | | +| atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:512:3:512:3 | b9 | | +| atl.cpp:508:20:508:24 | ref arg & ... | atl.cpp:508:21:508:24 | safe [inner post update] | | +| atl.cpp:508:20:508:24 | ref arg & ... | atl.cpp:509:10:509:13 | safe | | +| atl.cpp:508:21:508:24 | safe | atl.cpp:508:20:508:24 | & ... | | +| atl.cpp:511:10:511:11 | ref arg b9 | atl.cpp:512:3:512:3 | b9 | | +| atl.cpp:514:16:514:39 | call to indirect_source | atl.cpp:516:16:516:16 | w | | +| atl.cpp:514:16:514:39 | call to indirect_source | atl.cpp:520:15:520:15 | w | | +| atl.cpp:514:16:514:39 | call to indirect_source | atl.cpp:524:20:524:20 | w | | +| atl.cpp:516:16:516:16 | ref arg w | atl.cpp:520:15:520:15 | w | | +| atl.cpp:516:16:516:16 | ref arg w | atl.cpp:524:20:524:20 | w | | +| atl.cpp:516:16:516:16 | w | atl.cpp:516:16:516:17 | call to CComBSTR | TAINT | +| atl.cpp:516:16:516:17 | call to CComBSTR | atl.cpp:517:10:517:10 | b | | +| atl.cpp:516:16:516:17 | call to CComBSTR | atl.cpp:522:3:522:3 | b | | +| atl.cpp:517:10:517:10 | b [post update] | atl.cpp:522:3:522:3 | b | | +| atl.cpp:519:14:519:15 | call to CComBSTR | atl.cpp:520:5:520:6 | b2 | | +| atl.cpp:519:14:519:15 | call to CComBSTR | atl.cpp:521:10:521:11 | b2 | | +| atl.cpp:519:14:519:15 | call to CComBSTR | atl.cpp:522:3:522:3 | b2 | | +| atl.cpp:520:5:520:6 | ref arg b2 | atl.cpp:521:10:521:11 | b2 | | +| atl.cpp:520:5:520:6 | ref arg b2 | atl.cpp:522:3:522:3 | b2 | | +| atl.cpp:520:15:520:15 | ref arg w | atl.cpp:524:20:524:20 | w | | +| atl.cpp:521:10:521:11 | b2 [post update] | atl.cpp:522:3:522:3 | b2 | | +| atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:525:10:525:10 | b | | +| atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:526:3:526:3 | b | | +| atl.cpp:525:10:525:10 | b [post update] | atl.cpp:526:3:526:3 | b | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 9b004848a32533216fd40602e9acc792437b6e01 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 12:07:01 +0000 Subject: [PATCH 015/213] C++: Add MaD model for 'CComBSTR'. --- cpp/ql/lib/ext/CComBSTR.model.yml | 33 +++++++++++++++++++ .../dataflow/taint-tests/atl.cpp | 8 ++--- 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 cpp/ql/lib/ext/CComBSTR.model.yml diff --git a/cpp/ql/lib/ext/CComBSTR.model.yml b/cpp/ql/lib/ext/CComBSTR.model.yml new file mode 100644 index 000000000000..b578956edec2 --- /dev/null +++ b/cpp/ql/lib/ext/CComBSTR.model.yml @@ -0,0 +1,33 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CComBSTR", True, "CComBSTR", "(LPCSTR)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "CComBSTR", "(LPCOLESTR)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "CComBSTR", "(int,LPCSTR)", "", "Argument[*1]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "CComBSTR", "(int,LPCOLESTR)", "", "Argument[*1]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "CComBSTR", "(const CComBSTR&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "Append", "(const CComBSTR&)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "Append", "(wchar_t)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "Append", "(char)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "Append", "(LPCOLESTR)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "Append", "(LPCSTR)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "Append", "(LPCOLESTR,int)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "AppendBytes", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "AppendBSTR", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "ArrayToBSTR", "", "", "Argument[*0].Field[*pvData]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "AssignBSTR", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "Attach", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "BSTRToArray", "", "", "Argument[-1]", "Argument[*0].Field[*pvData]", "value", "manual"] + - ["", "CComBSTR", True, "Copy", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] + - ["", "CComBSTR", True, "CopyTo", "", "", "Argument[-1]", "Argument[*0]", "value", "manual"] + - ["", "CComBSTR", True, "LoadString", "(HINSTANCE,UINT)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "LoadString", "(UINT)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "ReadFromStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "ReadFromStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "WriteToStream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"] + - ["", "CComBSTR", True, "operator BSTR", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CComBSTR", True, "operator&", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CComBSTR", True, "operator+=", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"] + - ["", "CComBSTR", True, "operator+=", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 0eb636082e22..bade135966b4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -479,8 +479,8 @@ void test_CComBSTR() { CComBSTR b3; b3 += x; sink(b3.m_str); // $ MISSING: ir - sink(static_cast(b3)); // $ MISSING: ir - sink(**&b3); // $ MISSING: ir + sink(static_cast(b3)); // $ ir + sink(**&b3); // $ ir CComBSTR b4; b4.Append(source()); @@ -506,9 +506,9 @@ void test_CComBSTR() { SAFEARRAY safe; b9.Append(source()); b9.BSTRToArray(&safe); - sink(safe.pvData); // $ MISSING: ir + sink(safe.pvData); // $ ir - sink(b9.Copy()); // $ MISSING: ir + sink(b9.Copy()); // $ ir } wchar_t* w = indirect_source(); From 948be092575f46d24d37c44e0672181809f11f48 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 13:38:38 +0000 Subject: [PATCH 016/213] C++: Add an taint step from object to field for 'CComBSTR's. --- cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../cpp/models/implementations/CComBSTR.qll | 16 ++++++++++++ .../dataflow/taint-tests/atl.cpp | 26 +++++++++---------- 3 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/CComBSTR.qll diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index bb63416eaefa..9e67eaae5cf3 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -51,3 +51,4 @@ private import implementations.StructuredExceptionHandling private import implementations.ZMQ private import implementations.Win32CommandExecution private import implementations.CA2AEX +private import implementations.CComBSTR diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/CComBSTR.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/CComBSTR.qll new file mode 100644 index 000000000000..55d18a52ae45 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/CComBSTR.qll @@ -0,0 +1,16 @@ +private import cpp +private import semmle.code.cpp.ir.dataflow.FlowSteps +private import semmle.code.cpp.dataflow.new.DataFlow + +/** The `CComBSTR` class from the Microsoft "Active Template Library". */ +class CcomBstr extends Class { + CcomBstr() { this.hasGlobalName("CComBSTR") } +} + +private class Mstr extends Field { + Mstr() { this.getDeclaringType() instanceof CcomBstr and this.hasName("m_str") } +} + +private class MstrTaintInheritingContent extends TaintInheritingContent, DataFlow::FieldContent { + MstrTaintInheritingContent() { this.getField() instanceof Mstr } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index bade135966b4..c89b649ec9ae 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -459,14 +459,14 @@ void test_CComBSTR() { char* x = indirect_source(); { CComBSTR b(x); - sink(b.m_str); // $ MISSING: ir + sink(b.m_str); // $ ir CComBSTR b2(b); - sink(b2.m_str); // $ MISSING: ir + sink(b2.m_str); // $ ir } { CComBSTR b(10, x); - sink(b.m_str); // $ MISSING: ir + sink(b.m_str); // $ ir } { CComBSTR b(x); @@ -474,33 +474,33 @@ void test_CComBSTR() { CComBSTR b2; sink(b2.m_str); b2 += b; - sink(b2.m_str); // $ MISSING: ir + sink(b2.m_str); // $ ir CComBSTR b3; b3 += x; - sink(b3.m_str); // $ MISSING: ir + sink(b3.m_str); // $ ir sink(static_cast(b3)); // $ ir sink(**&b3); // $ ir CComBSTR b4; b4.Append(source()); - sink(b4.m_str); // $ MISSING: ir + sink(b4.m_str); // $ ir CComBSTR b5; b5.AppendBSTR(b4.m_str); - sink(b5.m_str); // $ MISSING: ir + sink(b5.m_str); // $ ir CComBSTR b6; b6.AppendBytes(x, 10); - sink(b6.m_str); // $ MISSING: ir + sink(b6.m_str); // $ ir CComBSTR b7; b7.ArrayToBSTR(getSafeArray()); - sink(b7.m_str); // $ MISSING: ir + sink(b7.m_str); // $ ir CComBSTR b8; b8.AssignBSTR(b7.m_str); - sink(b8.m_str); // $ MISSING: ir + sink(b8.m_str); // $ ir CComBSTR b9; SAFEARRAY safe; @@ -514,14 +514,14 @@ void test_CComBSTR() { wchar_t* w = indirect_source(); { CComBSTR b(w); - sink(b.m_str); // $ MISSING: ir + sink(b.m_str); // $ ir CComBSTR b2; b2.Attach(w); - sink(b2.m_str); // $ MISSING: ir + sink(b2.m_str); // $ ir } { CComBSTR b(10, w); - sink(b.m_str); // $ MISSING: ir + sink(b.m_str); // $ ir } } From e831cb5f2647ff59a98f5c9ea11e15e3dc61ce33 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 13:42:23 +0000 Subject: [PATCH 017/213] C++: Add failing tests with 'CComSafeArray'. --- .../dataflow/taint-tests/atl.cpp | 77 +++++++++++++++++ .../dataflow/taint-tests/localTaint.expected | 86 +++++++++++++++++++ 2 files changed, 163 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index c89b649ec9ae..a91cd9c88d6f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -525,3 +525,80 @@ void test_CComBSTR() { sink(b.m_str); // $ ir } } + +template +struct CComSafeArray { + CComSafeArray(); + CComSafeArray(const SAFEARRAYBOUND& bound); + CComSafeArray(ULONG ulCount, LONG lLBound); + CComSafeArray(const SAFEARRAYBOUND* pBound, UINT uDims); + CComSafeArray(const CComSafeArray& saSrc); + CComSafeArray(const SAFEARRAY& saSrc); + CComSafeArray(const SAFEARRAY* psaSrc); + + ~CComSafeArray() throw(); + + HRESULT Add(const SAFEARRAY* psaSrc); + HRESULT Add(ULONG ulCount, const T* pT, BOOL bCopy); + HRESULT Add(const T& t, BOOL bCopy); + HRESULT Attach(const SAFEARRAY* psaSrc); + HRESULT CopyFrom(LPSAFEARRAY* ppArray); + HRESULT CopyTo(LPSAFEARRAY* ppArray); + HRESULT Create(const SAFEARRAYBOUND* pBound, UINT uDims); + HRESULT Create(ULONG ulCount, LONG lLBound); + HRESULT Destroy(); + LPSAFEARRAY Detach(); + T& GetAt(LONG lIndex) const; + ULONG GetCount(UINT uDim) const; + UINT GetDimensions() const; + LONG GetLowerBound(UINT uDim) const; + LPSAFEARRAY GetSafeArrayPtr() throw(); + LONG GetUpperBound(UINT uDim) const; + bool IsSizable() const; + HRESULT MultiDimGetAt(const LONG* alIndex, T& t); + HRESULT MultiDimSetAt(const LONG* alIndex, const T& t); + HRESULT Resize(const SAFEARRAYBOUND* pBound); + HRESULT Resize(ULONG ulCount, LONG lLBound); + HRESULT SetAt(LONG lIndex, const T& t, BOOL bCopy); + operator LPSAFEARRAY() const; + T& operator[](long lindex) const; + T& operator[](int nindex) const; + + LPSAFEARRAY m_psa; +}; + +void test_CComSafeArray() { + LPSAFEARRAY safe = getSafeArray(); + sink(safe->pvData); // $ ir + { + CComSafeArray c(safe); + sink(c[0]); // $ MISSING: ir + sink(c.GetAt(0)); // $ MISSING: ir + sink(c.GetSafeArrayPtr()->pvData); // $ MISSING: ir + sink(c.m_psa->pvData); // $ MISSING: ir + } + { + CComSafeArray c; + sink(c[0]); + sink(c.GetAt(0)); + sink(c.GetSafeArrayPtr()->pvData); + c.Add(safe); + sink(c[0]); // $ MISSING: ir + sink(c.GetAt(0)); // $ MISSING: ir + sink(c.GetSafeArrayPtr()->pvData); // $ MISSING: ir + sink(static_cast(c)->pvData); // $ MISSING: ir + } + { + CComSafeArray c; + c.Add(source(), true); + sink(c[0]); // $ MISSING: ir + sink(c.GetAt(0)); // $ MISSING: ir + sink(c.GetSafeArrayPtr()->pvData); // $ MISSING: ir + } + { + CComSafeArray c; + c.SetAt(0, source(), true); + sink(c[0]); // $ MISSING: ir + sink(c[0L]); // $ MISSING: ir + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index becba8e527b8..4924d7d817f3 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -636,6 +636,92 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:525:10:525:10 | b | | | atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:526:3:526:3 | b | | | atl.cpp:525:10:525:10 | b [post update] | atl.cpp:526:3:526:3 | b | | +| atl.cpp:569:22:569:33 | call to getSafeArray | atl.cpp:570:8:570:11 | safe | | +| atl.cpp:569:22:569:33 | call to getSafeArray | atl.cpp:572:24:572:27 | safe | | +| atl.cpp:569:22:569:33 | call to getSafeArray | atl.cpp:582:11:582:14 | safe | | +| atl.cpp:570:8:570:11 | safe [post update] | atl.cpp:572:24:572:27 | safe | | +| atl.cpp:570:8:570:11 | safe [post update] | atl.cpp:582:11:582:14 | safe | | +| atl.cpp:572:24:572:27 | safe | atl.cpp:572:24:572:28 | call to CComSafeArray | TAINT | +| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:573:8:573:8 | c | | +| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:574:8:574:8 | c | | +| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:575:8:575:8 | c | | +| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:576:3:576:3 | c | | +| atl.cpp:573:8:573:8 | ref arg c | atl.cpp:574:8:574:8 | c | | +| atl.cpp:573:8:573:8 | ref arg c | atl.cpp:575:8:575:8 | c | | +| atl.cpp:573:8:573:8 | ref arg c | atl.cpp:576:3:576:3 | c | | +| atl.cpp:574:8:574:8 | ref arg c | atl.cpp:575:8:575:8 | c | | +| atl.cpp:574:8:574:8 | ref arg c | atl.cpp:576:3:576:3 | c | | +| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:576:3:576:3 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:579:10:579:10 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:580:10:580:10 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:581:10:581:10 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:582:5:582:5 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:583:10:583:10 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:584:10:584:10 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:585:10:585:10 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:586:35:586:35 | c | | +| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:587:3:587:3 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:580:10:580:10 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:581:10:581:10 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:582:5:582:5 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:583:10:583:10 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:584:10:584:10 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:586:35:586:35 | c | | +| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:581:10:581:10 | c | | +| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:582:5:582:5 | c | | +| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:583:10:583:10 | c | | +| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:584:10:584:10 | c | | +| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:586:35:586:35 | c | | +| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:582:5:582:5 | c | | +| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:583:10:583:10 | c | | +| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:584:10:584:10 | c | | +| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:586:35:586:35 | c | | +| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:583:10:583:10 | c | | +| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:584:10:584:10 | c | | +| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:586:35:586:35 | c | | +| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:584:10:584:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:586:35:586:35 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:586:35:586:35 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:586:35:586:35 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:586:35:586:35 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:590:5:590:5 | c | | +| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:591:10:591:10 | c | | +| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:592:10:592:10 | c | | +| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:593:10:593:10 | c | | +| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:594:3:594:3 | c | | +| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:591:10:591:10 | c | | +| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:592:10:592:10 | c | | +| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:593:10:593:10 | c | | +| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:594:3:594:3 | c | | +| atl.cpp:591:10:591:10 | ref arg c | atl.cpp:592:10:592:10 | c | | +| atl.cpp:591:10:591:10 | ref arg c | atl.cpp:593:10:593:10 | c | | +| atl.cpp:591:10:591:10 | ref arg c | atl.cpp:594:3:594:3 | c | | +| atl.cpp:592:10:592:10 | ref arg c | atl.cpp:593:10:593:10 | c | | +| atl.cpp:592:10:592:10 | ref arg c | atl.cpp:594:3:594:3 | c | | +| atl.cpp:593:10:593:10 | ref arg c | atl.cpp:594:3:594:3 | c | | +| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:597:5:597:5 | c | | +| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:598:10:598:10 | c | | +| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:599:10:599:10 | c | | +| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:600:3:600:3 | c | | +| atl.cpp:597:5:597:5 | ref arg c | atl.cpp:598:10:598:10 | c | | +| atl.cpp:597:5:597:5 | ref arg c | atl.cpp:599:10:599:10 | c | | +| atl.cpp:597:5:597:5 | ref arg c | atl.cpp:600:3:600:3 | c | | +| atl.cpp:598:10:598:10 | ref arg c | atl.cpp:599:10:599:10 | c | | +| atl.cpp:598:10:598:10 | ref arg c | atl.cpp:600:3:600:3 | c | | +| atl.cpp:599:10:599:10 | ref arg c | atl.cpp:600:3:600:3 | c | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 5f05417890733959f4bb89c0b2d765370578fab9 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:10:04 +0000 Subject: [PATCH 018/213] C++: Add MaD model for 'CComSafeArray'. --- cpp/ql/lib/ext/CComSafeArray.model.yml | 27 +++++++++++++++++++ .../dataflow/taint-tests/atl.cpp | 26 +++++++++--------- 2 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 cpp/ql/lib/ext/CComSafeArray.model.yml diff --git a/cpp/ql/lib/ext/CComSafeArray.model.yml b/cpp/ql/lib/ext/CComSafeArray.model.yml new file mode 100644 index 000000000000..4128ae13e177 --- /dev/null +++ b/cpp/ql/lib/ext/CComSafeArray.model.yml @@ -0,0 +1,27 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CComSafeArray", True, "CComSafeArray", "(const CComSafeArray &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CComSafeArray", True, "CComSafeArray", "(const SAFEARRAY &)", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "CComSafeArray", "(const SAFEARRAY *)", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "Add", "(const SAFEARRAY *)", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "Add", "(const T &,BOOL)", "", "Argument[*@0]", "Argument[-1].Field[*m_psa].Field[*@pvData]", "value", "manual"] + - ["", "CComSafeArray", True, "Attach", "", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "CopyFrom", "", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "CopyTo", "", "", "Argument[-1].Field[*m_psa]", "Argument[*0]", "value", "manual"] + - ["", "CComSafeArray", True, "Create", "(const SAFEARRAYBOUND *,UINT)", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "GetAt", "", "", "Argument[-1].Field[*m_psa].Field[*@pvData]", "ReturnValue[*@]", "value", "manual"] + - ["", "CComSafeArray", True, "GetLowerBound", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CComSafeArray", True, "GetSafeArrayPtr", "", "", "Argument[-1].Field[*m_psa]", "ReturnValue[*]", "value", "manual"] + - ["", "CComSafeArray", True, "GetUpperBound", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CComSafeArray", True, "MultiDimGetAt", "", "", "Argument[-1].Field[*m_psa].Field[*@pvData]", "Argument[*@1]", "value", "manual"] + - ["", "CComSafeArray", True, "MultiDimSetAt", "", "", "Argument[*@1]", "Argument[-1].Field[*m_psa].Field[*@pvData]", "value", "manual"] + - ["", "CComSafeArray", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Field[*m_psa].Field[*@pvData]", "value", "manual"] + - ["", "CComSafeArray", True, "operator LPSAFEARRAY", "", "", "Argument[-1].Field[*m_psa]", "ReturnValue[*]", "value", "manual"] + - ["", "CComSafeArray", True, "operator[]", "", "", "Argument[-1].Field[*m_psa].Field[*@pvData]", "ReturnValue[*@]", "value", "manual"] + - ["", "CComSafeArray", True, "operator=", "(const CComSafeArray&)", "", "Argument[*0].Field[*m_psa]", "ReturnValue[*]", "value", "manual"] + - ["", "CComSafeArray", True, "operator=", "(const CComSafeArray&)", "", "Argument[*0].Field[*m_psa]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "operator=", "(const SAFEARRAY *)", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "operator=", "(const SAFEARRAY *)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index a91cd9c88d6f..69a79eb75802 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -572,10 +572,10 @@ void test_CComSafeArray() { sink(safe->pvData); // $ ir { CComSafeArray c(safe); - sink(c[0]); // $ MISSING: ir - sink(c.GetAt(0)); // $ MISSING: ir - sink(c.GetSafeArrayPtr()->pvData); // $ MISSING: ir - sink(c.m_psa->pvData); // $ MISSING: ir + sink(c[0]); // $ ir + sink(c.GetAt(0)); // $ ir + sink(c.GetSafeArrayPtr()->pvData); // $ ir + sink(c.m_psa->pvData); // $ ir } { CComSafeArray c; @@ -583,22 +583,22 @@ void test_CComSafeArray() { sink(c.GetAt(0)); sink(c.GetSafeArrayPtr()->pvData); c.Add(safe); - sink(c[0]); // $ MISSING: ir - sink(c.GetAt(0)); // $ MISSING: ir - sink(c.GetSafeArrayPtr()->pvData); // $ MISSING: ir - sink(static_cast(c)->pvData); // $ MISSING: ir + sink(c[0]); // $ ir + sink(c.GetAt(0)); // $ ir + sink(c.GetSafeArrayPtr()->pvData); // $ ir + sink(static_cast(c)->pvData); // $ ir } { CComSafeArray c; c.Add(source(), true); - sink(c[0]); // $ MISSING: ir - sink(c.GetAt(0)); // $ MISSING: ir - sink(c.GetSafeArrayPtr()->pvData); // $ MISSING: ir + sink(c[0]); // $ ir + sink(c.GetAt(0)); // $ ir + sink(c.GetSafeArrayPtr()->pvData); // $ ir } { CComSafeArray c; c.SetAt(0, source(), true); - sink(c[0]); // $ MISSING: ir - sink(c[0L]); // $ MISSING: ir + sink(c[0]); // $ ir + sink(c[0L]); // $ ir } } From 1a79290fd67fe3da4abe481e243c64c9a02f0589 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:12:37 +0000 Subject: [PATCH 019/213] C++: Add failing tests with 'CPathT'. --- .../dataflow/taint-tests/atl.cpp | 104 ++++++++ .../dataflow/taint-tests/localTaint.expected | 248 ++++++++++++------ 2 files changed, 267 insertions(+), 85 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 69a79eb75802..35a66099a626 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -602,3 +602,107 @@ void test_CComSafeArray() { sink(c[0L]); // $ ir } } + +template +struct CPathT { + typedef StringType PCXSTR; // simplified + CPathT(PCXSTR pszPath); + CPathT(const CPathT& path); + CPathT() throw(); + + void AddBackslash(); + BOOL AddExtension(PCXSTR pszExtension); + BOOL Append(PCXSTR pszMore); + void BuildRoot(int iDrive); + void Canonicalize(); + void Combine(PCXSTR pszDir, PCXSTR pszFile); + CPathT CommonPrefix(PCXSTR pszOther); + BOOL CompactPathEx(UINT nMaxChars, DWORD dwFlags); + BOOL FileExists() const; + int FindExtension() const; + int FindFileName() const; + int GetDriveNumber() const; + StringType GetExtension() const; + BOOL IsDirectory() const; + BOOL IsFileSpec() const; + BOOL IsPrefix(PCXSTR pszPrefix) const; + BOOL IsRelative() const; + BOOL IsRoot() const; + BOOL IsSameRoot(PCXSTR pszOther) const; + BOOL IsUNC() const; + BOOL IsUNCServer() const; + BOOL IsUNCServerShare() const; + BOOL MakePretty(); + BOOL MatchSpec(PCXSTR pszSpec) const; + void QuoteSpaces(); + BOOL RelativePathTo( + PCXSTR pszFrom, + DWORD dwAttrFrom, + PCXSTR pszTo, + DWORD dwAttrTo); + void RemoveArgs(); + void RemoveBackslash(); + void RemoveBlanks(); + void RemoveExtension(); + BOOL RemoveFileSpec(); + BOOL RenameExtension(PCXSTR pszExtension); + int SkipRoot() const; + void StripPath(); + BOOL StripToRoot(); + void UnquoteSpaces(); + operator const StringType&() const throw(); + operator PCXSTR() const throw(); + operator StringType&() throw(); + CPathT& operator+=(PCXSTR pszMore); + + StringType m_strPath; +}; + +using CPath = CPathT; + +void test_CPathT() { + char* x = indirect_source(); + CPath p(x); + sink(static_cast(p)); // $ MISSING: ir + sink(p.m_strPath); // $ MISSING: ir + + CPath p2(p); + sink(p2.m_strPath); // $ MISSING: ir + + { + CPath p; + p.AddExtension(x); + sink(p.m_strPath); // $ MISSING: ir + } + { + CPath p; + p.Append(x); + sink(p.m_strPath); // $ MISSING: ir + + CPath p2; + p2 += p; + sink(p.m_strPath); // $ MISSING: ir + + CPath p3; + p3 += x; + sink(p.m_strPath); // $ MISSING: ir + } + + { + CPath p; + p.Combine(x, nullptr); + sink(p.m_strPath); // $ MISSING: ir + } + { + CPath p; + p.Combine(nullptr, x); + sink(p.m_strPath); // $ MISSING: ir + } + + { + CPath p; + auto p2 = p.CommonPrefix(x); + sink(p2.m_strPath); // $ MISSING: ir + sink(p2.GetExtension()); // $ MISSING: ir + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 4924d7d817f3..961011dbd234 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -636,92 +636,170 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:525:10:525:10 | b | | | atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:526:3:526:3 | b | | | atl.cpp:525:10:525:10 | b [post update] | atl.cpp:526:3:526:3 | b | | -| atl.cpp:569:22:569:33 | call to getSafeArray | atl.cpp:570:8:570:11 | safe | | -| atl.cpp:569:22:569:33 | call to getSafeArray | atl.cpp:572:24:572:27 | safe | | -| atl.cpp:569:22:569:33 | call to getSafeArray | atl.cpp:582:11:582:14 | safe | | -| atl.cpp:570:8:570:11 | safe [post update] | atl.cpp:572:24:572:27 | safe | | -| atl.cpp:570:8:570:11 | safe [post update] | atl.cpp:582:11:582:14 | safe | | -| atl.cpp:572:24:572:27 | safe | atl.cpp:572:24:572:28 | call to CComSafeArray | TAINT | -| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:573:8:573:8 | c | | -| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:574:8:574:8 | c | | -| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:575:8:575:8 | c | | -| atl.cpp:572:24:572:28 | call to CComSafeArray | atl.cpp:576:3:576:3 | c | | -| atl.cpp:573:8:573:8 | ref arg c | atl.cpp:574:8:574:8 | c | | -| atl.cpp:573:8:573:8 | ref arg c | atl.cpp:575:8:575:8 | c | | -| atl.cpp:573:8:573:8 | ref arg c | atl.cpp:576:3:576:3 | c | | -| atl.cpp:574:8:574:8 | ref arg c | atl.cpp:575:8:575:8 | c | | -| atl.cpp:574:8:574:8 | ref arg c | atl.cpp:576:3:576:3 | c | | -| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:576:3:576:3 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:579:10:579:10 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:580:10:580:10 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:581:10:581:10 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:582:5:582:5 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:583:10:583:10 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:584:10:584:10 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:585:10:585:10 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:586:35:586:35 | c | | -| atl.cpp:578:24:578:24 | call to CComSafeArray | atl.cpp:587:3:587:3 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:580:10:580:10 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:581:10:581:10 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:582:5:582:5 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:583:10:583:10 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:584:10:584:10 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:585:10:585:10 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:586:35:586:35 | c | | -| atl.cpp:579:10:579:10 | ref arg c | atl.cpp:587:3:587:3 | c | | -| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:581:10:581:10 | c | | -| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:582:5:582:5 | c | | -| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:583:10:583:10 | c | | -| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:584:10:584:10 | c | | -| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:585:10:585:10 | c | | -| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:586:35:586:35 | c | | -| atl.cpp:580:10:580:10 | ref arg c | atl.cpp:587:3:587:3 | c | | -| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:582:5:582:5 | c | | -| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:583:10:583:10 | c | | -| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:584:10:584:10 | c | | -| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:585:10:585:10 | c | | -| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:586:35:586:35 | c | | -| atl.cpp:581:10:581:10 | ref arg c | atl.cpp:587:3:587:3 | c | | -| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:583:10:583:10 | c | | -| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:584:10:584:10 | c | | -| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:585:10:585:10 | c | | -| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:586:35:586:35 | c | | -| atl.cpp:582:5:582:5 | ref arg c | atl.cpp:587:3:587:3 | c | | +| atl.cpp:571:22:571:33 | call to getSafeArray | atl.cpp:572:8:572:11 | safe | | +| atl.cpp:571:22:571:33 | call to getSafeArray | atl.cpp:574:24:574:27 | safe | | +| atl.cpp:571:22:571:33 | call to getSafeArray | atl.cpp:585:11:585:14 | safe | | +| atl.cpp:572:8:572:11 | safe [post update] | atl.cpp:574:24:574:27 | safe | | +| atl.cpp:572:8:572:11 | safe [post update] | atl.cpp:585:11:585:14 | safe | | +| atl.cpp:574:24:574:27 | safe | atl.cpp:574:24:574:28 | call to CComSafeArray | TAINT | +| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:575:8:575:8 | c | | +| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:576:8:576:8 | c | | +| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:577:8:577:8 | c | | +| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:578:8:578:8 | c | | +| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:579:3:579:3 | c | | +| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:576:8:576:8 | c | | +| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:577:8:577:8 | c | | +| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:578:8:578:8 | c | | +| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:579:3:579:3 | c | | +| atl.cpp:576:8:576:8 | ref arg c | atl.cpp:577:8:577:8 | c | | +| atl.cpp:576:8:576:8 | ref arg c | atl.cpp:578:8:578:8 | c | | +| atl.cpp:576:8:576:8 | ref arg c | atl.cpp:579:3:579:3 | c | | +| atl.cpp:577:8:577:8 | ref arg c | atl.cpp:578:8:578:8 | c | | +| atl.cpp:577:8:577:8 | ref arg c | atl.cpp:579:3:579:3 | c | | +| atl.cpp:578:8:578:8 | c [post update] | atl.cpp:579:3:579:3 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:582:10:582:10 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:583:10:583:10 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:584:10:584:10 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:585:5:585:5 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:586:10:586:10 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:587:10:587:10 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:588:10:588:10 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:589:35:589:35 | c | | +| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:590:3:590:3 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:583:10:583:10 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:584:10:584:10 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:585:5:585:5 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:586:10:586:10 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:587:10:587:10 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:589:35:589:35 | c | | +| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:590:3:590:3 | c | | | atl.cpp:583:10:583:10 | ref arg c | atl.cpp:584:10:584:10 | c | | -| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:585:10:585:10 | c | | -| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:586:35:586:35 | c | | -| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:587:3:587:3 | c | | -| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:585:10:585:10 | c | | -| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:586:35:586:35 | c | | -| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:587:3:587:3 | c | | -| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:586:35:586:35 | c | | -| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:587:3:587:3 | c | | -| atl.cpp:586:35:586:35 | ref arg c | atl.cpp:587:3:587:3 | c | | -| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:590:5:590:5 | c | | -| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:591:10:591:10 | c | | -| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:592:10:592:10 | c | | -| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:593:10:593:10 | c | | -| atl.cpp:589:24:589:24 | call to CComSafeArray | atl.cpp:594:3:594:3 | c | | -| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:591:10:591:10 | c | | -| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:592:10:592:10 | c | | -| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:593:10:593:10 | c | | -| atl.cpp:590:5:590:5 | ref arg c | atl.cpp:594:3:594:3 | c | | -| atl.cpp:591:10:591:10 | ref arg c | atl.cpp:592:10:592:10 | c | | -| atl.cpp:591:10:591:10 | ref arg c | atl.cpp:593:10:593:10 | c | | -| atl.cpp:591:10:591:10 | ref arg c | atl.cpp:594:3:594:3 | c | | -| atl.cpp:592:10:592:10 | ref arg c | atl.cpp:593:10:593:10 | c | | -| atl.cpp:592:10:592:10 | ref arg c | atl.cpp:594:3:594:3 | c | | -| atl.cpp:593:10:593:10 | ref arg c | atl.cpp:594:3:594:3 | c | | -| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:597:5:597:5 | c | | -| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:598:10:598:10 | c | | -| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:599:10:599:10 | c | | -| atl.cpp:596:24:596:24 | call to CComSafeArray | atl.cpp:600:3:600:3 | c | | -| atl.cpp:597:5:597:5 | ref arg c | atl.cpp:598:10:598:10 | c | | -| atl.cpp:597:5:597:5 | ref arg c | atl.cpp:599:10:599:10 | c | | -| atl.cpp:597:5:597:5 | ref arg c | atl.cpp:600:3:600:3 | c | | -| atl.cpp:598:10:598:10 | ref arg c | atl.cpp:599:10:599:10 | c | | -| atl.cpp:598:10:598:10 | ref arg c | atl.cpp:600:3:600:3 | c | | -| atl.cpp:599:10:599:10 | ref arg c | atl.cpp:600:3:600:3 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:585:5:585:5 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:586:10:586:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:587:10:587:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:589:35:589:35 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:585:5:585:5 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:586:10:586:10 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:587:10:587:10 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:589:35:589:35 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:586:10:586:10 | c | | +| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:587:10:587:10 | c | | +| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:589:35:589:35 | c | | +| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:587:10:587:10 | c | | +| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:589:35:589:35 | c | | +| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:589:35:589:35 | c | | +| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:588:10:588:10 | ref arg c | atl.cpp:589:35:589:35 | c | | +| atl.cpp:588:10:588:10 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:589:35:589:35 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:593:5:593:5 | c | | +| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:594:10:594:10 | c | | +| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:595:10:595:10 | c | | +| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:596:10:596:10 | c | | +| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:597:3:597:3 | c | | +| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:594:10:594:10 | c | | +| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:595:10:595:10 | c | | +| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:596:10:596:10 | c | | +| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:597:3:597:3 | c | | +| atl.cpp:594:10:594:10 | ref arg c | atl.cpp:595:10:595:10 | c | | +| atl.cpp:594:10:594:10 | ref arg c | atl.cpp:596:10:596:10 | c | | +| atl.cpp:594:10:594:10 | ref arg c | atl.cpp:597:3:597:3 | c | | +| atl.cpp:595:10:595:10 | ref arg c | atl.cpp:596:10:596:10 | c | | +| atl.cpp:595:10:595:10 | ref arg c | atl.cpp:597:3:597:3 | c | | +| atl.cpp:596:10:596:10 | ref arg c | atl.cpp:597:3:597:3 | c | | +| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:600:5:600:5 | c | | +| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:601:10:601:10 | c | | +| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:602:10:602:10 | c | | +| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:603:3:603:3 | c | | +| atl.cpp:600:5:600:5 | ref arg c | atl.cpp:601:10:601:10 | c | | +| atl.cpp:600:5:600:5 | ref arg c | atl.cpp:602:10:602:10 | c | | +| atl.cpp:600:5:600:5 | ref arg c | atl.cpp:603:3:603:3 | c | | +| atl.cpp:601:10:601:10 | ref arg c | atl.cpp:602:10:602:10 | c | | +| atl.cpp:601:10:601:10 | ref arg c | atl.cpp:603:3:603:3 | c | | +| atl.cpp:602:10:602:10 | ref arg c | atl.cpp:603:3:603:3 | c | | +| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:665:11:665:11 | x | | +| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:674:20:674:20 | x | | +| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:679:14:679:14 | x | | +| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:687:11:687:11 | x | | +| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:693:15:693:15 | x | | +| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:698:24:698:24 | x | | +| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:704:30:704:30 | x | | +| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:674:20:674:20 | x | | +| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:679:14:679:14 | x | | +| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:687:11:687:11 | x | | +| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:693:15:693:15 | x | | +| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:698:24:698:24 | x | | +| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:704:30:704:30 | x | | +| atl.cpp:665:11:665:11 | x | atl.cpp:665:11:665:12 | call to CPathT | TAINT | +| atl.cpp:665:11:665:12 | call to CPathT | atl.cpp:666:27:666:27 | p | | +| atl.cpp:665:11:665:12 | call to CPathT | atl.cpp:667:8:667:8 | p | | +| atl.cpp:665:11:665:12 | call to CPathT | atl.cpp:669:12:669:12 | p | | +| atl.cpp:666:27:666:27 | ref arg p | atl.cpp:667:8:667:8 | p | | +| atl.cpp:666:27:666:27 | ref arg p | atl.cpp:669:12:669:12 | p | | +| atl.cpp:667:8:667:8 | p [post update] | atl.cpp:669:12:669:12 | p | | +| atl.cpp:667:10:667:18 | ref arg m_strPath | atl.cpp:670:11:670:19 | m_strPath | | +| atl.cpp:669:12:669:12 | p | atl.cpp:669:12:669:13 | call to CPathT | | +| atl.cpp:669:12:669:13 | call to CPathT | atl.cpp:670:8:670:9 | p2 | | +| atl.cpp:673:11:673:11 | call to CPathT | atl.cpp:674:5:674:5 | p | | +| atl.cpp:673:11:673:11 | call to CPathT | atl.cpp:675:10:675:10 | p | | +| atl.cpp:674:5:674:5 | ref arg p | atl.cpp:675:10:675:10 | p | | +| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:679:14:679:14 | x | | +| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:687:11:687:11 | x | | +| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:693:15:693:15 | x | | +| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:698:24:698:24 | x | | +| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:704:30:704:30 | x | | +| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:679:5:679:5 | p | | +| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:680:10:680:10 | p | | +| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:683:11:683:11 | p | | +| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:684:10:684:10 | p | | +| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:688:10:688:10 | p | | +| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:680:10:680:10 | p | | +| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:683:11:683:11 | p | | +| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:684:10:684:10 | p | | +| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:688:10:688:10 | p | | +| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:687:11:687:11 | x | | +| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:693:15:693:15 | x | | +| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:698:24:698:24 | x | | +| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:704:30:704:30 | x | | +| atl.cpp:680:10:680:10 | p [post update] | atl.cpp:683:11:683:11 | p | | +| atl.cpp:680:10:680:10 | p [post update] | atl.cpp:684:10:684:10 | p | | +| atl.cpp:680:10:680:10 | p [post update] | atl.cpp:688:10:688:10 | p | | +| atl.cpp:680:12:680:20 | ref arg m_strPath | atl.cpp:684:12:684:20 | m_strPath | | +| atl.cpp:680:12:680:20 | ref arg m_strPath | atl.cpp:688:12:688:20 | m_strPath | | +| atl.cpp:682:11:682:12 | call to CPathT | atl.cpp:683:5:683:6 | p2 | | +| atl.cpp:683:11:683:11 | call to operator char *& | atl.cpp:683:8:683:8 | call to operator+= | TAINT | +| atl.cpp:683:11:683:11 | ref arg p | atl.cpp:684:10:684:10 | p | | +| atl.cpp:683:11:683:11 | ref arg p | atl.cpp:688:10:688:10 | p | | +| atl.cpp:684:10:684:10 | p [post update] | atl.cpp:688:10:688:10 | p | | +| atl.cpp:684:12:684:20 | ref arg m_strPath | atl.cpp:688:12:688:20 | m_strPath | | +| atl.cpp:686:11:686:12 | call to CPathT | atl.cpp:687:5:687:6 | p3 | | +| atl.cpp:687:11:687:11 | ref arg x | atl.cpp:693:15:693:15 | x | | +| atl.cpp:687:11:687:11 | ref arg x | atl.cpp:698:24:698:24 | x | | +| atl.cpp:687:11:687:11 | ref arg x | atl.cpp:704:30:704:30 | x | | +| atl.cpp:687:11:687:11 | x | atl.cpp:687:8:687:8 | call to operator+= | TAINT | +| atl.cpp:692:11:692:11 | call to CPathT | atl.cpp:693:5:693:5 | p | | +| atl.cpp:692:11:692:11 | call to CPathT | atl.cpp:694:10:694:10 | p | | +| atl.cpp:693:5:693:5 | ref arg p | atl.cpp:694:10:694:10 | p | | +| atl.cpp:693:15:693:15 | ref arg x | atl.cpp:698:24:698:24 | x | | +| atl.cpp:693:15:693:15 | ref arg x | atl.cpp:704:30:704:30 | x | | +| atl.cpp:697:11:697:11 | call to CPathT | atl.cpp:698:5:698:5 | p | | +| atl.cpp:697:11:697:11 | call to CPathT | atl.cpp:699:10:699:10 | p | | +| atl.cpp:698:5:698:5 | ref arg p | atl.cpp:699:10:699:10 | p | | +| atl.cpp:698:24:698:24 | ref arg x | atl.cpp:704:30:704:30 | x | | +| atl.cpp:703:11:703:11 | call to CPathT | atl.cpp:704:15:704:15 | p | | +| atl.cpp:704:17:704:28 | call to CommonPrefix | atl.cpp:705:10:705:11 | p2 | | +| atl.cpp:704:17:704:28 | call to CommonPrefix | atl.cpp:706:10:706:11 | p2 | | +| atl.cpp:705:10:705:11 | p2 [post update] | atl.cpp:706:10:706:11 | p2 | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 354361952ac6d4e8571a7b06e0f487c93fb7070b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:15:17 +0000 Subject: [PATCH 020/213] C++: Add MaD model for 'CPathT'. --- cpp/ql/lib/ext/CPathT.model.yml | 22 +++++++++++++++++++ .../dataflow/taint-tests/atl.cpp | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/lib/ext/CPathT.model.yml diff --git a/cpp/ql/lib/ext/CPathT.model.yml b/cpp/ql/lib/ext/CPathT.model.yml new file mode 100644 index 000000000000..2138dd6c9425 --- /dev/null +++ b/cpp/ql/lib/ext/CPathT.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CPathT", True, "CPathT", "", "", "Argument[*1]", "Argument[-1]", "value", "manual"] + - ["", "CPathT", True, "AddExtension", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CPathT", True, "Append", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CPathT", True, "Combine", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CPathT", True, "Combine", "", "", "Argument[*1]", "Argument[-1]", "taint", "manual"] + - ["", "CPathT", True, "CommonPrefix", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"] + - ["", "CPathT", True, "CommonPrefix", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CPathT", True, "GetExtension", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CPathT", True, "RelativePathTo", "", "", "Argument[*0]", "ReturnValue[-1]", "taint", "manual"] + - ["", "CPathT", True, "RelativePathTo", "", "", "Argument[*2]", "ReturnValue[-1]", "taint", "manual"] + - ["", "CPathT", True, "RenameExtension", "", "", "Argument[*0]", "ReturnValue[-1]", "taint", "manual"] + # Note: These don't work currently since we cannot use the template parameter in the name of the function + # - ["", "CPathT", True, "operator const T&", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] + # - ["", "CPathT", True, "operator T&", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] + - ["", "CPathT", True, "operator PCXSTR", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] + - ["", "CPathT", True, "operator +=", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] + - ["", "CPathT", True, "operator +=", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 35a66099a626..d6b7b6d2d6fb 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -703,6 +703,6 @@ void test_CPathT() { CPath p; auto p2 = p.CommonPrefix(x); sink(p2.m_strPath); // $ MISSING: ir - sink(p2.GetExtension()); // $ MISSING: ir + sink(p2.GetExtension()); // $ ir } } From c61395b9733b1236d05026030378260100a04586 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:18:16 +0000 Subject: [PATCH 021/213] C++: Add implicit read of the 'm_strPath' member. --- cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../code/cpp/models/implementations/CPathT.qll | 16 ++++++++++++++++ .../library-tests/dataflow/taint-tests/atl.cpp | 18 +++++++++--------- 3 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/CPathT.qll diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index 9e67eaae5cf3..b371e6dc116c 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -52,3 +52,4 @@ private import implementations.ZMQ private import implementations.Win32CommandExecution private import implementations.CA2AEX private import implementations.CComBSTR +private import implementations.CPathT diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/CPathT.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/CPathT.qll new file mode 100644 index 000000000000..b2fe3a363c7c --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/CPathT.qll @@ -0,0 +1,16 @@ +private import cpp +private import semmle.code.cpp.ir.dataflow.FlowSteps +private import semmle.code.cpp.dataflow.new.DataFlow + +/** The `CPathT` class from the Microsoft "Active Template Library". */ +class CPathT extends Class { + CPathT() { this.hasGlobalName("CPathT") } +} + +private class MStrPath extends Field { + MStrPath() { this.getDeclaringType() instanceof CPathT and this.hasName("m_strPath") } +} + +private class MStrPathTaintInheritingContent extends TaintInheritingContent, DataFlow::FieldContent { + MStrPathTaintInheritingContent() { this.getField() instanceof MStrPath } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index d6b7b6d2d6fb..46a147e555aa 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -664,45 +664,45 @@ void test_CPathT() { char* x = indirect_source(); CPath p(x); sink(static_cast(p)); // $ MISSING: ir - sink(p.m_strPath); // $ MISSING: ir + sink(p.m_strPath); // $ ir CPath p2(p); - sink(p2.m_strPath); // $ MISSING: ir + sink(p2.m_strPath); // $ ir { CPath p; p.AddExtension(x); - sink(p.m_strPath); // $ MISSING: ir + sink(p.m_strPath); // $ ir } { CPath p; p.Append(x); - sink(p.m_strPath); // $ MISSING: ir + sink(p.m_strPath); // $ ir CPath p2; p2 += p; - sink(p.m_strPath); // $ MISSING: ir + sink(p.m_strPath); // $ ir CPath p3; p3 += x; - sink(p.m_strPath); // $ MISSING: ir + sink(p.m_strPath); // $ ir } { CPath p; p.Combine(x, nullptr); - sink(p.m_strPath); // $ MISSING: ir + sink(p.m_strPath); // $ ir } { CPath p; p.Combine(nullptr, x); - sink(p.m_strPath); // $ MISSING: ir + sink(p.m_strPath); // $ ir } { CPath p; auto p2 = p.CommonPrefix(x); - sink(p2.m_strPath); // $ MISSING: ir + sink(p2.m_strPath); // $ ir sink(p2.GetExtension()); // $ ir } } From 029c0134eba01f629b1a0e7ffba4d98fb093ccef Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:20:24 +0000 Subject: [PATCH 022/213] C++: Add failing tests with 'CSimpleArray'. --- .../dataflow/taint-tests/atl.cpp | 47 +++++++++++++++++++ .../dataflow/taint-tests/localTaint.expected | 46 ++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 46a147e555aa..e21500166417 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -706,3 +706,50 @@ void test_CPathT() { sink(p2.GetExtension()); // $ ir } } + +template +struct CSimpleArray { + CSimpleArray(const CSimpleArray& src); + CSimpleArray(); + ~CSimpleArray(); + + BOOL Add(const T& t); + int Find(const T& t) const; + T* GetData() const; + int GetSize() const; + BOOL Remove(const T& t); + void RemoveAll(); + BOOL RemoveAt(int nIndex); + + BOOL SetAtIndex( + int nIndex, + const T& t); + + T& operator[](int nindex); + CSimpleArray & operator=(const CSimpleArray& src); +}; + +void test_CSimpleArray() { + int x = source(); + { + CSimpleArray a; + a.Add(x); + sink(a[0]); // $ MISSING: ir + a.Add(0); + sink(a[0]); // $ MISSING: ir + + CSimpleArray a2; + sink(a2[0]); + a2 = a; + sink(a2[0]); // $ MISSING: ir + } + { + CSimpleArray a; + a.Add(x); + sink(a.GetData()); // $ MISSING: ir + + CSimpleArray a2; + int pos = a2.Find(x); + sink(a2[pos]); // $ MISSING: ir + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 961011dbd234..952f67e2a547 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -800,6 +800,52 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:704:17:704:28 | call to CommonPrefix | atl.cpp:705:10:705:11 | p2 | | | atl.cpp:704:17:704:28 | call to CommonPrefix | atl.cpp:706:10:706:11 | p2 | | | atl.cpp:705:10:705:11 | p2 [post update] | atl.cpp:706:10:706:11 | p2 | | +| atl.cpp:733:11:733:21 | call to source | atl.cpp:736:11:736:11 | x | | +| atl.cpp:733:11:733:21 | call to source | atl.cpp:748:11:748:11 | x | | +| atl.cpp:733:11:733:21 | call to source | atl.cpp:752:23:752:23 | x | | +| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:736:5:736:5 | a | | +| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:737:10:737:10 | a | | +| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:738:5:738:5 | a | | +| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:739:10:739:10 | a | | +| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:743:10:743:10 | a | | +| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:745:3:745:3 | a | | +| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:737:10:737:10 | a | | +| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:738:5:738:5 | a | | +| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:739:10:739:10 | a | | +| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:743:10:743:10 | a | | +| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:745:3:745:3 | a | | +| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:738:5:738:5 | a | | +| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:739:10:739:10 | a | | +| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:743:10:743:10 | a | | +| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:745:3:745:3 | a | | +| atl.cpp:738:5:738:5 | ref arg a | atl.cpp:739:10:739:10 | a | | +| atl.cpp:738:5:738:5 | ref arg a | atl.cpp:743:10:743:10 | a | | +| atl.cpp:738:5:738:5 | ref arg a | atl.cpp:745:3:745:3 | a | | +| atl.cpp:739:10:739:10 | ref arg a | atl.cpp:743:10:743:10 | a | | +| atl.cpp:739:10:739:10 | ref arg a | atl.cpp:745:3:745:3 | a | | +| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:742:10:742:11 | a2 | | +| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:743:5:743:6 | a2 | | +| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:744:10:744:11 | a2 | | +| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:745:3:745:3 | a2 | | +| atl.cpp:742:10:742:11 | ref arg a2 | atl.cpp:743:5:743:6 | a2 | | +| atl.cpp:742:10:742:11 | ref arg a2 | atl.cpp:744:10:744:11 | a2 | | +| atl.cpp:742:10:742:11 | ref arg a2 | atl.cpp:745:3:745:3 | a2 | | +| atl.cpp:743:5:743:6 | ref arg a2 | atl.cpp:744:10:744:11 | a2 | | +| atl.cpp:743:5:743:6 | ref arg a2 | atl.cpp:745:3:745:3 | a2 | | +| atl.cpp:743:10:743:10 | a | atl.cpp:743:5:743:6 | ref arg a2 | TAINT | +| atl.cpp:743:10:743:10 | a | atl.cpp:743:8:743:8 | call to operator= | TAINT | +| atl.cpp:744:10:744:11 | ref arg a2 | atl.cpp:745:3:745:3 | a2 | | +| atl.cpp:747:23:747:23 | call to CSimpleArray | atl.cpp:748:5:748:5 | a | | +| atl.cpp:747:23:747:23 | call to CSimpleArray | atl.cpp:749:10:749:10 | a | | +| atl.cpp:747:23:747:23 | call to CSimpleArray | atl.cpp:754:3:754:3 | a | | +| atl.cpp:748:5:748:5 | ref arg a | atl.cpp:749:10:749:10 | a | | +| atl.cpp:748:5:748:5 | ref arg a | atl.cpp:754:3:754:3 | a | | +| atl.cpp:749:10:749:10 | ref arg a | atl.cpp:754:3:754:3 | a | | +| atl.cpp:751:23:751:24 | call to CSimpleArray | atl.cpp:752:15:752:16 | a2 | | +| atl.cpp:751:23:751:24 | call to CSimpleArray | atl.cpp:753:10:753:11 | a2 | | +| atl.cpp:751:23:751:24 | call to CSimpleArray | atl.cpp:754:3:754:3 | a2 | | +| atl.cpp:752:18:752:21 | call to Find | atl.cpp:753:13:753:15 | pos | | +| atl.cpp:753:10:753:11 | ref arg a2 | atl.cpp:754:3:754:3 | a2 | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 02b88d5dbdafd21fb67ad6e94c42a7be6494f5f6 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:29:32 +0000 Subject: [PATCH 023/213] C++: Add MaD model for 'CSimpleArray'. --- cpp/ql/lib/ext/CSimpleArray.model.yml | 11 +++++++++++ .../test/library-tests/dataflow/taint-tests/atl.cpp | 8 ++++---- 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 cpp/ql/lib/ext/CSimpleArray.model.yml diff --git a/cpp/ql/lib/ext/CSimpleArray.model.yml b/cpp/ql/lib/ext/CSimpleArray.model.yml new file mode 100644 index 000000000000..1c6337bf74c3 --- /dev/null +++ b/cpp/ql/lib/ext/CSimpleArray.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CSimpleArray", True, "CSimpleArray", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CSimpleArray", True, "Add", "", "", "Argument[*0]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CSimpleArray", True, "GetData", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CSimpleArray", True, "SetAtIndex", "", "", "Argument[*1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CSimpleArray", True, "operator[]", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CSimpleArray", True, "operator=", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index e21500166417..531ca573c94d 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -734,19 +734,19 @@ void test_CSimpleArray() { { CSimpleArray a; a.Add(x); - sink(a[0]); // $ MISSING: ir + sink(a[0]); // $ ir a.Add(0); - sink(a[0]); // $ MISSING: ir + sink(a[0]); // $ ir CSimpleArray a2; sink(a2[0]); a2 = a; - sink(a2[0]); // $ MISSING: ir + sink(a2[0]); // $ ir } { CSimpleArray a; a.Add(x); - sink(a.GetData()); // $ MISSING: ir + sink(a.GetData()); // $ ir CSimpleArray a2; int pos = a2.Find(x); From 12674ea2e619613a482b3b3ac5875653d513ba51 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:31:45 +0000 Subject: [PATCH 024/213] C++: Add failing tests with 'CSimpleMap'. --- .../dataflow/taint-tests/atl.cpp | 55 +++++++++++++++++++ .../dataflow/taint-tests/localTaint.expected | 42 ++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 531ca573c94d..44c5df7018f5 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -753,3 +753,58 @@ void test_CSimpleArray() { sink(a2[pos]); // $ MISSING: ir } } + +template +struct CSimpleMap { + CSimpleMap(); + ~CSimpleMap(); + + BOOL Add(const TKey& key, const TVal& val); + int FindKey(const TKey& key) const; + int FindVal(const TVal& val) const; + TKey& GetKeyAt(int nIndex) const; + int GetSize() const; + TVal& GetValueAt(int nIndex) const; + TVal Lookup(const TKey& key) const; + BOOL Remove(const TKey& key); + void RemoveAll(); + BOOL RemoveAt(int nIndex); + TKey ReverseLookup(const TVal& val) const; + BOOL SetAt(const TKey& key, const TVal& val); + BOOL SetAtIndex(int nIndex, const TKey& key, const TVal& val); +}; + +void test_CSimpleMap() { + wchar_t* x = source(); + { + CSimpleMap a; + a.Add("hello", x); + sink(a.Lookup("hello")); // $ MISSING: ir + } + { + CSimpleMap a; + auto pos = a.FindKey("hello"); + sink(a.GetValueAt(pos)); // $ MISSING: ir + } + { + CSimpleMap a; + auto pos = a.FindVal(x); + sink(a.GetValueAt(pos)); // $ MISSING: ir + } + { + CSimpleMap a; + auto key = a.ReverseLookup(x); + sink(key); + sink(a.Lookup(key)); // $ MISSING: ir + } + { + CSimpleMap a; + a.SetAt("hello", x); + sink(a.Lookup("hello")); // $ MISSING: ir + } + { + CSimpleMap a; + a.SetAtIndex(0, "hello", x); + sink(a.Lookup("hello")); // $ MISSING: ir + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 952f67e2a547..395ba48f967e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -846,6 +846,48 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:751:23:751:24 | call to CSimpleArray | atl.cpp:754:3:754:3 | a2 | | | atl.cpp:752:18:752:21 | call to Find | atl.cpp:753:13:753:15 | pos | | | atl.cpp:753:10:753:11 | ref arg a2 | atl.cpp:754:3:754:3 | a2 | | +| atl.cpp:778:16:778:31 | call to source | atl.cpp:781:20:781:20 | x | | +| atl.cpp:778:16:778:31 | call to source | atl.cpp:791:26:791:26 | x | | +| atl.cpp:778:16:778:31 | call to source | atl.cpp:796:32:796:32 | x | | +| atl.cpp:778:16:778:31 | call to source | atl.cpp:802:22:802:22 | x | | +| atl.cpp:778:16:778:31 | call to source | atl.cpp:807:30:807:30 | x | | +| atl.cpp:780:33:780:33 | call to CSimpleMap | atl.cpp:781:5:781:5 | a | | +| atl.cpp:780:33:780:33 | call to CSimpleMap | atl.cpp:782:10:782:10 | a | | +| atl.cpp:780:33:780:33 | call to CSimpleMap | atl.cpp:783:3:783:3 | a | | +| atl.cpp:781:5:781:5 | ref arg a | atl.cpp:782:10:782:10 | a | | +| atl.cpp:781:5:781:5 | ref arg a | atl.cpp:783:3:783:3 | a | | +| atl.cpp:782:10:782:10 | ref arg a | atl.cpp:783:3:783:3 | a | | +| atl.cpp:785:33:785:33 | call to CSimpleMap | atl.cpp:786:16:786:16 | a | | +| atl.cpp:785:33:785:33 | call to CSimpleMap | atl.cpp:787:10:787:10 | a | | +| atl.cpp:785:33:785:33 | call to CSimpleMap | atl.cpp:788:3:788:3 | a | | +| atl.cpp:786:18:786:24 | call to FindKey | atl.cpp:787:23:787:25 | pos | | +| atl.cpp:787:10:787:10 | ref arg a | atl.cpp:788:3:788:3 | a | | +| atl.cpp:790:33:790:33 | call to CSimpleMap | atl.cpp:791:16:791:16 | a | | +| atl.cpp:790:33:790:33 | call to CSimpleMap | atl.cpp:792:10:792:10 | a | | +| atl.cpp:790:33:790:33 | call to CSimpleMap | atl.cpp:793:3:793:3 | a | | +| atl.cpp:791:18:791:24 | call to FindVal | atl.cpp:792:23:792:25 | pos | | +| atl.cpp:792:10:792:10 | ref arg a | atl.cpp:793:3:793:3 | a | | +| atl.cpp:795:33:795:33 | call to CSimpleMap | atl.cpp:796:16:796:16 | a | | +| atl.cpp:795:33:795:33 | call to CSimpleMap | atl.cpp:798:10:798:10 | a | | +| atl.cpp:795:33:795:33 | call to CSimpleMap | atl.cpp:799:3:799:3 | a | | +| atl.cpp:796:16:796:16 | ref arg a | atl.cpp:798:10:798:10 | a | | +| atl.cpp:796:16:796:16 | ref arg a | atl.cpp:799:3:799:3 | a | | +| atl.cpp:796:18:796:30 | call to ReverseLookup | atl.cpp:797:10:797:12 | key | | +| atl.cpp:796:18:796:30 | call to ReverseLookup | atl.cpp:798:19:798:21 | key | | +| atl.cpp:797:10:797:12 | ref arg key | atl.cpp:798:19:798:21 | key | | +| atl.cpp:798:10:798:10 | ref arg a | atl.cpp:799:3:799:3 | a | | +| atl.cpp:801:33:801:33 | call to CSimpleMap | atl.cpp:802:5:802:5 | a | | +| atl.cpp:801:33:801:33 | call to CSimpleMap | atl.cpp:803:10:803:10 | a | | +| atl.cpp:801:33:801:33 | call to CSimpleMap | atl.cpp:804:3:804:3 | a | | +| atl.cpp:802:5:802:5 | ref arg a | atl.cpp:803:10:803:10 | a | | +| atl.cpp:802:5:802:5 | ref arg a | atl.cpp:804:3:804:3 | a | | +| atl.cpp:803:10:803:10 | ref arg a | atl.cpp:804:3:804:3 | a | | +| atl.cpp:806:33:806:33 | call to CSimpleMap | atl.cpp:807:5:807:5 | a | | +| atl.cpp:806:33:806:33 | call to CSimpleMap | atl.cpp:808:10:808:10 | a | | +| atl.cpp:806:33:806:33 | call to CSimpleMap | atl.cpp:809:3:809:3 | a | | +| atl.cpp:807:5:807:5 | ref arg a | atl.cpp:808:10:808:10 | a | | +| atl.cpp:807:5:807:5 | ref arg a | atl.cpp:809:3:809:3 | a | | +| atl.cpp:808:10:808:10 | ref arg a | atl.cpp:809:3:809:3 | a | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 74b6c9dcc75731e0922b47b085d8c058d7d6ef69 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:36:48 +0000 Subject: [PATCH 025/213] C++: Add MaD model for 'CSimpleMap'. --- cpp/ql/lib/ext/CSimpleMap.model.yml | 12 ++++++++++++ .../test/library-tests/dataflow/taint-tests/atl.cpp | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 cpp/ql/lib/ext/CSimpleMap.model.yml diff --git a/cpp/ql/lib/ext/CSimpleMap.model.yml b/cpp/ql/lib/ext/CSimpleMap.model.yml new file mode 100644 index 000000000000..323b5be01742 --- /dev/null +++ b/cpp/ql/lib/ext/CSimpleMap.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CSimpleMap", True, "Add", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CSimpleMap", True, "GetValueAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "taint", "manual"] + - ["", "CSimpleMap", True, "Lookup", "", "", "Argument[-1].Element[@]", "ReturnValue.Element[@]", "value", "manual"] + - ["", "CSimpleMap", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CSimpleMap", True, "SetAtIndex", "", "", "Argument[*@2]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CSimpleMap", True, "operator[]", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["", "CSimpleMap", True, "operator=", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 44c5df7018f5..fe76e3f2f93b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -779,7 +779,7 @@ void test_CSimpleMap() { { CSimpleMap a; a.Add("hello", x); - sink(a.Lookup("hello")); // $ MISSING: ir + sink(a.Lookup("hello")); // $ ir } { CSimpleMap a; @@ -800,11 +800,11 @@ void test_CSimpleMap() { { CSimpleMap a; a.SetAt("hello", x); - sink(a.Lookup("hello")); // $ MISSING: ir + sink(a.Lookup("hello")); // $ ir } { CSimpleMap a; a.SetAtIndex(0, "hello", x); - sink(a.Lookup("hello")); // $ MISSING: ir + sink(a.Lookup("hello")); // $ ir } } From 1ea879a880c0e409b56f45248f55a35493b4d0fa Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 14:38:10 +0000 Subject: [PATCH 026/213] C++: Add failing tests for 'CUrl'. --- .../dataflow/taint-tests/atl.cpp | 89 +++++++++++++++++++ .../dataflow/taint-tests/localTaint.expected | 66 ++++++++++++++ 2 files changed, 155 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index fe76e3f2f93b..1727684b51a3 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -808,3 +808,92 @@ void test_CSimpleMap() { sink(a.Lookup("hello")); // $ ir } } + +struct CUrl { + CUrl& operator= (const CUrl& urlThat) throw(); + CUrl() throw(); + CUrl(const CUrl& urlThat) throw(); + ~CUrl() throw(); + + inline BOOL Canonicalize(DWORD dwFlags) throw(); + inline void Clear() throw(); + + BOOL CrackUrl(LPCTSTR lpszUrl, DWORD dwFlags) throw(); + inline BOOL CreateUrl(LPTSTR lpszUrl, DWORD* pdwMaxLength, DWORD dwFlags) const throw(); + + inline LPCTSTR GetExtraInfo() const throw(); + inline DWORD GetExtraInfoLength() const throw(); + inline LPCTSTR GetHostName() const throw(); + inline DWORD GetHostNameLength() const throw(); + inline LPCTSTR GetPassword() const throw(); + inline DWORD GetPasswordLength() const throw(); + inline ATL_URL_PORT GetPortNumber() const throw(); + inline ATL_URL_SCHEME GetScheme() const throw(); + inline LPCTSTR GetSchemeName() const throw(); + inline DWORD GetSchemeNameLength() const throw(); + inline DWORD GetUrlLength() const throw(); + inline LPCTSTR GetUrlPath() const throw(); + inline DWORD GetUrlPathLength() const throw(); + inline LPCTSTR GetUserName() const throw(); + inline DWORD GetUserNameLength() const throw(); + inline BOOL SetExtraInfo(LPCTSTR lpszInfo) throw(); + inline BOOL SetHostName(LPCTSTR lpszHost) throw(); + inline BOOL SetPassword(LPCTSTR lpszPass) throw(); + inline BOOL SetPortNumber(ATL_URL_PORT nPrt) throw(); + inline BOOL SetScheme(ATL_URL_SCHEME nScheme) throw(); + inline BOOL SetSchemeName(LPCTSTR lpszSchm) throw(); + inline BOOL SetUrlPath(LPCTSTR lpszPath) throw(); + inline BOOL SetUserName(LPCTSTR lpszUser) throw(); +}; + +void test_CUrl() { + char* x = indirect_source(); + CUrl url; + url.CrackUrl(x, 0); + sink(url); // $ MISSING: ir + sink(url.GetExtraInfo()); // $ MISSING: ir + sink(url.GetHostName()); // $ MISSING: ir + sink(url.GetPassword()); // $ MISSING: ir + sink(url.GetSchemeName()); // $ MISSING: ir + sink(url.GetUrlPath()); // $ MISSING: ir + sink(url.GetUserName()); // $ MISSING: ir + + { + CUrl url2; + DWORD len; + char buffer[1024]; + url2.CrackUrl(x, 0); + url2.CreateUrl(buffer, &len, 0); + sink(buffer); // $ ast MISSING: ir + } + { + CUrl url2; + url2.SetExtraInfo(x); + sink(url2); // $ MISSING: ir + } + { + CUrl url2; + url2.SetHostName(x); + sink(url2); // $ MISSING: ir + } + { + CUrl url2; + url2.SetPassword(x); + sink(url2); // $ MISSING: ir + } + { + CUrl url2; + url2.SetSchemeName(x); + sink(url2); // $ MISSING: ir + } + { + CUrl url2; + url2.SetUrlPath(x); + sink(url2); // $ MISSING: ir + } + { + CUrl url2; + url2.SetUserName(x); + sink(url2); // $ MISSING: ir + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 395ba48f967e..3f77cb77b9cf 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -888,6 +888,72 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:807:5:807:5 | ref arg a | atl.cpp:808:10:808:10 | a | | | atl.cpp:807:5:807:5 | ref arg a | atl.cpp:809:3:809:3 | a | | | atl.cpp:808:10:808:10 | ref arg a | atl.cpp:809:3:809:3 | a | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:852:16:852:16 | x | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:865:19:865:19 | x | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:871:23:871:23 | x | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:876:22:876:22 | x | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:881:22:881:22 | x | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:886:24:886:24 | x | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:891:21:891:21 | x | | +| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:896:22:896:22 | x | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:852:3:852:5 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:853:8:853:10 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:854:8:854:10 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:855:8:855:10 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:856:8:856:10 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:857:8:857:10 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:858:8:858:10 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:859:8:859:10 | url | | +| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:899:1:899:1 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:853:8:853:10 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:854:8:854:10 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:855:8:855:10 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:856:8:856:10 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:857:8:857:10 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:858:8:858:10 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:859:8:859:10 | url | | +| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:899:1:899:1 | url | | +| atl.cpp:862:10:862:13 | call to CUrl | atl.cpp:865:5:865:8 | url2 | | +| atl.cpp:862:10:862:13 | call to CUrl | atl.cpp:866:5:866:8 | url2 | | +| atl.cpp:862:10:862:13 | call to CUrl | atl.cpp:868:3:868:3 | url2 | | +| atl.cpp:863:11:863:13 | len | atl.cpp:866:29:866:31 | len | | +| atl.cpp:864:10:864:15 | buffer | atl.cpp:866:20:866:25 | buffer | | +| atl.cpp:864:10:864:15 | buffer | atl.cpp:867:10:867:15 | buffer | | +| atl.cpp:865:5:865:8 | ref arg url2 | atl.cpp:866:5:866:8 | url2 | | +| atl.cpp:865:5:865:8 | ref arg url2 | atl.cpp:868:3:868:3 | url2 | | +| atl.cpp:866:20:866:25 | ref arg buffer | atl.cpp:867:10:867:15 | buffer | | +| atl.cpp:866:28:866:31 | ref arg & ... | atl.cpp:866:29:866:31 | len [inner post update] | | +| atl.cpp:866:29:866:31 | len | atl.cpp:866:28:866:31 | & ... | | +| atl.cpp:870:10:870:13 | call to CUrl | atl.cpp:871:5:871:8 | url2 | | +| atl.cpp:870:10:870:13 | call to CUrl | atl.cpp:872:10:872:13 | url2 | | +| atl.cpp:870:10:870:13 | call to CUrl | atl.cpp:873:3:873:3 | url2 | | +| atl.cpp:871:5:871:8 | ref arg url2 | atl.cpp:872:10:872:13 | url2 | | +| atl.cpp:871:5:871:8 | ref arg url2 | atl.cpp:873:3:873:3 | url2 | | +| atl.cpp:875:10:875:13 | call to CUrl | atl.cpp:876:5:876:8 | url2 | | +| atl.cpp:875:10:875:13 | call to CUrl | atl.cpp:877:10:877:13 | url2 | | +| atl.cpp:875:10:875:13 | call to CUrl | atl.cpp:878:3:878:3 | url2 | | +| atl.cpp:876:5:876:8 | ref arg url2 | atl.cpp:877:10:877:13 | url2 | | +| atl.cpp:876:5:876:8 | ref arg url2 | atl.cpp:878:3:878:3 | url2 | | +| atl.cpp:880:10:880:13 | call to CUrl | atl.cpp:881:5:881:8 | url2 | | +| atl.cpp:880:10:880:13 | call to CUrl | atl.cpp:882:10:882:13 | url2 | | +| atl.cpp:880:10:880:13 | call to CUrl | atl.cpp:883:3:883:3 | url2 | | +| atl.cpp:881:5:881:8 | ref arg url2 | atl.cpp:882:10:882:13 | url2 | | +| atl.cpp:881:5:881:8 | ref arg url2 | atl.cpp:883:3:883:3 | url2 | | +| atl.cpp:885:10:885:13 | call to CUrl | atl.cpp:886:5:886:8 | url2 | | +| atl.cpp:885:10:885:13 | call to CUrl | atl.cpp:887:10:887:13 | url2 | | +| atl.cpp:885:10:885:13 | call to CUrl | atl.cpp:888:3:888:3 | url2 | | +| atl.cpp:886:5:886:8 | ref arg url2 | atl.cpp:887:10:887:13 | url2 | | +| atl.cpp:886:5:886:8 | ref arg url2 | atl.cpp:888:3:888:3 | url2 | | +| atl.cpp:890:10:890:13 | call to CUrl | atl.cpp:891:5:891:8 | url2 | | +| atl.cpp:890:10:890:13 | call to CUrl | atl.cpp:892:10:892:13 | url2 | | +| atl.cpp:890:10:890:13 | call to CUrl | atl.cpp:893:3:893:3 | url2 | | +| atl.cpp:891:5:891:8 | ref arg url2 | atl.cpp:892:10:892:13 | url2 | | +| atl.cpp:891:5:891:8 | ref arg url2 | atl.cpp:893:3:893:3 | url2 | | +| atl.cpp:895:10:895:13 | call to CUrl | atl.cpp:896:5:896:8 | url2 | | +| atl.cpp:895:10:895:13 | call to CUrl | atl.cpp:897:10:897:13 | url2 | | +| atl.cpp:895:10:895:13 | call to CUrl | atl.cpp:898:3:898:3 | url2 | | +| atl.cpp:896:5:896:8 | ref arg url2 | atl.cpp:897:10:897:13 | url2 | | +| atl.cpp:896:5:896:8 | ref arg url2 | atl.cpp:898:3:898:3 | url2 | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | From 300e3eaba681fc50ba0d9914e16267b7b22f1e33 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:09:22 +0000 Subject: [PATCH 027/213] C++: Add MaD model for 'CUrl'. --- cpp/ql/lib/ext/CUrl.model.yml | 21 ++++++++++++++ .../dataflow/taint-tests/atl.cpp | 28 +++++++++---------- 2 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 cpp/ql/lib/ext/CUrl.model.yml diff --git a/cpp/ql/lib/ext/CUrl.model.yml b/cpp/ql/lib/ext/CUrl.model.yml new file mode 100644 index 000000000000..3a4f8fe2ff5a --- /dev/null +++ b/cpp/ql/lib/ext/CUrl.model.yml @@ -0,0 +1,21 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # TODO this model can be improved a lot once we have MapKey content # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CUrl", True, "CUrl", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CUrl", True, "CrackUrl", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CUrl", True, "CreateUrl", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"] + - ["", "CUrl", True, "GetExtraInfo", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CUrl", True, "GetHostName", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CUrl", True, "GetPassword", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CUrl", True, "GetSchemeName", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CUrl", True, "GetUrlPath", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CUrl", True, "GetUserName", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CUrl", True, "SetExtraInfo", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CUrl", True, "SetHostName", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CUrl", True, "SetPassword", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CUrl", True, "SetSchemeName", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CUrl", True, "SetUrlPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CUrl", True, "SetUserName", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CUrl", True, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 1727684b51a3..de3df30b2836 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -850,13 +850,13 @@ void test_CUrl() { char* x = indirect_source(); CUrl url; url.CrackUrl(x, 0); - sink(url); // $ MISSING: ir - sink(url.GetExtraInfo()); // $ MISSING: ir - sink(url.GetHostName()); // $ MISSING: ir - sink(url.GetPassword()); // $ MISSING: ir - sink(url.GetSchemeName()); // $ MISSING: ir - sink(url.GetUrlPath()); // $ MISSING: ir - sink(url.GetUserName()); // $ MISSING: ir + sink(url); // $ ir + sink(url.GetExtraInfo()); // $ ir + sink(url.GetHostName()); // $ ir + sink(url.GetPassword()); // $ ir + sink(url.GetSchemeName()); // $ ir + sink(url.GetUrlPath()); // $ ir + sink(url.GetUserName()); // $ ir { CUrl url2; @@ -864,36 +864,36 @@ void test_CUrl() { char buffer[1024]; url2.CrackUrl(x, 0); url2.CreateUrl(buffer, &len, 0); - sink(buffer); // $ ast MISSING: ir + sink(buffer); // $ ast ir } { CUrl url2; url2.SetExtraInfo(x); - sink(url2); // $ MISSING: ir + sink(url2); // $ ir } { CUrl url2; url2.SetHostName(x); - sink(url2); // $ MISSING: ir + sink(url2); // $ ir } { CUrl url2; url2.SetPassword(x); - sink(url2); // $ MISSING: ir + sink(url2); // $ ir } { CUrl url2; url2.SetSchemeName(x); - sink(url2); // $ MISSING: ir + sink(url2); // $ ir } { CUrl url2; url2.SetUrlPath(x); - sink(url2); // $ MISSING: ir + sink(url2); // $ ir } { CUrl url2; url2.SetUserName(x); - sink(url2); // $ MISSING: ir + sink(url2); // $ ir } } \ No newline at end of file From e73fccdb4a0251641c871c32d926b954522b8cc5 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:10:16 +0000 Subject: [PATCH 028/213] C++: Add more types that we'll need for later. --- .../dataflow/source-sink-tests/atl.cpp | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp new file mode 100644 index 000000000000..8b3174b8046b --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -0,0 +1,56 @@ +typedef void* HANDLE; +typedef long LONG; +typedef LONG HRESULT; +typedef const char* LPCTSTR; +typedef unsigned long DWORD; +typedef unsigned long ULONG; +typedef void* PVOID; +typedef void* LPVOID; +typedef bool BOOL; +typedef const void* LPCVOID; +typedef unsigned long long ULONGLONG; +typedef long long LONGLONG; +typedef unsigned long* ULONG_PTR; +typedef char *LPTSTR; +typedef DWORD* LPDWORD; +typedef ULONG REGSAM; +typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION; +typedef PVOID PSECURITY_DESCRIPTOR; +typedef struct _GUID { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} GUID; +typedef GUID* REFGUID; + +typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + LPVOID lpSecurityDescriptor; + BOOL bInheritHandle; +} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + +typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME, *PFILETIME, *LPFILETIME; + +using size_t = decltype(sizeof(int)); +using SIZE_T = size_t; + +typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + PVOID Pointer; + } DUMMYUNIONNAME; + HANDLE hEvent; +} OVERLAPPED, *LPOVERLAPPED; + +using LPOVERLAPPED_COMPLETION_ROUTINE = void(DWORD, DWORD, LPOVERLAPPED); + +using HKEY = void*; From dee47f2111a3ae001ad69df7ba37a858bf287107 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:18:07 +0000 Subject: [PATCH 029/213] C++: Add a failing test with 'CAtlFile'. --- .../dataflow/source-sink-tests/atl.cpp | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index 8b3174b8046b..bcc75fe0bd13 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -54,3 +54,84 @@ typedef struct _OVERLAPPED { using LPOVERLAPPED_COMPLETION_ROUTINE = void(DWORD, DWORD, LPOVERLAPPED); using HKEY = void*; + +class CAtlTransactionManager; + +class CHandle { + CHandle() throw(); + CHandle(CHandle& h) throw(); + explicit CHandle(HANDLE h) throw(); +}; + +struct CAtlFile : public CHandle { + CAtlFile() throw(); + CAtlFile(CAtlTransactionManager* pTM) throw(); + CAtlFile(CAtlFile& file) throw(); + explicit CAtlFile(HANDLE hFile) throw(); + + HRESULT Create( + LPCTSTR szFilename, + DWORD dwDesiredAccess, + DWORD dwShareMode, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + LPSECURITY_ATTRIBUTES lpsa, + HANDLE hTemplateFile) throw(); + + HRESULT Flush() throw(); + HRESULT GetOverlappedResult( + LPOVERLAPPED pOverlapped, + DWORD& dwBytesTransferred, + BOOL bWait + ) throw(); + + HRESULT GetPosition(ULONGLONG& nPos) const throw(); + HRESULT GetSize(ULONGLONG& nLen) const throw(); + HRESULT LockRange(ULONGLONG nPos, ULONGLONG nCount) throw(); + + HRESULT Read( + LPVOID pBuffer, + DWORD nBufSize) throw(); + + HRESULT Read( + LPVOID pBuffer, + DWORD nBufSize, + DWORD& nBytesRead) throw(); + HRESULT Read( + LPVOID pBuffer, + DWORD nBufSize, + LPOVERLAPPED pOverlapped) throw(); + HRESULT Read( + LPVOID pBuffer, + DWORD nBufSize, + LPOVERLAPPED pOverlapped, + LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine) throw(); + + HRESULT Seek( + LONGLONG nOffset, + DWORD dwFrom) throw(); + + HRESULT SetSize(ULONGLONG nNewLen) throw(); + HRESULT UnlockRange(ULONGLONG nPos, ULONGLONG nCount) throw(); + HRESULT Write( + LPCVOID pBuffer, + DWORD nBufSize, + LPOVERLAPPED pOverlapped, + LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine) throw(); + + HRESULT Write( + LPCVOID pBuffer, + DWORD nBufSize, + DWORD* pnBytesWritten) throw(); + + HRESULT Write( + LPCVOID pBuffer, + DWORD nBufSize, + LPOVERLAPPED pOverlapped) throw(); +}; + +void test_CAtlFile() { + CAtlFile catFile; + char buffer[1024]; + catFile.Read(buffer, 1024); // $ MISSING: local_source +} From 74eae4a18dd1fa02e6256ea41e156b4c918ff9b6 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:21:45 +0000 Subject: [PATCH 030/213] C++: Add a MaD model for 'CAtlFile' and mark reads as local flow sources. --- cpp/ql/lib/ext/CAtlFile.model.yml | 9 +++++++++ cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../cpp/models/implementations/CAtlFile.qll | 17 +++++++++++++++++ .../dataflow/source-sink-tests/atl.cpp | 2 +- 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/lib/ext/CAtlFile.model.yml create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFile.qll diff --git a/cpp/ql/lib/ext/CAtlFile.model.yml b/cpp/ql/lib/ext/CAtlFile.model.yml new file mode 100644 index 000000000000..03584d62f037 --- /dev/null +++ b/cpp/ql/lib/ext/CAtlFile.model.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CAtlFile", True, "CAtlFile", "(CAtlFile &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CAtlFile", True, "CAtlFile", "(HANDLE)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CAtlFile", True, "Create", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CAtlFile", True, "Read", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"] diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index b371e6dc116c..37c97dcca8df 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -53,3 +53,4 @@ private import implementations.Win32CommandExecution private import implementations.CA2AEX private import implementations.CComBSTR private import implementations.CPathT +private import implementations.CAtlFile diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFile.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFile.qll new file mode 100644 index 000000000000..6c01a29c539d --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFile.qll @@ -0,0 +1,17 @@ +import semmle.code.cpp.models.interfaces.FlowSource + +/** + * The `CAtlFile` class from Microsoft's Active Template Library. + */ +class CAtlFile extends Class { + CAtlFile() { this.hasGlobalName("CAtlFile") } +} + +private class CAtlFileRead extends MemberFunction, LocalFlowSourceFunction { + CAtlFileRead() { this.getClassAndName("Read") instanceof CAtlFile } + + override predicate hasLocalFlowSource(FunctionOutput output, string description) { + output.isParameterDeref(0) and + description = "string read by " + this.getName() + } +} diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index bcc75fe0bd13..2724e42aa345 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -133,5 +133,5 @@ struct CAtlFile : public CHandle { void test_CAtlFile() { CAtlFile catFile; char buffer[1024]; - catFile.Read(buffer, 1024); // $ MISSING: local_source + catFile.Read(buffer, 1024); // $ local_source } From ac0599cf75a4b1f50ca7fbe9317ded9bb2d136ba Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:24:35 +0000 Subject: [PATCH 031/213] C++: Add a failing test with 'CAtlFileMapping'. --- .../dataflow/source-sink-tests/atl.cpp | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index 2724e42aa345..63d1bb171052 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -135,3 +135,47 @@ void test_CAtlFile() { char buffer[1024]; catFile.Read(buffer, 1024); // $ local_source } + +struct CAtlFileMappingBase { + CAtlFileMappingBase(CAtlFileMappingBase& orig); + CAtlFileMappingBase() throw(); + ~CAtlFileMappingBase() throw(); + + HRESULT CopyFrom(CAtlFileMappingBase& orig) throw(); + void* GetData() const throw(); + HANDLE GetHandle() throw (); + SIZE_T GetMappingSize() throw(); + + HRESULT MapFile( + HANDLE hFile, + SIZE_T nMappingSize, + ULONGLONG nOffset, + DWORD dwMappingProtection, + DWORD dwViewDesiredAccess) throw(); + + HRESULT MapSharedMem( + SIZE_T nMappingSize, + LPCTSTR szName, + BOOL* pbAlreadyExisted, + LPSECURITY_ATTRIBUTES lpsa, + DWORD dwMappingProtection, + DWORD dwViewDesiredAccess) throw(); + + HRESULT OpenMapping( + LPCTSTR szName, + SIZE_T nMappingSize, + ULONGLONG nOffset, + DWORD dwViewDesiredAccess) throw(); + + HRESULT Unmap() throw(); +}; + +template +struct CAtlFileMapping : public CAtlFileMappingBase { + operator T*() const throw(); +}; + +void test_CAtlFileMapping(CAtlFileMapping mapping) { + char* data = static_cast(mapping); // $ MISSING: local_source + void* data2 = mapping.GetData(); // $ MISSING: local_source +} From 3709151353ecf426f73341a35d0642d5f91de93b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:31:12 +0000 Subject: [PATCH 032/213] C++: Add a MaD model for 'CAtlFileMappingBase' and mark reads as local flow sources. --- cpp/ql/lib/ext/CAtlFileMappingBase.model.yml | 13 +++++++ cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../implementations/CAtlFileMapping.qll | 37 +++++++++++++++++++ .../dataflow/source-sink-tests/atl.cpp | 4 +- 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 cpp/ql/lib/ext/CAtlFileMappingBase.model.yml create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFileMapping.qll diff --git a/cpp/ql/lib/ext/CAtlFileMappingBase.model.yml b/cpp/ql/lib/ext/CAtlFileMappingBase.model.yml new file mode 100644 index 000000000000..dcf9fd6ca70d --- /dev/null +++ b/cpp/ql/lib/ext/CAtlFileMappingBase.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CAtlFileMappingBase", True, "CAtlFileMappingBase", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CAtlFileMappingBase", True, "CopyFrom", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CAtlFileMappingBase", True, "GetData", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CAtlFileMappingBase", True, "GetHandle", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CAtlFileMappingBase", True, "MapFile", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CAtlFileMappingBase", True, "MapSharedMem", "", "", "Argument[*1]", "Argument[-1]", "taint", "manual"] + - ["", "CAtlFileMappingBase", True, "OpenMapping", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CAtlFileMappingBase", True, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index 37c97dcca8df..f6ff93061af0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -54,3 +54,4 @@ private import implementations.CA2AEX private import implementations.CComBSTR private import implementations.CPathT private import implementations.CAtlFile +private import implementations.CAtlFileMapping diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFileMapping.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFileMapping.qll new file mode 100644 index 000000000000..85dae06806fb --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlFileMapping.qll @@ -0,0 +1,37 @@ +import semmle.code.cpp.models.interfaces.FlowSource + +/** + * The `CAtlFileMapping` class from Microsoft's Active Template Library. + */ +class CAtlFileMapping extends Class { + CAtlFileMapping() { this.hasGlobalName("CAtlFileMapping") } +} + +/** + * The `CAtlFileMappingBase` class from Microsoft's Active Template Library. + */ +class CAtlFileMappingBase extends Class { + CAtlFileMappingBase() { this.hasGlobalName("CAtlFileMappingBase") } +} + +private class CAtlFileMappingBaseGetData extends MemberFunction, LocalFlowSourceFunction { + CAtlFileMappingBaseGetData() { + this.getClassAndName("GetData") = any(CAtlFileMappingBase fileMaping).getADerivedClass*() + } + + override predicate hasLocalFlowSource(FunctionOutput output, string description) { + output.isReturnValueDeref(1) and + description = "data read by " + this.getName() + } +} + +private class CAtlFileMappingGetData extends MemberFunction, LocalFlowSourceFunction { + CAtlFileMappingGetData() { + this.(ConversionOperator).getDeclaringType() instanceof CAtlFileMapping + } + + override predicate hasLocalFlowSource(FunctionOutput output, string description) { + output.isReturnValueDeref(1) and + description = "data read by " + this.getName() + } +} diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index 63d1bb171052..8a9f9f0ea0a8 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -176,6 +176,6 @@ struct CAtlFileMapping : public CAtlFileMappingBase { }; void test_CAtlFileMapping(CAtlFileMapping mapping) { - char* data = static_cast(mapping); // $ MISSING: local_source - void* data2 = mapping.GetData(); // $ MISSING: local_source + char* data = static_cast(mapping); // $ local_source + void* data2 = mapping.GetData(); // $ local_source } From 67ba85a0a3bf4c20f51fcf04c383fc876d48970c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:32:59 +0000 Subject: [PATCH 033/213] C++: Add failing tests for 'CAtlTemporaryFile'. --- .../dataflow/source-sink-tests/atl.cpp | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index 8a9f9f0ea0a8..3440940a4f0d 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -179,3 +179,39 @@ void test_CAtlFileMapping(CAtlFileMapping mapping) { char* data = static_cast(mapping); // $ local_source void* data2 = mapping.GetData(); // $ local_source } + +struct CAtlTemporaryFile { + CAtlTemporaryFile() throw(); + ~CAtlTemporaryFile() throw(); + HRESULT Close(LPCTSTR szNewName) throw(); + HRESULT Create(LPCTSTR pszDir, DWORD dwDesiredAccess) throw(); + HRESULT Flush() throw(); + HRESULT GetPosition(ULONGLONG& nPos) const throw(); + HRESULT GetSize(ULONGLONG& nLen) const throw(); + HRESULT HandsOff() throw(); + HRESULT HandsOn() throw(); + HRESULT LockRange(ULONGLONG nPos, ULONGLONG nCount) throw(); + + HRESULT Read( + LPVOID pBuffer, + DWORD nBufSize, + DWORD& nBytesRead) throw(); + HRESULT Seek(LONGLONG nOffset, DWORD dwFrom) throw(); + + HRESULT SetSize(ULONGLONG nNewLen) throw(); + LPCTSTR TempFileName() throw(); + HRESULT UnlockRange(ULONGLONG nPos, ULONGLONG nCount) throw(); + + HRESULT Write( + LPCVOID pBuffer, + DWORD nBufSize, + DWORD* pnBytesWritten) throw(); + operator HANDLE() throw(); +}; + +void test_CAtlTemporaryFile() { + CAtlTemporaryFile file; + char buffer[1024]; + DWORD bytesRead; + file.Read(buffer, 1024, bytesRead); // $ MISSING: local_source +} From 33212da87621c003703992660b5ab524e38096eb Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:38:34 +0000 Subject: [PATCH 034/213] C++: Add a MaD model for 'CAtlTemporaryFile' and mark reads as local flow sources. --- cpp/ql/lib/ext/CAtlTemporaryFile.model.yml | 8 ++++++++ cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../implementations/CAtlTemporaryFile.qll | 17 +++++++++++++++++ .../dataflow/source-sink-tests/atl.cpp | 2 +- 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/lib/ext/CAtlTemporaryFile.model.yml create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlTemporaryFile.qll diff --git a/cpp/ql/lib/ext/CAtlTemporaryFile.model.yml b/cpp/ql/lib/ext/CAtlTemporaryFile.model.yml new file mode 100644 index 000000000000..71a05266a2d3 --- /dev/null +++ b/cpp/ql/lib/ext/CAtlTemporaryFile.model.yml @@ -0,0 +1,8 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CAtlTemporaryFile", True, "Create", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CAtlTemporaryFile", True, "Read", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"] + - ["", "CAtlTemporaryFile", True, "Write", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index f6ff93061af0..cd86b53f90e0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -55,3 +55,4 @@ private import implementations.CComBSTR private import implementations.CPathT private import implementations.CAtlFile private import implementations.CAtlFileMapping +private import implementations.CAtlTemporaryFile diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlTemporaryFile.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlTemporaryFile.qll new file mode 100644 index 000000000000..cc3a36d0fbd7 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/CAtlTemporaryFile.qll @@ -0,0 +1,17 @@ +import semmle.code.cpp.models.interfaces.FlowSource + +/** + * The `CAtlFile` class from Microsoft's Active Template Library. + */ +class CAtlTemporaryFile extends Class { + CAtlTemporaryFile() { this.hasGlobalName("CAtlTemporaryFile") } +} + +private class CAtlTemporaryFileRead extends MemberFunction, LocalFlowSourceFunction { + CAtlTemporaryFileRead() { this.getClassAndName("Read") instanceof CAtlTemporaryFile } + + override predicate hasLocalFlowSource(FunctionOutput output, string description) { + output.isParameterDeref(0) and + description = "string read by " + this.getName() + } +} diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index 3440940a4f0d..35698f13e847 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -213,5 +213,5 @@ void test_CAtlTemporaryFile() { CAtlTemporaryFile file; char buffer[1024]; DWORD bytesRead; - file.Read(buffer, 1024, bytesRead); // $ MISSING: local_source + file.Read(buffer, 1024, bytesRead); // $ local_source } From 5aada39a4e0a146f880bd2d94b719f975fde5412 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:40:37 +0000 Subject: [PATCH 035/213] C++: Add failing tests for 'CRegKey'. --- .../dataflow/source-sink-tests/atl.cpp | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index 35698f13e847..e8fbcbf96609 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -215,3 +215,175 @@ void test_CAtlTemporaryFile() { DWORD bytesRead; file.Read(buffer, 1024, bytesRead); // $ local_source } + +struct CRegKey { + CRegKey() throw(); + CRegKey(CRegKey& key) throw(); + explicit CRegKey(HKEY hKey) throw(); + CRegKey(CAtlTransactionManager* pTM) throw(); + + ~CRegKey() throw(); + void Attach(HKEY hKey) throw(); + LONG Close() throw(); + + LONG Create( + HKEY hKeyParent, + LPCTSTR lpszKeyName, + LPTSTR lpszClass, + DWORD dwOptions, + REGSAM samDesired, + LPSECURITY_ATTRIBUTES lpSecAttr, + LPDWORD lpdwDisposition) throw(); + + LONG DeleteSubKey(LPCTSTR lpszSubKey) throw(); + LONG DeleteValue(LPCTSTR lpszValue) throw(); + HKEY Detach() throw(); + + LONG EnumKey( + DWORD iIndex, + LPTSTR pszName, + LPDWORD pnNameLength, + FILETIME* pftLastWriteTime) throw(); + + LONG Flush() throw(); + + LONG GetKeySecurity( + SECURITY_INFORMATION si, + PSECURITY_DESCRIPTOR psd, + LPDWORD pnBytes) throw(); + + LONG NotifyChangeKeyValue( + BOOL bWatchSubtree, + DWORD dwNotifyFilter, + HANDLE hEvent, + BOOL bAsync) throw(); + + LONG Open( + HKEY hKeyParent, + LPCTSTR lpszKeyName, + REGSAM samDesired) throw(); + + LONG QueryBinaryValue( + LPCTSTR pszValueName, + void* pValue, + ULONG* pnBytes) throw(); + + LONG QueryDWORDValue( + LPCTSTR pszValueName, + DWORD& dwValue) throw(); + + LONG QueryGUIDValue( + LPCTSTR pszValueName, + GUID& guidValue) throw(); + + LONG QueryMultiStringValue( + LPCTSTR pszValueName, + LPTSTR pszValue, + ULONG* pnChars) throw(); + + LONG QueryQWORDValue( + LPCTSTR pszValueName, + ULONGLONG& qwValue) throw(); + + LONG QueryStringValue( + LPCTSTR pszValueName, + LPTSTR pszValue, + ULONG* pnChars) throw(); + + LONG QueryValue( + LPCTSTR pszValueName, + DWORD* pdwType, + void* pData, + ULONG* pnBytes) throw(); + + LONG QueryValue( + DWORD& dwValue, + LPCTSTR lpszValueName); + + LONG QueryValue( + LPTSTR szValue, + LPCTSTR lpszValueName, + DWORD* pdwCount); + + LONG RecurseDeleteKey(LPCTSTR lpszKey) throw(); + + LONG SetBinaryValue( + LPCTSTR pszValueName, + const void* pValue, + ULONG nBytes) throw(); + + LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue) throw(); + + LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue) throw(); + + LONG SetKeySecurity(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR psd) throw(); + + LONG SetKeyValue( + LPCTSTR lpszKeyName, + LPCTSTR lpszValue, + LPCTSTR lpszValueName) throw(); + + LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue) throw(); + + LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue) throw(); + + LONG SetStringValue( + LPCTSTR pszValueName, + LPCTSTR pszValue, + DWORD dwType) throw(); + + LONG SetValue( + LPCTSTR pszValueName, + DWORD dwType, + const void* pValue, + ULONG nBytes) throw(); + + static LONG SetValue( + HKEY hKeyParent, + LPCTSTR lpszKeyName, + LPCTSTR lpszValue, + LPCTSTR lpszValueName); + + LONG SetValue( + DWORD dwValue, + LPCTSTR lpszValueName); + + LONG SetValue( + LPCTSTR lpszValue, + LPCTSTR lpszValueName, + bool bMulti, + int nValueLen); + + operator HKEY() const throw(); + CRegKey& operator= (CRegKey& key) throw(); + + HKEY m_hKey; +}; + +void test_CRegKey() { + CRegKey key; + char data[1024]; + ULONG bytesRead; + key.QueryBinaryValue("foo", data, &bytesRead); // $ MISSING: local_source + + DWORD value; + key.QueryDWORDValue("foo", value); // $ MISSING: local_source + + GUID guid; + key.QueryGUIDValue("foo", guid); // $ MISSING: local_source + + key.QueryMultiStringValue("foo", data, &bytesRead); // $ MISSING: local_source + + ULONGLONG qword; + key.QueryQWORDValue("foo", qword); // $ MISSING: local_source + + key.QueryStringValue("foo", data, &bytesRead); // $ MISSING: local_source + + key.QueryValue(data, "foo", &bytesRead); // $ MISSING: local_source + + DWORD type; + key.QueryValue("foo", &type, data, &bytesRead); // $ MISSING: local_source + + DWORD value2; + key.QueryValue(value2, "foo"); // $ MISSING: local_source +} \ No newline at end of file From d69de0cc761fe1739962fb8277eb4a8c4afe5748 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:43:39 +0000 Subject: [PATCH 036/213] C++: Add a MaD model for 'CRegKey' and mark query calls as local flow sources. --- cpp/ql/lib/ext/CRegKey.model.yml | 19 ++++ cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../cpp/models/implementations/CRegKey.qll | 87 +++++++++++++++++++ .../dataflow/source-sink-tests/atl.cpp | 18 ++-- 4 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 cpp/ql/lib/ext/CRegKey.model.yml create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/CRegKey.qll diff --git a/cpp/ql/lib/ext/CRegKey.model.yml b/cpp/ql/lib/ext/CRegKey.model.yml new file mode 100644 index 000000000000..52b742029ac5 --- /dev/null +++ b/cpp/ql/lib/ext/CRegKey.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["", "CRegKey", True, "CRegKey", "(CRegKey&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CRegKey", True, "CRegKey", "(HKEY)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CRegKey", True, "Attach", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryBinaryValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryDWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryMultiStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryQWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"] + - ["", "CRegKey", True, "QueryValue", "(DWORD&,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] + - ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[**0]", "taint", "manual"] + - ["", "CRegKey", True, "QueryValue", "operator HKEY", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "Argument[-1]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index cd86b53f90e0..83bda3e2a44e 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -56,3 +56,4 @@ private import implementations.CPathT private import implementations.CAtlFile private import implementations.CAtlFileMapping private import implementations.CAtlTemporaryFile +private import implementations.CRegKey diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/CRegKey.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/CRegKey.qll new file mode 100644 index 000000000000..e6d1a5ba09ec --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/CRegKey.qll @@ -0,0 +1,87 @@ +private import cpp +private import semmle.code.cpp.models.interfaces.FlowSource +private import semmle.code.cpp.ir.dataflow.FlowSteps +private import semmle.code.cpp.dataflow.new.DataFlow + +/** The `CRegKey` class from the Microsoft "Active Template Library". */ +class CRegKey extends Class { + CRegKey() { this.hasGlobalName("CRegKey") } +} + +module CRegKey { + /** The `m_hKey` member on a object of type `CRegKey`. */ + class MhKey extends Field { + MhKey() { + this.getDeclaringType() instanceof CRegKey and + this.getName() = "m_hKey" + } + } + + private class MhKeyPathTaintInheritingContent extends TaintInheritingContent, + DataFlow::FieldContent + { + MhKeyPathTaintInheritingContent() { this.getField() instanceof MhKey } + } + + private class CRegKeyMemberFunction extends MemberFunction { + string name; + + CRegKeyMemberFunction() { this.getClassAndName(name) instanceof CRegKey } + } + + abstract private class CRegKeyFlowSource extends CRegKeyMemberFunction, LocalFlowSourceFunction { + FunctionOutput output; + + final override predicate hasLocalFlowSource(FunctionOutput output_, string description) { + output_ = output and + description = "registry string read by " + name + } + } + + /** The `CRegKey::QueryBinaryValue` function from Win32. */ + class QueryBinaryValue extends CRegKeyFlowSource { + QueryBinaryValue() { name = "QueryBinaryValue" and output.isParameterDeref(1) } + } + + /** The `CRegKey::QueryDWORDValue` function from Win32. */ + class QueryDwordValue extends CRegKeyFlowSource { + QueryDwordValue() { name = "QueryDWORDValue" and output.isParameterDeref(1) } + } + + /** The `CRegKey::QueryGUIDValue` function from Win32. */ + class QueryGuidValue extends CRegKeyFlowSource { + QueryGuidValue() { name = "QueryGUIDValue" and output.isParameterDeref(1) } + } + + /** The `CRegKey::QueryMultiStringValue` function from Win32. */ + class QueryMultiStringValue extends CRegKeyFlowSource { + QueryMultiStringValue() { name = "QueryMultiStringValue" and output.isParameterDeref(1) } + } + + /** The `CRegKey::QueryQWORDValue` function from Win32. */ + class QueryQwordValue extends CRegKeyFlowSource { + QueryQwordValue() { name = "QueryQWORDValue" and output.isParameterDeref(1) } + } + + /** The `CRegKey::QueryStringValue` function from Win32. */ + class QueryStringValue extends CRegKeyFlowSource { + QueryStringValue() { name = "QueryStringValue" and output.isParameterDeref(1) } + } + + /** The `CRegKey::QueryValue` function from Win32. */ + class QueryValue extends CRegKeyFlowSource { + QueryValue() { + name = "QueryValue" and + ( + this.getNumberOfParameters() = 4 and + output.isParameterDeref(2) + or + this.getNumberOfParameters() = 2 and + output.isParameterDeref(0) + or + this.getNumberOfParameters() = 3 and + output.isParameterDeref(0) + ) + } + } +} diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp index e8fbcbf96609..7df5e3dc1a08 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp @@ -364,26 +364,26 @@ void test_CRegKey() { CRegKey key; char data[1024]; ULONG bytesRead; - key.QueryBinaryValue("foo", data, &bytesRead); // $ MISSING: local_source + key.QueryBinaryValue("foo", data, &bytesRead); // $ local_source DWORD value; - key.QueryDWORDValue("foo", value); // $ MISSING: local_source + key.QueryDWORDValue("foo", value); // $ local_source GUID guid; - key.QueryGUIDValue("foo", guid); // $ MISSING: local_source + key.QueryGUIDValue("foo", guid); // $ local_source - key.QueryMultiStringValue("foo", data, &bytesRead); // $ MISSING: local_source + key.QueryMultiStringValue("foo", data, &bytesRead); // $ local_source ULONGLONG qword; - key.QueryQWORDValue("foo", qword); // $ MISSING: local_source + key.QueryQWORDValue("foo", qword); // $ local_source - key.QueryStringValue("foo", data, &bytesRead); // $ MISSING: local_source + key.QueryStringValue("foo", data, &bytesRead); // $ local_source - key.QueryValue(data, "foo", &bytesRead); // $ MISSING: local_source + key.QueryValue(data, "foo", &bytesRead); // $ local_source DWORD type; - key.QueryValue("foo", &type, data, &bytesRead); // $ MISSING: local_source + key.QueryValue("foo", &type, data, &bytesRead); // $ local_source DWORD value2; - key.QueryValue(value2, "foo"); // $ MISSING: local_source + key.QueryValue(value2, "foo"); // $ local_source } \ No newline at end of file From 19e7c3776049a71101397e5fde8156969e932d66 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 15:47:29 +0000 Subject: [PATCH 037/213] C++: Update the final test changes. Nothing exciting here. --- .../dataflow/external-models/flow.expected | 10 +- .../external-models/validatemodels.expected | 14 +- .../taint-tests/test_mad-signatures.expected | 848 ++++++++++++++++++ 3 files changed, 861 insertions(+), 11 deletions(-) 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 d1e895f2eafb..3c5b69b09f4b 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:819 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:817 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:818 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:809 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:807 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:808 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:818 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:808 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:819 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:809 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index b02760131065..166d834ea768 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -5,23 +5,25 @@ | Dubious member name "operator LPSTR" in summary model. | | Dubious member name "operator LPWSTR" in summary model. | | Dubious member name "operator PCXSTR" in summary model. | -| Dubious member name "operator StringType&" in summary model. | -| Dubious member name "operator T*" in summary model. | -| Dubious member name "operator const StringType&" in summary model. | | Dubious member name "operator&" in summary model. | | Dubious member name "operator*" in summary model. | | Dubious member name "operator+=" in summary model. | | Dubious member name "operator->" in summary model. | | Dubious member name "operator=" in summary model. | | Dubious member name "operator[]" in summary model. | +| Dubious signature "(CAtlFile &)" in summary model. | | Dubious signature "(CRegKey&)" in summary model. | | Dubious signature "(DWORD&,LPCTSTR)" in summary model. | | Dubious signature "(InputIterator,InputIterator,const Allocator &)" in summary model. | +| Dubious signature "(LPCTSTR,DWORD *,void *,ULONG *)" in summary model. | +| Dubious signature "(LPTSTR,LPCTSTR,DWORD *)" in summary model. | | Dubious signature "(const CComBSTR&)" in summary model. | +| Dubious signature "(const CComSafeArray &)" in summary model. | | Dubious signature "(const CComSafeArray&)" in summary model. | -| Dubious signature "(const SAFEARRAY&)" in summary model. | -| Dubious signature "(const SAFEARRAY*)" in summary model. | -| Dubious signature "(const SAFEARRAYBOUND*, UINT)" in summary model. | +| Dubious signature "(const SAFEARRAY &)" in summary model. | +| Dubious signature "(const SAFEARRAY *)" in summary model. | +| Dubious signature "(const SAFEARRAYBOUND *,UINT)" in summary model. | +| Dubious signature "(const T &,BOOL)" in summary model. | | Dubious signature "(const deque &)" in summary model. | | Dubious signature "(const deque &,const Allocator &)" in summary model. | | Dubious signature "(const forward_list &)" in summary model. | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 26031f42c0ac..1f84cd3379af 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -1,4 +1,90 @@ signatureMatches +| atl.cpp:68:3:68:15 | _U_STRINGorID | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:68:3:68:15 | _U_STRINGorID | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:69:3:69:15 | _U_STRINGorID | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:256:3:256:10 | CAtlList | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:256:3:256:10 | CAtlList | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:410:3:410:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:410:3:410:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 1 | +| atl.cpp:411:3:411:10 | CComBSTR | (int,LPCSTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:411:3:411:10 | CComBSTR | (int,LPCSTR) | CComBSTR | CComBSTR | 1 | +| atl.cpp:412:3:412:10 | CComBSTR | (LPCOLESTR) | CComBSTR | Append | 0 | +| atl.cpp:412:3:412:10 | CComBSTR | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:413:3:413:10 | CComBSTR | (LPCSTR) | CComBSTR | Append | 0 | +| atl.cpp:413:3:413:10 | CComBSTR | (LPCSTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:418:11:418:16 | Append | (wchar_t) | CComBSTR | Append | 0 | +| atl.cpp:419:11:419:16 | Append | (char) | CComBSTR | Append | 0 | +| atl.cpp:420:11:420:16 | Append | (LPCOLESTR) | CComBSTR | Append | 0 | +| atl.cpp:420:11:420:16 | Append | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:421:11:421:16 | Append | (LPCSTR) | CComBSTR | Append | 0 | +| atl.cpp:421:11:421:16 | Append | (LPCSTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:422:11:422:16 | Append | (LPCOLESTR,int) | CComBSTR | Append | 0 | +| atl.cpp:422:11:422:16 | Append | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| atl.cpp:424:11:424:21 | AppendBytes | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| atl.cpp:425:11:425:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | Add | 0 | +| atl.cpp:425:11:425:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | +| atl.cpp:425:11:425:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | +| atl.cpp:437:8:437:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:437:8:437:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 1 | +| atl.cpp:437:8:437:17 | LoadString | (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 1 | +| atl.cpp:438:8:438:17 | LoadString | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:438:8:438:17 | LoadString | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:447:13:447:22 | operator+= | (LPCOLESTR) | CComBSTR | Append | 0 | +| atl.cpp:447:13:447:22 | operator+= | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:537:3:537:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | Add | 0 | +| atl.cpp:537:3:537:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | +| atl.cpp:537:3:537:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | +| atl.cpp:541:11:541:13 | Add | (const SAFEARRAY *) | CComSafeArray | Add | 0 | +| atl.cpp:541:11:541:13 | Add | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | +| atl.cpp:541:11:541:13 | Add | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | +| atl.cpp:543:11:543:13 | Add | (const T &,BOOL) | CComSafeArray | Add | 0 | +| atl.cpp:543:11:543:13 | Add | (const T &,BOOL) | CComSafeArray | Add | 1 | +| atl.cpp:762:8:762:10 | Add | (const deque &,const Allocator &) | deque | deque | 1 | +| atl.cpp:762:8:762:10 | Add | (const forward_list &,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:762:8:762:10 | Add | (const list &,const Allocator &) | list | list | 1 | +| atl.cpp:762:8:762:10 | Add | (const vector &,const Allocator &) | vector | vector | 1 | +| atl.cpp:762:8:762:10 | Add | (deque &&,const Allocator &) | deque | deque | 1 | +| atl.cpp:762:8:762:10 | Add | (forward_list &&,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:762:8:762:10 | Add | (list &&,const Allocator &) | list | list | 1 | +| atl.cpp:762:8:762:10 | Add | (vector &&,const Allocator &) | vector | vector | 1 | +| atl.cpp:773:8:773:12 | SetAt | (const deque &,const Allocator &) | deque | deque | 1 | +| atl.cpp:773:8:773:12 | SetAt | (const forward_list &,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:773:8:773:12 | SetAt | (const list &,const Allocator &) | list | list | 1 | +| atl.cpp:773:8:773:12 | SetAt | (const vector &,const Allocator &) | vector | vector | 1 | +| atl.cpp:773:8:773:12 | SetAt | (deque &&,const Allocator &) | deque | deque | 1 | +| atl.cpp:773:8:773:12 | SetAt | (forward_list &&,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:773:8:773:12 | SetAt | (list &&,const Allocator &) | list | list | 1 | +| atl.cpp:773:8:773:12 | SetAt | (vector &&,const Allocator &) | vector | vector | 1 | +| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | deque | deque | 2 | +| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | forward_list | forward_list | 2 | +| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | list | list | 2 | +| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | vector | vector | 2 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | deque | deque | 1 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | deque | deque | 2 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | forward_list | forward_list | 2 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | list | list | 1 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | list | list | 2 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | vector | vector | 1 | +| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | vector | vector | 2 | +| atl.cpp:839:15:839:26 | SetExtraInfo | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:840:15:840:25 | SetHostName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:841:15:841:25 | SetPassword | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:844:15:844:27 | SetSchemeName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:845:15:845:24 | SetUrlPath | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:846:15:846:25 | SetUserName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| constructor_delegation.cpp:10:2:10:8 | MyValue | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| constructor_delegation.cpp:19:2:19:15 | MyDerivedValue | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| standalone_iterators.cpp:103:27:103:36 | operator+= | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| stl.h:165:8:165:16 | push_back | (char) | CComBSTR | Append | 0 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | deque | assign | 0 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | deque | assign | 1 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | forward_list | assign | 0 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | forward_list | assign | 1 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | list | assign | 0 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | list | assign | 1 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | vector | assign | 0 | +| stl.h:181:47:181:52 | append | (InputIt,InputIt) | vector | assign | 1 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | deque | assign | 0 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | deque | assign | 1 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | forward_list | assign | 0 | @@ -7,6 +93,14 @@ signatureMatches | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | list | assign | 1 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | vector | assign | 0 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | vector | assign | 1 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | deque | assign | 0 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | deque | assign | 1 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | forward_list | assign | 0 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | forward_list | assign | 1 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | list | assign | 0 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | list | assign | 1 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | vector | assign | 0 | +| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | vector | assign | 1 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | deque | assign | 0 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | deque | assign | 1 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | forward_list | assign | 0 | @@ -15,6 +109,18 @@ signatureMatches | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | list | assign | 1 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | vector | assign | 0 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | vector | assign | 1 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | deque | insert | 0 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | deque | insert | 1 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | deque | insert | 2 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | forward_list | insert_after | 0 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | forward_list | insert_after | 1 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | forward_list | insert_after | 2 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | list | insert | 0 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | list | insert | 1 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | list | insert | 2 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | vector | insert | 0 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | vector | insert | 1 | +| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | vector | insert | 2 | | stl.h:190:17:190:23 | replace | (const_iterator,InputIt,InputIt) | deque | insert | 0 | | stl.h:190:17:190:23 | replace | (const_iterator,InputIt,InputIt) | deque | insert | 1 | | stl.h:190:17:190:23 | replace | (const_iterator,InputIt,InputIt) | deque | insert | 2 | @@ -267,7 +373,24 @@ signatureMatches | stl.h:678:33:678:38 | format | (format_string,Args &&) | | format | 1 | | stl.h:683:6:683:48 | same_signature_as_format_but_different_name | (format_string,Args &&) | | format | 0 | | stl.h:683:6:683:48 | same_signature_as_format_but_different_name | (format_string,Args &&) | | format | 1 | +| string.cpp:20:6:20:9 | sink | (char) | CComBSTR | Append | 0 | +| taint.cpp:4:6:4:21 | arithAssignments | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| taint.cpp:249:13:249:13 | _FUN | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| taint.cpp:249:13:249:13 | operator() | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| taint.cpp:302:6:302:14 | myAssign2 | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| taint.cpp:307:6:307:14 | myAssign3 | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| taint.cpp:312:6:312:14 | myAssign4 | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| taint.cpp:523:7:523:13 | _strset | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| vector.cpp:333:6:333:35 | vector_iterator_assign_wrapper | (LPCOLESTR,int) | CComBSTR | Append | 1 | getSignatureParameterName +| (CAtlFile &) | CAtlFile | CAtlFile | 0 | CAtlFile & | +| (CRegKey&) | CRegKey | CRegKey | 0 | CRegKey& | +| (DWORD&,LPCTSTR) | CRegKey | QueryValue | 0 | DWORD& | +| (DWORD&,LPCTSTR) | CRegKey | QueryValue | 1 | LPCTSTR | +| (HANDLE) | CAtlFile | CAtlFile | 0 | HANDLE | +| (HINSTANCE,UINT) | CComBSTR | LoadString | 0 | HINSTANCE | +| (HINSTANCE,UINT) | CComBSTR | LoadString | 1 | UINT | +| (HKEY) | CRegKey | CRegKey | 0 | HKEY | | (InputIt,InputIt) | deque | assign | 0 | func:0 | | (InputIt,InputIt) | deque | assign | 1 | func:0 | | (InputIt,InputIt) | forward_list | assign | 0 | func:0 | @@ -288,6 +411,35 @@ getSignatureParameterName | (InputIterator,InputIterator,const Allocator &) | vector | vector | 0 | func:0 | | (InputIterator,InputIterator,const Allocator &) | vector | vector | 1 | func:0 | | (InputIterator,InputIterator,const Allocator &) | vector | vector | 2 | const class:1 & | +| (LPCOLESTR) | CComBSTR | Append | 0 | LPCOLESTR | +| (LPCOLESTR) | CComBSTR | CComBSTR | 0 | LPCOLESTR | +| (LPCOLESTR,int) | CComBSTR | Append | 0 | LPCOLESTR | +| (LPCOLESTR,int) | CComBSTR | Append | 1 | int | +| (LPCSTR) | CComBSTR | Append | 0 | LPCSTR | +| (LPCSTR) | CComBSTR | CComBSTR | 0 | LPCSTR | +| (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | LPCTSTR | +| (LPCTSTR,DWORD *,void *,ULONG *) | CRegKey | QueryValue | 0 | LPCTSTR | +| (LPCTSTR,DWORD *,void *,ULONG *) | CRegKey | QueryValue | 1 | DWORD * | +| (LPCTSTR,DWORD *,void *,ULONG *) | CRegKey | QueryValue | 2 | void * | +| (LPCTSTR,DWORD *,void *,ULONG *) | CRegKey | QueryValue | 3 | ULONG * | +| (LPTSTR,LPCTSTR,DWORD *) | CRegKey | QueryValue | 0 | LPTSTR | +| (LPTSTR,LPCTSTR,DWORD *) | CRegKey | QueryValue | 1 | LPCTSTR | +| (LPTSTR,LPCTSTR,DWORD *) | CRegKey | QueryValue | 2 | DWORD * | +| (UINT) | CComBSTR | LoadString | 0 | UINT | +| (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | UINT | +| (char) | CComBSTR | Append | 0 | char | +| (const CComBSTR&) | CComBSTR | Append | 0 | const CComBSTR& | +| (const CComBSTR&) | CComBSTR | CComBSTR | 0 | const CComBSTR& | +| (const CComSafeArray &) | CComSafeArray | CComSafeArray | 0 | const CComSafeArray & | +| (const CComSafeArray&) | CComSafeArray | operator= | 0 | const CComSafeArray& | +| (const SAFEARRAY &) | CComSafeArray | CComSafeArray | 0 | const SAFEARRAY & | +| (const SAFEARRAY *) | CComSafeArray | Add | 0 | const SAFEARRAY * | +| (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | const SAFEARRAY * | +| (const SAFEARRAY *) | CComSafeArray | operator= | 0 | const SAFEARRAY * | +| (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 0 | const SAFEARRAYBOUND * | +| (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 1 | UINT | +| (const T &,BOOL) | CComSafeArray | Add | 0 | const class:0 & | +| (const T &,BOOL) | CComSafeArray | Add | 1 | BOOL | | (const deque &) | deque | deque | 0 | const deque & | | (const deque &,const Allocator &) | deque | deque | 0 | const deque & | | (const deque &,const Allocator &) | deque | deque | 1 | const class:1 & | @@ -348,6 +500,10 @@ getSignatureParameterName | (forward_list &&) | forward_list | forward_list | 0 | forward_list && | | (forward_list &&,const Allocator &) | forward_list | forward_list | 0 | forward_list && | | (forward_list &&,const Allocator &) | forward_list | forward_list | 1 | const class:1 & | +| (int,LPCOLESTR) | CComBSTR | CComBSTR | 0 | int | +| (int,LPCOLESTR) | CComBSTR | CComBSTR | 1 | LPCOLESTR | +| (int,LPCSTR) | CComBSTR | CComBSTR | 0 | int | +| (int,LPCSTR) | CComBSTR | CComBSTR | 1 | LPCSTR | | (list &&) | list | list | 0 | list && | | (list &&,const Allocator &) | list | list | 0 | list && | | (list &&,const Allocator &) | list | list | 1 | const class:1 & | @@ -374,15 +530,303 @@ getSignatureParameterName | (vector &&) | vector | vector | 0 | vector && | | (vector &&,const Allocator &) | vector | vector | 0 | vector && | | (vector &&,const Allocator &) | vector | vector | 1 | const class:1 & | +| (wchar_t) | CComBSTR | Append | 0 | wchar_t | getParameterTypeName +| arrayassignment.cpp:3:6:3:9 | sink | 0 | int | +| arrayassignment.cpp:4:6:4:9 | sink | 0 | MyInt | +| arrayassignment.cpp:5:6:5:9 | sink | 0 | MyArray | +| arrayassignment.cpp:37:7:37:7 | MyInt | 0 | const MyInt & | +| arrayassignment.cpp:44:9:44:17 | operator= | 0 | const int & | +| arrayassignment.cpp:45:9:45:17 | operator= | 0 | const MyInt & | +| arrayassignment.cpp:83:7:83:7 | MyArray | 0 | MyArray && | +| arrayassignment.cpp:83:7:83:7 | MyArray | 0 | const MyArray & | +| arrayassignment.cpp:83:7:83:7 | operator= | 0 | MyArray && | +| arrayassignment.cpp:83:7:83:7 | operator= | 0 | const MyArray & | +| arrayassignment.cpp:88:7:88:9 | get | 0 | int | +| arrayassignment.cpp:90:7:90:16 | operator[] | 0 | int | +| arrayassignment.cpp:124:6:124:9 | sink | 0 | int * | +| atl.cpp:28:8:28:8 | operator= | 0 | __POSITION && | +| atl.cpp:28:8:28:8 | operator= | 0 | const __POSITION & | +| atl.cpp:49:16:49:16 | operator= | 0 | const tagSAFEARRAYBOUND & | +| atl.cpp:49:16:49:16 | operator= | 0 | tagSAFEARRAYBOUND && | +| atl.cpp:54:16:54:16 | operator= | 0 | const tagVARIANT & | +| atl.cpp:54:16:54:16 | operator= | 0 | tagVARIANT && | +| atl.cpp:58:16:58:16 | operator= | 0 | const tagSAFEARRAY & | +| atl.cpp:58:16:58:16 | operator= | 0 | tagSAFEARRAY && | +| atl.cpp:67:8:67:8 | _U_STRINGorID | 0 | _U_STRINGorID && | +| atl.cpp:67:8:67:8 | _U_STRINGorID | 0 | const _U_STRINGorID & | +| atl.cpp:67:8:67:8 | operator= | 0 | _U_STRINGorID && | +| atl.cpp:67:8:67:8 | operator= | 0 | const _U_STRINGorID & | +| atl.cpp:68:3:68:15 | _U_STRINGorID | 0 | UINT | +| atl.cpp:69:3:69:15 | _U_STRINGorID | 0 | LPCTSTR | +| atl.cpp:193:10:193:12 | Add | 0 | INARGTYPclass:0 | +| atl.cpp:195:10:195:15 | Append | 0 | const CAtlArray & | +| atl.cpp:195:10:195:15 | Append | 0 | const CAtlArray> & | +| atl.cpp:196:8:196:11 | Copy | 0 | const CAtlArray & | +| atl.cpp:196:8:196:11 | Copy | 0 | const CAtlArray> & | +| atl.cpp:198:6:198:10 | GetAt | 0 | size_t | +| atl.cpp:202:8:202:20 | InsertArrayAt | 0 | size_t | +| atl.cpp:202:8:202:20 | InsertArrayAt | 1 | const CAtlArray * | +| atl.cpp:202:8:202:20 | InsertArrayAt | 1 | const CAtlArray> * | +| atl.cpp:203:8:203:15 | InsertAt | 0 | size_t | +| atl.cpp:203:8:203:15 | InsertAt | 1 | INARGTYPclass:0 | +| atl.cpp:203:8:203:15 | InsertAt | 2 | size_t | +| atl.cpp:208:8:208:16 | SetAtGrow | 0 | size_t | +| atl.cpp:208:8:208:16 | SetAtGrow | 1 | INARGTYPclass:0 | +| atl.cpp:210:6:210:15 | operator[] | 0 | size_t | +| atl.cpp:256:3:256:10 | CAtlList | 0 | UINT | +| atl.cpp:259:12:259:18 | AddHead | 0 | INARGTYPclass:0 | +| atl.cpp:260:8:260:18 | AddHeadList | 0 | const CAtlList * | +| atl.cpp:260:8:260:18 | AddHeadList | 0 | const CAtlList> * | +| atl.cpp:262:12:262:18 | AddTail | 0 | INARGTYPclass:0 | +| atl.cpp:263:8:263:18 | AddTailList | 0 | const CAtlList * | +| atl.cpp:263:8:263:18 | AddTailList | 0 | const CAtlList> * | +| atl.cpp:264:12:264:15 | Find | 0 | INARGTYPclass:0 | +| atl.cpp:264:12:264:15 | Find | 1 | POSITION | +| atl.cpp:265:12:265:20 | FindIndex | 0 | size_t | +| atl.cpp:266:6:266:10 | GetAt | 0 | POSITION | +| atl.cpp:279:12:279:22 | InsertAfter | 0 | POSITION | +| atl.cpp:279:12:279:22 | InsertAfter | 1 | INARGTYPclass:0 | +| atl.cpp:280:12:280:23 | InsertBefore | 0 | POSITION | +| atl.cpp:280:12:280:23 | InsertBefore | 1 | INARGTYPclass:0 | +| atl.cpp:290:8:290:12 | SetAt | 0 | POSITION | +| atl.cpp:290:8:290:12 | SetAt | 1 | INARGTYPclass:0 | +| atl.cpp:400:8:400:8 | operator= | 0 | IUnknown && | +| atl.cpp:400:8:400:8 | operator= | 0 | const IUnknown & | +| atl.cpp:402:8:402:8 | operator= | 0 | ISequentialStream && | +| atl.cpp:402:8:402:8 | operator= | 0 | const ISequentialStream & | +| atl.cpp:404:8:404:8 | operator= | 0 | IStream && | +| atl.cpp:404:8:404:8 | operator= | 0 | const IStream & | +| atl.cpp:406:8:406:8 | operator= | 0 | const CComBSTR & | +| atl.cpp:408:3:408:10 | CComBSTR | 0 | const CComBSTR & | +| atl.cpp:409:3:409:10 | CComBSTR | 0 | int | +| atl.cpp:410:3:410:10 | CComBSTR | 0 | int | +| atl.cpp:410:3:410:10 | CComBSTR | 1 | LPCOLESTR | +| atl.cpp:411:3:411:10 | CComBSTR | 0 | int | +| atl.cpp:411:3:411:10 | CComBSTR | 1 | LPCSTR | +| atl.cpp:412:3:412:10 | CComBSTR | 0 | LPCOLESTR | +| atl.cpp:413:3:413:10 | CComBSTR | 0 | LPCSTR | +| atl.cpp:414:3:414:10 | CComBSTR | 0 | CComBSTR && | +| atl.cpp:417:11:417:16 | Append | 0 | const CComBSTR & | +| atl.cpp:418:11:418:16 | Append | 0 | wchar_t | +| atl.cpp:419:11:419:16 | Append | 0 | char | +| atl.cpp:420:11:420:16 | Append | 0 | LPCOLESTR | +| atl.cpp:421:11:421:16 | Append | 0 | LPCSTR | +| atl.cpp:422:11:422:16 | Append | 0 | LPCOLESTR | +| atl.cpp:422:11:422:16 | Append | 1 | int | +| atl.cpp:423:11:423:20 | AppendBSTR | 0 | BSTR | +| atl.cpp:424:11:424:21 | AppendBytes | 0 | const char * | +| atl.cpp:424:11:424:21 | AppendBytes | 1 | int | +| atl.cpp:425:11:425:21 | ArrayToBSTR | 0 | const SAFEARRAY * | +| atl.cpp:426:11:426:20 | AssignBSTR | 0 | const BSTR | +| atl.cpp:427:8:427:13 | Attach | 0 | BSTR | +| atl.cpp:428:11:428:21 | BSTRToArray | 0 | LPSAFEARRAY | +| atl.cpp:431:11:431:16 | CopyTo | 0 | BSTR * | +| atl.cpp:433:11:433:16 | CopyTo | 0 | VARIANT * | +| atl.cpp:437:8:437:17 | LoadString | 0 | HINSTANCE | +| atl.cpp:437:8:437:17 | LoadString | 1 | UINT | +| atl.cpp:438:8:438:17 | LoadString | 0 | UINT | +| atl.cpp:439:11:439:24 | ReadFromStream | 0 | IStream * | +| atl.cpp:441:11:441:23 | WriteToStream | 0 | IStream * | +| atl.cpp:446:13:446:22 | operator+= | 0 | const CComBSTR & | +| atl.cpp:447:13:447:22 | operator+= | 0 | LPCOLESTR | +| atl.cpp:537:3:537:15 | CComSafeArray | 0 | const SAFEARRAY * | +| atl.cpp:541:11:541:13 | Add | 0 | const SAFEARRAY * | +| atl.cpp:543:11:543:13 | Add | 0 | const class:0 & | +| atl.cpp:543:11:543:13 | Add | 0 | const int & | +| atl.cpp:543:11:543:13 | Add | 1 | BOOL | +| atl.cpp:551:6:551:10 | GetAt | 0 | LONG | +| atl.cpp:562:11:562:15 | SetAt | 0 | LONG | +| atl.cpp:562:11:562:15 | SetAt | 1 | const class:0 & | +| atl.cpp:562:11:562:15 | SetAt | 1 | const int & | +| atl.cpp:562:11:562:15 | SetAt | 2 | BOOL | +| atl.cpp:564:6:564:15 | operator[] | 0 | long | +| atl.cpp:565:6:565:15 | operator[] | 0 | int | +| atl.cpp:609:3:609:8 | CPathT | 0 | PCXSTR | +| atl.cpp:610:3:610:8 | CPathT | 0 | const CPathT & | +| atl.cpp:614:8:614:19 | AddExtension | 0 | PCXSTR | +| atl.cpp:615:8:615:13 | Append | 0 | PCXSTR | +| atl.cpp:618:8:618:14 | Combine | 0 | PCXSTR | +| atl.cpp:618:8:618:14 | Combine | 1 | PCXSTR | +| atl.cpp:619:22:619:33 | CommonPrefix | 0 | PCXSTR | +| atl.cpp:656:23:656:32 | operator+= | 0 | PCXSTR | +| atl.cpp:716:8:716:10 | Add | 0 | const class:0 & | +| atl.cpp:716:8:716:10 | Add | 0 | const int & | +| atl.cpp:717:7:717:10 | Find | 0 | const class:0 & | +| atl.cpp:717:7:717:10 | Find | 0 | const int & | +| atl.cpp:728:6:728:15 | operator[] | 0 | int | +| atl.cpp:729:21:729:29 | operator= | 0 | const CSimpleArray & | +| atl.cpp:762:8:762:10 | Add | 0 | char *const & | +| atl.cpp:762:8:762:10 | Add | 0 | const class:0 & | +| atl.cpp:762:8:762:10 | Add | 1 | const class:1 & | +| atl.cpp:762:8:762:10 | Add | 1 | wchar_t *const & | +| atl.cpp:763:7:763:13 | FindKey | 0 | char *const & | +| atl.cpp:763:7:763:13 | FindKey | 0 | const class:0 & | +| atl.cpp:764:7:764:13 | FindVal | 0 | const class:1 & | +| atl.cpp:764:7:764:13 | FindVal | 0 | wchar_t *const & | +| atl.cpp:767:9:767:18 | GetValueAt | 0 | int | +| atl.cpp:768:8:768:13 | Lookup | 0 | char *const & | +| atl.cpp:768:8:768:13 | Lookup | 0 | const class:0 & | +| atl.cpp:772:8:772:20 | ReverseLookup | 0 | const class:1 & | +| atl.cpp:772:8:772:20 | ReverseLookup | 0 | wchar_t *const & | +| atl.cpp:773:8:773:12 | SetAt | 0 | char *const & | +| atl.cpp:773:8:773:12 | SetAt | 0 | const class:0 & | +| atl.cpp:773:8:773:12 | SetAt | 1 | const class:1 & | +| atl.cpp:773:8:773:12 | SetAt | 1 | wchar_t *const & | +| atl.cpp:774:8:774:17 | SetAtIndex | 0 | int | +| atl.cpp:774:8:774:17 | SetAtIndex | 1 | char *const & | +| atl.cpp:774:8:774:17 | SetAtIndex | 1 | const class:0 & | +| atl.cpp:774:8:774:17 | SetAtIndex | 2 | const class:1 & | +| atl.cpp:774:8:774:17 | SetAtIndex | 2 | wchar_t *const & | +| atl.cpp:813:9:813:17 | operator= | 0 | const CUrl & | +| atl.cpp:815:3:815:6 | CUrl | 0 | const CUrl & | +| atl.cpp:818:15:818:26 | Canonicalize | 0 | DWORD | +| atl.cpp:821:8:821:15 | CrackUrl | 0 | LPCTSTR | +| atl.cpp:821:8:821:15 | CrackUrl | 1 | DWORD | +| atl.cpp:822:15:822:23 | CreateUrl | 0 | LPTSTR | +| atl.cpp:822:15:822:23 | CreateUrl | 1 | DWORD * | +| atl.cpp:822:15:822:23 | CreateUrl | 2 | DWORD | +| atl.cpp:839:15:839:26 | SetExtraInfo | 0 | LPCTSTR | +| atl.cpp:840:15:840:25 | SetHostName | 0 | LPCTSTR | +| atl.cpp:841:15:841:25 | SetPassword | 0 | LPCTSTR | +| atl.cpp:842:15:842:27 | SetPortNumber | 0 | ATL_URL_PORT | +| atl.cpp:843:15:843:23 | SetScheme | 0 | ATL_URL_SCHEME | +| atl.cpp:844:15:844:27 | SetSchemeName | 0 | LPCTSTR | +| atl.cpp:845:15:845:24 | SetUrlPath | 0 | LPCTSTR | +| atl.cpp:846:15:846:25 | SetUserName | 0 | LPCTSTR | +| bsd.cpp:6:8:6:8 | operator= | 0 | const sockaddr & | +| bsd.cpp:6:8:6:8 | operator= | 0 | sockaddr && | +| bsd.cpp:12:5:12:10 | accept | 0 | int | +| bsd.cpp:12:5:12:10 | accept | 1 | sockaddr * | +| bsd.cpp:12:5:12:10 | accept | 2 | int * | +| bsd.cpp:14:6:14:9 | sink | 0 | sockaddr | +| constructor_delegation.cpp:5:7:5:7 | MyValue | 0 | MyValue && | +| constructor_delegation.cpp:5:7:5:7 | MyValue | 0 | const MyValue & | +| constructor_delegation.cpp:5:7:5:7 | operator= | 0 | MyValue && | +| constructor_delegation.cpp:5:7:5:7 | operator= | 0 | const MyValue & | +| constructor_delegation.cpp:8:2:8:8 | MyValue | 0 | int | +| constructor_delegation.cpp:9:2:9:8 | MyValue | 0 | int | +| constructor_delegation.cpp:9:2:9:8 | MyValue | 1 | bool | +| constructor_delegation.cpp:10:2:10:8 | MyValue | 0 | int | +| constructor_delegation.cpp:10:2:10:8 | MyValue | 1 | int | +| constructor_delegation.cpp:11:2:11:8 | MyValue | 0 | int | +| constructor_delegation.cpp:11:2:11:8 | MyValue | 1 | bool | +| constructor_delegation.cpp:11:2:11:8 | MyValue | 2 | bool | +| constructor_delegation.cpp:16:7:16:7 | MyDerivedValue | 0 | MyDerivedValue && | +| constructor_delegation.cpp:16:7:16:7 | MyDerivedValue | 0 | const MyDerivedValue & | +| constructor_delegation.cpp:16:7:16:7 | operator= | 0 | MyDerivedValue && | +| constructor_delegation.cpp:16:7:16:7 | operator= | 0 | const MyDerivedValue & | +| constructor_delegation.cpp:19:2:19:15 | MyDerivedValue | 0 | bool | +| constructor_delegation.cpp:19:2:19:15 | MyDerivedValue | 1 | int | +| copyableclass.cpp:8:2:8:16 | MyCopyableClass | 0 | int | +| copyableclass.cpp:9:2:9:16 | MyCopyableClass | 0 | const MyCopyableClass & | +| copyableclass.cpp:10:19:10:27 | operator= | 0 | const MyCopyableClass & | +| copyableclass_declonly.cpp:8:2:8:24 | MyCopyableClassDeclOnly | 0 | int | +| copyableclass_declonly.cpp:9:2:9:24 | MyCopyableClassDeclOnly | 0 | const MyCopyableClassDeclOnly & | +| copyableclass_declonly.cpp:10:27:10:35 | operator= | 0 | const MyCopyableClassDeclOnly & | +| file://:0:0:0:0 | operator delete | 0 | void * | +| file://:0:0:0:0 | operator new | 0 | unsigned long | +| file://:0:0:0:0 | operator= | 0 | __va_list_tag && | +| file://:0:0:0:0 | operator= | 0 | const __va_list_tag & | +| format.cpp:3:16:3:16 | operator= | 0 | FILE && | +| format.cpp:3:16:3:16 | operator= | 0 | const FILE & | +| format.cpp:5:5:5:12 | snprintf | 0 | char * | +| format.cpp:5:5:5:12 | snprintf | 1 | size_t | +| format.cpp:5:5:5:12 | snprintf | 2 | const char * | +| format.cpp:6:5:6:11 | sprintf | 0 | char * | +| format.cpp:6:5:6:11 | sprintf | 1 | const char * | +| format.cpp:7:5:7:12 | swprintf | 0 | wchar_t * | +| format.cpp:7:5:7:12 | swprintf | 1 | size_t | +| format.cpp:7:5:7:12 | swprintf | 2 | const wchar_t * | +| format.cpp:14:5:14:13 | vsnprintf | 0 | char * | +| format.cpp:14:5:14:13 | vsnprintf | 1 | size_t | +| format.cpp:14:5:14:13 | vsnprintf | 2 | const char * | +| format.cpp:14:5:14:13 | vsnprintf | 3 | va_list | +| format.cpp:16:5:16:13 | mysprintf | 0 | char * | +| format.cpp:16:5:16:13 | mysprintf | 1 | size_t | +| format.cpp:16:5:16:13 | mysprintf | 2 | const char * | +| format.cpp:28:5:28:10 | sscanf | 0 | const char * | +| format.cpp:28:5:28:10 | sscanf | 1 | const char * | +| format.cpp:142:8:142:13 | strlen | 0 | const char * | +| format.cpp:143:8:143:13 | wcslen | 0 | const wchar_t * | +| format.cpp:169:6:169:9 | test | 0 | format_string | +| map.cpp:8:6:8:9 | sink | 0 | char * | +| map.cpp:9:6:9:9 | sink | 0 | const char * | +| map.cpp:10:6:10:9 | sink | 0 | bool | +| map.cpp:11:6:11:9 | sink | 0 | pair | +| map.cpp:12:6:12:9 | sink | 0 | map, allocator>> | +| map.cpp:13:6:13:9 | sink | 0 | iterator | +| map.cpp:14:6:14:9 | sink | 0 | unordered_map, equal_to, allocator>> | +| map.cpp:15:6:15:9 | sink | 0 | iterator | +| map.cpp:16:6:16:9 | sink | 0 | unordered_map, hash, equal_to, allocator>>> | +| map.cpp:17:6:17:9 | sink | 0 | iterator | +| map.cpp:442:7:442:19 | indirect_sink | 0 | int * | +| movableclass.cpp:5:7:5:7 | MyMovableClass | 0 | const MyMovableClass & | +| movableclass.cpp:5:7:5:7 | operator= | 0 | const MyMovableClass & | +| movableclass.cpp:8:2:8:15 | MyMovableClass | 0 | int | +| movableclass.cpp:9:2:9:15 | MyMovableClass | 0 | MyMovableClass && | +| movableclass.cpp:13:18:13:26 | operator= | 0 | MyMovableClass && | +| set.cpp:8:6:8:9 | sink | 0 | char * | +| set.cpp:9:6:9:9 | sink | 0 | set, allocator> | +| set.cpp:10:6:10:9 | sink | 0 | iterator | +| set.cpp:11:6:11:9 | sink | 0 | unordered_set, equal_to, allocator> | +| set.cpp:12:6:12:9 | sink | 0 | iterator | +| smart_pointer.cpp:4:6:4:9 | sink | 0 | int | +| smart_pointer.cpp:5:6:5:9 | sink | 0 | int * | | smart_pointer.cpp:7:27:7:30 | sink | 0 | shared_ptr & | | smart_pointer.cpp:7:27:7:30 | sink | 0 | shared_ptr & | | smart_pointer.cpp:8:27:8:30 | sink | 0 | unique_ptr & | | smart_pointer.cpp:8:27:8:30 | sink | 0 | unique_ptr & | +| smart_pointer.cpp:60:8:60:8 | operator= | 0 | A && | +| smart_pointer.cpp:60:8:60:8 | operator= | 0 | const A & | +| smart_pointer.cpp:70:6:70:14 | getNumber | 0 | shared_ptr | +| smart_pointer.cpp:80:8:80:8 | operator= | 0 | B && | +| smart_pointer.cpp:80:8:80:8 | operator= | 0 | const B & | +| smart_pointer.cpp:86:6:86:24 | test_operator_arrow | 0 | unique_ptr | +| smart_pointer.cpp:86:6:86:24 | test_operator_arrow | 1 | unique_ptr | +| smart_pointer.cpp:97:6:97:12 | taint_x | 0 | A * | +| smart_pointer.cpp:107:8:107:8 | C | 0 | C && | +| smart_pointer.cpp:107:8:107:8 | C | 0 | const C & | +| smart_pointer.cpp:107:8:107:8 | operator= | 0 | C && | +| smart_pointer.cpp:107:8:107:8 | operator= | 0 | const C & | +| smart_pointer.cpp:112:6:112:19 | taint_x_shared | 0 | shared_ptr | +| smart_pointer.cpp:116:6:116:24 | taint_x_shared_cref | 0 | const shared_ptr & | +| smart_pointer.cpp:120:6:120:18 | getNumberCRef | 0 | const shared_ptr & | +| smart_pointer.cpp:124:5:124:27 | nested_shared_ptr_taint | 0 | shared_ptr | +| smart_pointer.cpp:124:5:124:27 | nested_shared_ptr_taint | 1 | unique_ptr> | +| smart_pointer.cpp:132:5:132:32 | nested_shared_ptr_taint_cref | 0 | shared_ptr | +| smart_pointer.cpp:132:5:132:32 | nested_shared_ptr_taint_cref | 1 | unique_ptr> | +| standalone_iterators.cpp:5:6:5:9 | sink | 0 | int | +| standalone_iterators.cpp:7:7:7:7 | operator= | 0 | const int_iterator_by_typedefs & | +| standalone_iterators.cpp:7:7:7:7 | operator= | 0 | int_iterator_by_typedefs && | +| standalone_iterators.cpp:16:30:16:39 | operator++ | 0 | int | +| standalone_iterators.cpp:20:7:20:7 | operator= | 0 | const int_iterator_by_trait & | +| standalone_iterators.cpp:20:7:20:7 | operator= | 0 | int_iterator_by_trait && | +| standalone_iterators.cpp:23:27:23:36 | operator++ | 0 | int | +| standalone_iterators.cpp:36:7:36:7 | operator= | 0 | const non_iterator & | +| standalone_iterators.cpp:36:7:36:7 | operator= | 0 | non_iterator && | +| standalone_iterators.cpp:39:18:39:27 | operator++ | 0 | int | +| standalone_iterators.cpp:43:6:43:18 | test_typedefs | 0 | int_iterator_by_typedefs | +| standalone_iterators.cpp:49:6:49:15 | test_trait | 0 | int_iterator_by_trait | +| standalone_iterators.cpp:55:6:55:22 | test_non_iterator | 0 | non_iterator | +| standalone_iterators.cpp:63:7:63:7 | operator= | 0 | const insert_iterator_by_trait & | +| standalone_iterators.cpp:63:7:63:7 | operator= | 0 | insert_iterator_by_trait && | +| standalone_iterators.cpp:66:30:66:39 | operator++ | 0 | int | +| standalone_iterators.cpp:68:30:68:39 | operator-- | 0 | int | +| standalone_iterators.cpp:70:31:70:39 | operator= | 0 | int | +| standalone_iterators.cpp:82:7:82:7 | container | 0 | const container & | +| standalone_iterators.cpp:82:7:82:7 | container | 0 | container && | +| standalone_iterators.cpp:82:7:82:7 | operator= | 0 | const container & | +| standalone_iterators.cpp:82:7:82:7 | operator= | 0 | container && | +| standalone_iterators.cpp:88:6:88:9 | sink | 0 | container | +| standalone_iterators.cpp:102:6:102:9 | sink | 0 | insert_iterator_by_trait | +| standalone_iterators.cpp:103:27:103:36 | operator+= | 0 | insert_iterator_by_trait & | +| standalone_iterators.cpp:103:27:103:36 | operator+= | 1 | int | | stl.h:29:34:29:40 | forward | 0 | remove_reference_t & | | stl.h:29:34:29:40 | forward | 0 | remove_reference_t & | | stl.h:29:34:29:40 | forward | 0 | remove_reference_t & | | stl.h:29:34:29:40 | forward | 0 | remove_reference_t & | +| stl.h:29:34:29:40 | forward | 0 | remove_reference_t> & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | @@ -391,6 +835,8 @@ getParameterTypeName | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | +| stl.h:49:3:49:10 | iterator | 0 | const iterator, ptrdiff_t, pair *, pair &> & | +| stl.h:49:3:49:10 | iterator | 0 | const iterator, ptrdiff_t, pair *, pair &> & | | stl.h:52:12:52:21 | operator++ | 0 | int | | stl.h:52:12:52:21 | operator++ | 0 | int | | stl.h:52:12:52:21 | operator++ | 0 | int | @@ -403,59 +849,111 @@ getParameterTypeName | stl.h:56:8:56:17 | operator!= | 0 | iterator | | stl.h:56:8:56:17 | operator!= | 0 | iterator | | stl.h:56:8:56:17 | operator!= | 0 | iterator | +| stl.h:56:8:56:17 | operator!= | 0 | iterator, ptrdiff_t, pair *, pair &> | | stl.h:59:12:59:20 | operator+ | 0 | int | | stl.h:60:12:60:20 | operator- | 0 | int | | stl.h:61:13:61:22 | operator+= | 0 | int | | stl.h:61:13:61:22 | operator+= | 0 | int | | stl.h:62:13:62:22 | operator-= | 0 | int | | stl.h:64:18:64:27 | operator[] | 0 | int | +| stl.h:67:9:67:9 | operator= | 0 | const input_iterator_tag & | +| stl.h:67:9:67:9 | operator= | 0 | input_iterator_tag && | +| stl.h:68:9:68:9 | operator= | 0 | const forward_iterator_tag & | +| stl.h:68:9:68:9 | operator= | 0 | forward_iterator_tag && | +| stl.h:69:9:69:9 | operator= | 0 | bidirectional_iterator_tag && | +| stl.h:69:9:69:9 | operator= | 0 | const bidirectional_iterator_tag & | +| stl.h:70:9:70:9 | operator= | 0 | const random_access_iterator_tag & | +| stl.h:70:9:70:9 | operator= | 0 | random_access_iterator_tag && | +| stl.h:72:9:72:9 | operator= | 0 | const output_iterator_tag & | +| stl.h:72:9:72:9 | operator= | 0 | output_iterator_tag && | | stl.h:86:22:86:41 | back_insert_iterator | 0 | class:0 & | | stl.h:86:22:86:41 | back_insert_iterator | 0 | class:0 & | +| stl.h:86:22:86:41 | back_insert_iterator | 0 | vector, allocator>, allocator, allocator>>> & | +| stl.h:86:22:86:41 | back_insert_iterator | 0 | vector> & | | stl.h:88:25:88:33 | operator= | 0 | value_type && | | stl.h:88:25:88:33 | operator= | 0 | value_type && | | stl.h:91:24:91:33 | operator++ | 0 | int | | stl.h:91:24:91:33 | operator++ | 0 | int | | stl.h:95:44:95:44 | back_inserter | 0 | func:0 & | | stl.h:95:44:95:44 | back_inserter | 0 | func:0 & | +| stl.h:95:44:95:44 | back_inserter | 0 | vector, allocator>, allocator, allocator>>> & | +| stl.h:95:44:95:44 | back_inserter | 0 | vector> & | +| stl.h:147:12:147:23 | basic_string | 0 | const allocator & | +| stl.h:148:3:148:14 | basic_string | 0 | const char * | | stl.h:148:3:148:14 | basic_string | 0 | const class:2 & | +| stl.h:148:3:148:14 | basic_string | 1 | const allocator & | | stl.h:149:33:149:44 | basic_string | 0 | const class:0 * | +| stl.h:149:33:149:44 | basic_string | 0 | func:0 | | stl.h:149:33:149:44 | basic_string | 1 | const class:2 & | +| stl.h:149:33:149:44 | basic_string | 1 | func:0 | +| stl.h:149:33:149:44 | basic_string | 2 | const allocator & | | stl.h:151:16:151:20 | c_str | 0 | func:0 | | stl.h:151:16:151:20 | c_str | 1 | func:0 | | stl.h:151:16:151:20 | c_str | 2 | const class:2 & | +| stl.h:165:8:165:16 | push_back | 0 | char | | stl.h:173:13:173:22 | operator[] | 0 | size_type | | stl.h:175:13:175:14 | at | 0 | size_type | +| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & | +| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & | | stl.h:176:35:176:44 | operator+= | 0 | size_type | | stl.h:176:35:176:44 | operator+= | 0 | size_type | +| stl.h:177:17:177:26 | operator+= | 0 | const char * | | stl.h:177:17:177:26 | operator+= | 0 | const func:0 & | +| stl.h:178:17:178:22 | append | 0 | const basic_string, allocator> & | | stl.h:178:17:178:22 | append | 0 | const class:0 * | | stl.h:179:17:179:22 | append | 0 | const basic_string & | +| stl.h:179:17:179:22 | append | 0 | const char * | | stl.h:180:17:180:22 | append | 0 | const class:0 * | +| stl.h:180:17:180:22 | append | 0 | size_type | +| stl.h:180:17:180:22 | append | 1 | char | +| stl.h:181:47:181:52 | append | 0 | func:0 | | stl.h:181:47:181:52 | append | 0 | size_type | | stl.h:181:47:181:52 | append | 1 | class:0 | +| stl.h:181:47:181:52 | append | 1 | func:0 | +| stl.h:182:17:182:22 | assign | 0 | const basic_string, allocator> & | | stl.h:182:17:182:22 | assign | 0 | func:0 | | stl.h:182:17:182:22 | assign | 1 | func:0 | | stl.h:183:17:183:22 | assign | 0 | const basic_string & | +| stl.h:183:17:183:22 | assign | 0 | size_type | +| stl.h:183:17:183:22 | assign | 1 | char | +| stl.h:184:47:184:52 | assign | 0 | func:0 | | stl.h:184:47:184:52 | assign | 0 | size_type | | stl.h:184:47:184:52 | assign | 1 | class:0 | +| stl.h:184:47:184:52 | assign | 1 | func:0 | | stl.h:185:17:185:22 | insert | 0 | func:0 | +| stl.h:185:17:185:22 | insert | 0 | size_type | +| stl.h:185:17:185:22 | insert | 1 | const basic_string, allocator> & | | stl.h:185:17:185:22 | insert | 1 | func:0 | | stl.h:186:17:186:22 | insert | 0 | size_type | | stl.h:186:17:186:22 | insert | 1 | const basic_string & | +| stl.h:186:17:186:22 | insert | 1 | size_type | +| stl.h:186:17:186:22 | insert | 2 | char | | stl.h:187:17:187:22 | insert | 0 | size_type | +| stl.h:187:17:187:22 | insert | 1 | const char * | | stl.h:187:17:187:22 | insert | 1 | size_type | | stl.h:187:17:187:22 | insert | 2 | class:0 | +| stl.h:188:12:188:17 | insert | 0 | const_iterator | | stl.h:188:12:188:17 | insert | 0 | size_type | | stl.h:188:12:188:17 | insert | 1 | const class:0 * | +| stl.h:188:12:188:17 | insert | 1 | size_type | +| stl.h:188:12:188:17 | insert | 2 | char | | stl.h:189:42:189:47 | insert | 0 | const_iterator | +| stl.h:189:42:189:47 | insert | 1 | func:0 | | stl.h:189:42:189:47 | insert | 1 | size_type | | stl.h:189:42:189:47 | insert | 2 | class:0 | +| stl.h:189:42:189:47 | insert | 2 | func:0 | | stl.h:190:17:190:23 | replace | 0 | const_iterator | +| stl.h:190:17:190:23 | replace | 0 | size_type | | stl.h:190:17:190:23 | replace | 1 | func:0 | +| stl.h:190:17:190:23 | replace | 1 | size_type | +| stl.h:190:17:190:23 | replace | 2 | const basic_string, allocator> & | | stl.h:190:17:190:23 | replace | 2 | func:0 | | stl.h:191:17:191:23 | replace | 0 | size_type | | stl.h:191:17:191:23 | replace | 1 | size_type | | stl.h:191:17:191:23 | replace | 2 | const basic_string & | +| stl.h:191:17:191:23 | replace | 2 | size_type | +| stl.h:191:17:191:23 | replace | 3 | char | +| stl.h:192:13:192:16 | copy | 0 | char * | | stl.h:192:13:192:16 | copy | 0 | size_type | | stl.h:192:13:192:16 | copy | 1 | size_type | | stl.h:192:13:192:16 | copy | 2 | size_type | @@ -463,11 +961,18 @@ getParameterTypeName | stl.h:193:8:193:12 | clear | 0 | class:0 * | | stl.h:193:8:193:12 | clear | 1 | size_type | | stl.h:193:8:193:12 | clear | 2 | size_type | +| stl.h:194:16:194:21 | substr | 0 | size_type | +| stl.h:194:16:194:21 | substr | 1 | size_type | +| stl.h:195:8:195:11 | swap | 0 | basic_string, allocator> & | | stl.h:195:8:195:11 | swap | 0 | size_type | | stl.h:195:8:195:11 | swap | 1 | size_type | | stl.h:198:94:198:102 | operator+ | 0 | const basic_string & | +| stl.h:198:94:198:102 | operator+ | 0 | const basic_string, allocator> & | | stl.h:198:94:198:102 | operator+ | 1 | const basic_string & | +| stl.h:198:94:198:102 | operator+ | 1 | const basic_string, allocator> & | | stl.h:199:94:199:102 | operator+ | 0 | const basic_string & | +| stl.h:199:94:199:102 | operator+ | 0 | const basic_string, allocator> & | +| stl.h:199:94:199:102 | operator+ | 1 | const char * | | stl.h:199:94:199:102 | operator+ | 1 | const func:0 * | | stl.h:214:33:214:42 | operator>> | 0 | int & | | stl.h:217:33:217:35 | get | 0 | char_type & | @@ -484,26 +989,49 @@ getParameterTypeName | stl.h:226:32:226:38 | getline | 1 | streamsize | | stl.h:226:32:226:38 | getline | 2 | char_type | | stl.h:229:68:229:77 | operator>> | 0 | basic_istream & | +| stl.h:229:68:229:77 | operator>> | 0 | basic_istream> & | +| stl.h:229:68:229:77 | operator>> | 1 | char * | | stl.h:229:68:229:77 | operator>> | 1 | func:0 * | | stl.h:230:85:230:94 | operator>> | 0 | basic_istream & | +| stl.h:230:85:230:94 | operator>> | 0 | basic_istream> & | | stl.h:230:85:230:94 | operator>> | 1 | basic_string & | +| stl.h:230:85:230:94 | operator>> | 1 | basic_string, allocator> & | | stl.h:232:84:232:90 | getline | 0 | basic_istream & | +| stl.h:232:84:232:90 | getline | 0 | basic_istream> & | | stl.h:232:84:232:90 | getline | 1 | basic_string & | +| stl.h:232:84:232:90 | getline | 1 | basic_string, allocator> & | +| stl.h:232:84:232:90 | getline | 2 | char | | stl.h:232:84:232:90 | getline | 2 | func:0 | | stl.h:233:84:233:90 | getline | 0 | basic_istream & | +| stl.h:233:84:233:90 | getline | 0 | basic_istream> & | | stl.h:233:84:233:90 | getline | 1 | basic_string & | +| stl.h:233:84:233:90 | getline | 1 | basic_string, allocator> & | | stl.h:240:33:240:42 | operator<< | 0 | int | | stl.h:242:33:242:35 | put | 0 | char_type | | stl.h:243:33:243:37 | write | 0 | const char_type * | | stl.h:243:33:243:37 | write | 1 | streamsize | | stl.h:247:67:247:76 | operator<< | 0 | basic_ostream & | +| stl.h:247:67:247:76 | operator<< | 0 | basic_ostream> & | +| stl.h:247:67:247:76 | operator<< | 1 | const char * | | stl.h:247:67:247:76 | operator<< | 1 | const func:0 * | | stl.h:248:85:248:94 | operator<< | 0 | basic_ostream & | +| stl.h:248:85:248:94 | operator<< | 0 | basic_ostream> & | | stl.h:248:85:248:94 | operator<< | 1 | const basic_string & | +| stl.h:248:85:248:94 | operator<< | 1 | const basic_string, allocator> & | | stl.h:259:12:259:29 | basic_stringstream | 0 | const basic_string & | +| stl.h:259:12:259:29 | basic_stringstream | 0 | const basic_string, allocator> & | | stl.h:263:23:263:31 | operator= | 0 | basic_stringstream && | +| stl.h:263:23:263:31 | operator= | 0 | basic_stringstream, allocator> && | | stl.h:265:8:265:11 | swap | 0 | basic_stringstream & | +| stl.h:265:8:265:11 | swap | 0 | basic_stringstream, allocator> & | | stl.h:268:8:268:10 | str | 0 | const basic_string & | +| stl.h:268:8:268:10 | str | 0 | const basic_string, allocator> & | +| stl.h:293:12:293:17 | vector | 0 | const allocator & | +| stl.h:293:12:293:17 | vector | 0 | const allocator & | +| stl.h:293:12:293:17 | vector | 0 | const allocator & | +| stl.h:293:12:293:17 | vector | 0 | const allocator & | +| stl.h:293:12:293:17 | vector | 0 | const allocator & | +| stl.h:293:12:293:17 | vector | 0 | const allocator, allocator>> & | | stl.h:293:12:293:17 | vector | 0 | const class:1 & | | stl.h:293:12:293:17 | vector | 0 | const class:1 & | | stl.h:293:12:293:17 | vector | 0 | const class:1 & | @@ -513,6 +1041,9 @@ getParameterTypeName | stl.h:294:12:294:17 | vector | 0 | size_type | | stl.h:294:12:294:17 | vector | 0 | size_type | | stl.h:294:12:294:17 | vector | 0 | size_type | +| stl.h:294:12:294:17 | vector | 1 | const allocator & | +| stl.h:294:12:294:17 | vector | 1 | const allocator & | +| stl.h:294:12:294:17 | vector | 1 | const allocator>> & | | stl.h:294:12:294:17 | vector | 1 | const class:1 & | | stl.h:294:12:294:17 | vector | 1 | const class:1 & | | stl.h:294:12:294:17 | vector | 1 | const class:1 & | @@ -520,13 +1051,20 @@ getParameterTypeName | stl.h:295:3:295:8 | vector | 0 | size_type | | stl.h:295:3:295:8 | vector | 1 | const class:0 & | | stl.h:295:3:295:8 | vector | 1 | const class:0 & | +| stl.h:295:3:295:8 | vector | 1 | const int & | +| stl.h:295:3:295:8 | vector | 1 | const short & | +| stl.h:295:3:295:8 | vector | 2 | const allocator & | +| stl.h:295:3:295:8 | vector | 2 | const allocator & | | stl.h:295:3:295:8 | vector | 2 | const class:1 & | | stl.h:295:3:295:8 | vector | 2 | const class:1 & | | stl.h:296:101:296:106 | vector | 0 | func:0 | | stl.h:296:101:296:106 | vector | 1 | func:0 | +| stl.h:296:101:296:106 | vector | 2 | const allocator & | | stl.h:296:101:296:106 | vector | 2 | const class:1 & | | stl.h:301:11:301:19 | operator= | 0 | const vector & | +| stl.h:301:11:301:19 | operator= | 0 | const vector> & | | stl.h:302:11:302:19 | operator= | 0 | vector && | +| stl.h:302:11:302:19 | operator= | 0 | vector> && | | stl.h:303:106:303:111 | assign | 0 | func:0 | | stl.h:303:106:303:111 | assign | 1 | func:0 | | stl.h:306:8:306:13 | assign | 0 | size_type | @@ -535,6 +1073,9 @@ getParameterTypeName | stl.h:306:8:306:13 | assign | 1 | const class:0 & | | stl.h:306:8:306:13 | assign | 1 | const class:0 & | | stl.h:306:8:306:13 | assign | 1 | const class:0 & | +| stl.h:306:8:306:13 | assign | 1 | const float & | +| stl.h:306:8:306:13 | assign | 1 | const int & | +| stl.h:306:8:306:13 | assign | 1 | const int *const & | | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:315:13:315:22 | operator[] | 0 | size_type | @@ -542,11 +1083,15 @@ getParameterTypeName | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:318:13:318:14 | at | 0 | size_type | +| stl.h:327:8:327:16 | push_back | 0 | const MyPair & | +| stl.h:327:8:327:16 | push_back | 0 | const MyVectorContainer & | | stl.h:327:8:327:16 | push_back | 0 | const class:0 & | | stl.h:327:8:327:16 | push_back | 0 | const class:0 & | | stl.h:328:8:328:16 | push_back | 0 | class:0 && | +| stl.h:328:8:328:16 | push_back | 0 | int && | | stl.h:331:12:331:17 | insert | 0 | const_iterator | | stl.h:331:12:331:17 | insert | 1 | class:0 && | +| stl.h:331:12:331:17 | insert | 1 | int && | | stl.h:333:42:333:47 | insert | 0 | const_iterator | | stl.h:333:42:333:47 | insert | 0 | const_iterator | | stl.h:333:42:333:47 | insert | 1 | func:0 | @@ -557,21 +1102,38 @@ getParameterTypeName | stl.h:335:37:335:43 | emplace | 1 | func:0 && | | stl.h:336:33:336:44 | emplace_back | 0 | func:0 && | | stl.h:338:8:338:11 | swap | 0 | vector & | +| stl.h:338:8:338:11 | swap | 0 | vector> & | | stl.h:351:12:351:21 | shared_ptr | 0 | class:0 * | +| stl.h:351:12:351:21 | shared_ptr | 0 | int * | | stl.h:352:3:352:12 | shared_ptr | 0 | const shared_ptr & | | stl.h:352:3:352:12 | shared_ptr | 0 | const shared_ptr & | +| stl.h:369:12:369:21 | unique_ptr | 0 | A * | | stl.h:369:12:369:21 | unique_ptr | 0 | class:0 * | | stl.h:380:52:380:62 | make_unique | 0 | func:1 && | | stl.h:380:52:380:62 | make_unique | 0 | func:1 && | | stl.h:380:52:380:62 | make_unique | 0 | func:1 && | +| stl.h:380:52:380:62 | make_unique | 0 | int && | +| stl.h:380:52:380:62 | make_unique | 0 | int && | | stl.h:382:52:382:62 | make_shared | 0 | func:1 && | | stl.h:382:52:382:62 | make_shared | 0 | func:1 && | | stl.h:382:52:382:62 | make_shared | 0 | func:1 && | +| stl.h:382:52:382:62 | make_shared | 0 | int && | +| stl.h:382:52:382:62 | make_shared | 0 | int && | +| stl.h:396:3:396:3 | pair | 0 | char *const & | +| stl.h:396:3:396:3 | pair | 0 | char *const & | +| stl.h:396:3:396:3 | pair | 0 | const char *const & | +| stl.h:396:3:396:3 | pair | 0 | const char *const & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | +| stl.h:396:3:396:3 | pair | 0 | const pair & | +| stl.h:396:3:396:3 | pair | 1 | char *const & | +| stl.h:396:3:396:3 | pair | 1 | char *const & | +| stl.h:396:3:396:3 | pair | 1 | const char *const & | +| stl.h:396:3:396:3 | pair | 1 | const char *const & | +| stl.h:396:3:396:3 | pair | 1 | const char *const & | | stl.h:396:3:396:3 | pair | 1 | const class:1 & | | stl.h:396:3:396:3 | pair | 1 | const class:1 & | | stl.h:396:3:396:3 | pair | 1 | const class:1 & | @@ -590,12 +1152,24 @@ getParameterTypeName | stl.h:397:30:397:33 | pair | 0 | const pair & | | stl.h:397:30:397:33 | pair | 0 | const pair & | | stl.h:399:8:399:11 | swap | 0 | pair & | +| stl.h:402:72:402:72 | make_pair | 0 | char *&& | +| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[2] | +| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[2] | +| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[4] | +| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[4] | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | +| stl.h:402:72:402:72 | make_pair | 0 | pair && | +| stl.h:402:72:402:72 | make_pair | 1 | char *&& | +| stl.h:402:72:402:72 | make_pair | 1 | char *&& | +| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[2] | +| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[4] | +| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[4] | +| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[4] | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | @@ -603,7 +1177,9 @@ getParameterTypeName | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:422:3:422:5 | map | 0 | const map & | +| stl.h:422:3:422:5 | map | 0 | const map, allocator>> & | | stl.h:426:8:426:16 | operator= | 0 | const map & | +| stl.h:426:8:426:16 | operator= | 0 | const map, allocator>> & | | stl.h:435:6:435:15 | operator[] | 0 | key_type && | | stl.h:435:6:435:15 | operator[] | 0 | key_type && | | stl.h:436:6:436:7 | at | 0 | const key_type & | @@ -633,14 +1209,19 @@ getParameterTypeName | stl.h:454:30:454:45 | insert_or_assign | 2 | func:0 && | | stl.h:456:12:456:16 | erase | 0 | iterator | | stl.h:459:8:459:11 | swap | 0 | map & | +| stl.h:459:8:459:11 | swap | 0 | map, allocator>> & | | stl.h:462:27:462:31 | merge | 0 | map & | +| stl.h:462:27:462:31 | merge | 0 | map>> & | | stl.h:465:12:465:15 | find | 0 | const key_type & | | stl.h:468:12:468:22 | lower_bound | 0 | const key_type & | | stl.h:470:12:470:22 | upper_bound | 0 | const key_type & | | stl.h:473:28:473:38 | equal_range | 0 | const key_type & | | stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map & | | stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map & | +| stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map, equal_to, allocator>> & | +| stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map, hash, equal_to, allocator>>> & | | stl.h:494:18:494:26 | operator= | 0 | const unordered_map & | +| stl.h:494:18:494:26 | operator= | 0 | const unordered_map, equal_to, allocator>> & | | stl.h:503:16:503:25 | operator[] | 0 | key_type && | | stl.h:503:16:503:25 | operator[] | 0 | key_type && | | stl.h:504:16:504:17 | at | 0 | const key_type & | @@ -679,13 +1260,17 @@ getParameterTypeName | stl.h:522:30:522:45 | insert_or_assign | 2 | func:0 && | | stl.h:524:12:524:16 | erase | 0 | iterator | | stl.h:527:8:527:11 | swap | 0 | unordered_map & | +| stl.h:527:8:527:11 | swap | 0 | unordered_map, equal_to, allocator>> & | | stl.h:530:37:530:41 | merge | 0 | unordered_map & | +| stl.h:530:37:530:41 | merge | 0 | unordered_map>> & | | stl.h:533:12:533:15 | find | 0 | const key_type & | | stl.h:536:28:536:38 | equal_range | 0 | const key_type & | | stl.h:555:3:555:5 | set | 0 | const set & | +| stl.h:555:3:555:5 | set | 0 | const set, allocator> & | | stl.h:557:33:557:35 | set | 0 | func:0 | | stl.h:557:33:557:35 | set | 1 | func:0 | | stl.h:560:8:560:16 | operator= | 0 | const set & | +| stl.h:560:8:560:16 | operator= | 0 | const set, allocator> & | | stl.h:568:48:568:54 | emplace | 0 | func:0 && | | stl.h:568:48:568:54 | emplace | 0 | func:0 && | | stl.h:569:36:569:47 | emplace_hint | 0 | const_iterator | @@ -699,16 +1284,20 @@ getParameterTypeName | stl.h:574:38:574:43 | insert | 1 | func:0 | | stl.h:576:12:576:16 | erase | 0 | iterator | | stl.h:579:8:579:11 | swap | 0 | set & | +| stl.h:579:8:579:11 | swap | 0 | set, allocator> & | | stl.h:582:27:582:31 | merge | 0 | set & | +| stl.h:582:27:582:31 | merge | 0 | set> & | | stl.h:585:12:585:15 | find | 0 | const key_type & | | stl.h:588:12:588:22 | lower_bound | 0 | const key_type & | | stl.h:590:12:590:22 | upper_bound | 0 | const key_type & | | stl.h:592:28:592:38 | equal_range | 0 | const key_type & | | stl.h:609:3:609:15 | unordered_set | 0 | const unordered_set & | +| stl.h:609:3:609:15 | unordered_set | 0 | const unordered_set, equal_to, allocator> & | | stl.h:611:33:611:45 | unordered_set | 0 | func:0 | | stl.h:611:33:611:45 | unordered_set | 1 | func:0 | | stl.h:611:33:611:45 | unordered_set | 2 | size_type | | stl.h:614:18:614:26 | operator= | 0 | const unordered_set & | +| stl.h:614:18:614:26 | operator= | 0 | const unordered_set, equal_to, allocator> & | | stl.h:622:48:622:54 | emplace | 0 | func:0 && | | stl.h:622:48:622:54 | emplace | 0 | func:0 && | | stl.h:623:36:623:47 | emplace_hint | 0 | const_iterator | @@ -722,23 +1311,282 @@ getParameterTypeName | stl.h:628:38:628:43 | insert | 1 | func:0 | | stl.h:630:12:630:16 | erase | 0 | iterator | | stl.h:633:8:633:11 | swap | 0 | unordered_set & | +| stl.h:633:8:633:11 | swap | 0 | unordered_set, equal_to, allocator> & | | stl.h:636:37:636:41 | merge | 0 | unordered_set & | +| stl.h:636:37:636:41 | merge | 0 | unordered_set> & | | stl.h:639:12:639:15 | find | 0 | const key_type & | | stl.h:641:28:641:38 | equal_range | 0 | const key_type & | | stl.h:671:21:671:39 | basic_format_string | 0 | const func:0 & | | stl.h:671:21:671:39 | basic_format_string | 0 | const func:0 & | | stl.h:678:33:678:38 | format | 0 | format_string | | stl.h:678:33:678:38 | format | 0 | format_string | +| stl.h:678:33:678:38 | format | 1 | char *&& | | stl.h:678:33:678:38 | format | 1 | func:0 && | | stl.h:678:33:678:38 | format | 1 | func:0 && | | stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 0 | format_string | | stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 1 | func:0 && | +| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 1 | int & | +| string.cpp:17:6:17:9 | sink | 0 | const char * | +| string.cpp:18:6:18:9 | sink | 0 | const string & | +| string.cpp:19:6:19:9 | sink | 0 | const char * | +| string.cpp:19:6:19:9 | sink | 1 | const char * | +| string.cpp:20:6:20:9 | sink | 0 | char | +| string.cpp:21:6:21:9 | sink | 0 | iterator | +| stringstream.cpp:13:6:13:9 | sink | 0 | int | +| stringstream.cpp:15:6:15:9 | sink | 0 | const string & | | stringstream.cpp:18:6:18:9 | sink | 0 | const basic_ostream> & | | stringstream.cpp:21:6:21:9 | sink | 0 | const basic_istream> & | | stringstream.cpp:24:6:24:9 | sink | 0 | const basic_iostream> & | +| stringstream.cpp:26:6:26:29 | test_stringstream_string | 0 | int | +| stringstream.cpp:70:6:70:26 | test_stringstream_int | 0 | int | +| structlikeclass.cpp:5:7:5:7 | StructLikeClass | 0 | StructLikeClass && | +| structlikeclass.cpp:5:7:5:7 | StructLikeClass | 0 | const StructLikeClass & | +| structlikeclass.cpp:5:7:5:7 | operator= | 0 | StructLikeClass && | +| structlikeclass.cpp:5:7:5:7 | operator= | 0 | const StructLikeClass & | +| structlikeclass.cpp:8:2:8:16 | StructLikeClass | 0 | int | +| swap1.cpp:14:9:14:9 | move | 0 | Class & | | swap1.cpp:14:9:14:9 | move | 0 | func:0 & | +| swap1.cpp:24:9:24:13 | Class | 0 | Class && | +| swap1.cpp:25:9:25:13 | Class | 0 | const Class & | +| swap1.cpp:27:16:27:24 | operator= | 0 | const Class & | +| swap1.cpp:34:16:34:24 | operator= | 0 | Class && | +| swap1.cpp:40:16:40:26 | copy_assign | 0 | const Class & | +| swap1.cpp:47:16:47:26 | move_assign | 0 | Class && | +| swap1.cpp:53:14:53:17 | swap | 0 | Class & | +| swap1.cpp:61:10:61:13 | swap | 0 | Class & | +| swap1.cpp:61:10:61:13 | swap | 1 | Class & | +| swap2.cpp:14:9:14:9 | move | 0 | Class & | | swap2.cpp:14:9:14:9 | move | 0 | func:0 & | +| swap2.cpp:24:9:24:13 | Class | 0 | Class && | +| swap2.cpp:25:9:25:13 | Class | 0 | const Class & | +| swap2.cpp:27:16:27:24 | operator= | 0 | const Class & | +| swap2.cpp:34:16:34:24 | operator= | 0 | Class && | +| swap2.cpp:40:16:40:26 | copy_assign | 0 | const Class & | +| swap2.cpp:47:16:47:26 | move_assign | 0 | Class && | +| swap2.cpp:53:14:53:17 | swap | 0 | Class & | +| swap2.cpp:61:10:61:13 | swap | 0 | Class & | +| swap2.cpp:61:10:61:13 | swap | 1 | Class & | | swap.h:4:20:4:23 | swap | 0 | func:0 & | +| swap.h:4:20:4:23 | swap | 0 | int & | | swap.h:4:20:4:23 | swap | 1 | func:0 & | +| swap.h:4:20:4:23 | swap | 1 | int & | +| taint.cpp:4:6:4:21 | arithAssignments | 0 | int | +| taint.cpp:4:6:4:21 | arithAssignments | 1 | int | +| taint.cpp:22:5:22:13 | increment | 0 | int | +| taint.cpp:23:5:23:8 | zero | 0 | int | +| taint.cpp:69:7:69:7 | MyClass | 0 | MyClass && | +| taint.cpp:69:7:69:7 | MyClass | 0 | const MyClass & | +| taint.cpp:69:7:69:7 | operator= | 0 | MyClass && | +| taint.cpp:69:7:69:7 | operator= | 0 | const MyClass & | +| taint.cpp:100:6:100:15 | array_test | 0 | int | +| taint.cpp:142:5:142:10 | select | 0 | int | +| taint.cpp:142:5:142:10 | select | 1 | int | +| taint.cpp:142:5:142:10 | select | 2 | int | +| taint.cpp:150:6:150:12 | fn_test | 0 | int | +| taint.cpp:156:7:156:12 | strcpy | 0 | char * | +| taint.cpp:156:7:156:12 | strcpy | 1 | const char * | +| taint.cpp:157:7:157:12 | strcat | 0 | char * | +| taint.cpp:157:7:157:12 | strcat | 1 | const char * | +| taint.cpp:180:7:180:12 | callee | 0 | int * | +| taint.cpp:190:7:190:12 | memcpy | 0 | void * | +| taint.cpp:190:7:190:12 | memcpy | 1 | void * | +| taint.cpp:190:7:190:12 | memcpy | 2 | int | +| taint.cpp:192:6:192:16 | test_memcpy | 0 | int * | +| taint.cpp:228:11:228:11 | (unnamed constructor) | 0 | const lambda [] type at line 233, col. 11 & | +| taint.cpp:228:11:228:11 | (unnamed constructor) | 0 | lambda [] type at line 233, col. 11 && | +| taint.cpp:228:11:228:11 | operator= | 0 | const lambda [] type at line 233, col. 11 & | +| taint.cpp:235:11:235:11 | (unnamed constructor) | 0 | const lambda [] type at line 240, col. 11 & | +| taint.cpp:235:11:235:11 | (unnamed constructor) | 0 | lambda [] type at line 240, col. 11 && | +| taint.cpp:235:11:235:11 | operator= | 0 | const lambda [] type at line 240, col. 11 & | +| taint.cpp:243:11:243:11 | (unnamed constructor) | 0 | const lambda [] type at line 248, col. 11 & | +| taint.cpp:243:11:243:11 | (unnamed constructor) | 0 | lambda [] type at line 248, col. 11 && | +| taint.cpp:243:11:243:11 | operator= | 0 | const lambda [] type at line 248, col. 11 & | +| taint.cpp:249:11:249:11 | (unnamed constructor) | 0 | const lambda [] type at line 254, col. 11 & | +| taint.cpp:249:11:249:11 | (unnamed constructor) | 0 | lambda [] type at line 254, col. 11 && | +| taint.cpp:249:11:249:11 | operator= | 0 | const lambda [] type at line 254, col. 11 & | +| taint.cpp:249:13:249:13 | _FUN | 0 | int | +| taint.cpp:249:13:249:13 | _FUN | 1 | int | +| taint.cpp:249:13:249:13 | operator() | 0 | int | +| taint.cpp:249:13:249:13 | operator() | 1 | int | +| taint.cpp:255:11:255:11 | (unnamed constructor) | 0 | const lambda [] type at line 260, col. 11 & | +| taint.cpp:255:11:255:11 | (unnamed constructor) | 0 | lambda [] type at line 260, col. 11 && | +| taint.cpp:255:11:255:11 | operator= | 0 | const lambda [] type at line 260, col. 11 & | +| taint.cpp:255:13:255:13 | _FUN | 0 | int & | +| taint.cpp:255:13:255:13 | _FUN | 1 | int & | +| taint.cpp:255:13:255:13 | _FUN | 2 | int & | +| taint.cpp:255:13:255:13 | operator() | 0 | int & | +| taint.cpp:255:13:255:13 | operator() | 1 | int & | +| taint.cpp:255:13:255:13 | operator() | 2 | int & | +| taint.cpp:266:5:266:6 | id | 0 | int | +| taint.cpp:297:6:297:14 | myAssign1 | 0 | int & | +| taint.cpp:297:6:297:14 | myAssign1 | 1 | int & | +| taint.cpp:302:6:302:14 | myAssign2 | 0 | int & | +| taint.cpp:302:6:302:14 | myAssign2 | 1 | int | +| taint.cpp:307:6:307:14 | myAssign3 | 0 | int * | +| taint.cpp:307:6:307:14 | myAssign3 | 1 | int | +| taint.cpp:312:6:312:14 | myAssign4 | 0 | int * | +| taint.cpp:312:6:312:14 | myAssign4 | 1 | int | +| taint.cpp:320:6:320:16 | myNotAssign | 0 | int & | +| taint.cpp:320:6:320:16 | myNotAssign | 1 | int & | +| taint.cpp:361:7:361:12 | strdup | 0 | const char * | +| taint.cpp:362:7:362:13 | strndup | 0 | const char * | +| taint.cpp:362:7:362:13 | strndup | 1 | size_t | +| taint.cpp:363:10:363:15 | wcsdup | 0 | const wchar_t * | +| taint.cpp:364:7:364:13 | strdupa | 0 | const char * | +| taint.cpp:365:7:365:14 | strndupa | 0 | const char * | +| taint.cpp:365:7:365:14 | strndupa | 1 | size_t | +| taint.cpp:367:6:367:16 | test_strdup | 0 | char * | +| taint.cpp:379:6:379:17 | test_strndup | 0 | int | +| taint.cpp:387:6:387:16 | test_wcsdup | 0 | wchar_t * | +| taint.cpp:397:6:397:17 | test_strdupa | 0 | char * | +| taint.cpp:409:6:409:18 | test_strndupa | 0 | int | +| taint.cpp:419:7:419:7 | MyClass2 | 0 | MyClass2 && | +| taint.cpp:419:7:419:7 | MyClass2 | 0 | const MyClass2 & | +| taint.cpp:419:7:419:7 | operator= | 0 | MyClass2 && | +| taint.cpp:419:7:419:7 | operator= | 0 | const MyClass2 & | +| taint.cpp:421:2:421:9 | MyClass2 | 0 | int | +| taint.cpp:422:7:422:15 | setMember | 0 | int | +| taint.cpp:428:7:428:7 | MyClass3 | 0 | MyClass3 && | +| taint.cpp:428:7:428:7 | MyClass3 | 0 | const MyClass3 & | +| taint.cpp:428:7:428:7 | operator= | 0 | MyClass3 && | +| taint.cpp:428:7:428:7 | operator= | 0 | const MyClass3 & | +| taint.cpp:430:2:430:9 | MyClass3 | 0 | const char * | +| taint.cpp:431:7:431:15 | setString | 0 | const char * | +| taint.cpp:474:6:474:9 | swop | 0 | int & | +| taint.cpp:474:6:474:9 | swop | 1 | int & | +| taint.cpp:500:5:500:12 | getdelim | 0 | char ** | +| taint.cpp:500:5:500:12 | getdelim | 1 | size_t * | +| taint.cpp:500:5:500:12 | getdelim | 2 | int | +| taint.cpp:500:5:500:12 | getdelim | 3 | FILE * | +| taint.cpp:502:6:502:18 | test_getdelim | 0 | FILE * | +| taint.cpp:512:7:512:12 | strtok | 0 | char * | +| taint.cpp:512:7:512:12 | strtok | 1 | const char * | +| taint.cpp:514:6:514:16 | test_strtok | 0 | char * | +| taint.cpp:523:7:523:13 | _strset | 0 | char * | +| taint.cpp:523:7:523:13 | _strset | 1 | int | +| taint.cpp:525:6:525:18 | test_strset_1 | 0 | char * | +| taint.cpp:525:6:525:18 | test_strset_1 | 1 | char | +| taint.cpp:531:6:531:18 | test_strset_2 | 0 | char * | +| taint.cpp:538:7:538:13 | mempcpy | 0 | void * | +| taint.cpp:538:7:538:13 | mempcpy | 1 | const void * | +| taint.cpp:538:7:538:13 | mempcpy | 2 | size_t | +| taint.cpp:540:6:540:17 | test_mempcpy | 0 | int * | +| taint.cpp:548:7:548:13 | memccpy | 0 | void * | +| taint.cpp:548:7:548:13 | memccpy | 1 | const void * | +| taint.cpp:548:7:548:13 | memccpy | 2 | int | +| taint.cpp:548:7:548:13 | memccpy | 3 | size_t | +| taint.cpp:550:6:550:17 | test_memccpy | 0 | int * | +| taint.cpp:558:7:558:12 | strcat | 0 | char * | +| taint.cpp:558:7:558:12 | strcat | 1 | const char * | +| taint.cpp:560:6:560:16 | test_strcat | 0 | char * | +| taint.cpp:560:6:560:16 | test_strcat | 1 | char * | +| taint.cpp:560:6:560:16 | test_strcat | 2 | char * | +| taint.cpp:560:6:560:16 | test_strcat | 3 | char * | +| taint.cpp:570:16:570:25 | _mbsncat_l | 0 | unsigned char * | +| taint.cpp:570:16:570:25 | _mbsncat_l | 1 | const unsigned char * | +| taint.cpp:570:16:570:25 | _mbsncat_l | 2 | int | +| taint.cpp:570:16:570:25 | _mbsncat_l | 3 | _locale_t | +| taint.cpp:572:6:572:20 | test__mbsncat_l | 0 | unsigned char * | +| taint.cpp:572:6:572:20 | test__mbsncat_l | 1 | const unsigned char * | +| taint.cpp:572:6:572:20 | test__mbsncat_l | 2 | unsigned char * | +| taint.cpp:572:6:572:20 | test__mbsncat_l | 3 | _locale_t | +| taint.cpp:572:6:572:20 | test__mbsncat_l | 4 | _locale_t | +| taint.cpp:572:6:572:20 | test__mbsncat_l | 5 | int | +| taint.cpp:589:7:589:12 | strsep | 0 | char ** | +| taint.cpp:589:7:589:12 | strsep | 1 | const char * | +| taint.cpp:591:6:591:16 | test_strsep | 0 | char * | +| taint.cpp:602:7:602:13 | _strinc | 0 | const char * | +| taint.cpp:602:7:602:13 | _strinc | 1 | _locale_t | +| taint.cpp:603:16:603:22 | _mbsinc | 0 | const unsigned char * | +| taint.cpp:604:16:604:22 | _strdec | 0 | const unsigned char * | +| taint.cpp:604:16:604:22 | _strdec | 1 | const unsigned char * | +| taint.cpp:606:6:606:17 | test__strinc | 0 | char * | +| taint.cpp:606:6:606:17 | test__strinc | 1 | char * | +| taint.cpp:606:6:606:17 | test__strinc | 2 | char * | +| taint.cpp:606:6:606:17 | test__strinc | 3 | char * | +| taint.cpp:606:6:606:17 | test__strinc | 4 | _locale_t | +| taint.cpp:616:6:616:17 | test__mbsinc | 0 | unsigned char * | +| taint.cpp:616:6:616:17 | test__mbsinc | 1 | char * | +| taint.cpp:616:6:616:17 | test__mbsinc | 2 | unsigned char * | +| taint.cpp:616:6:616:17 | test__mbsinc | 3 | char * | +| taint.cpp:626:6:626:17 | test__strdec | 0 | const unsigned char * | +| taint.cpp:626:6:626:17 | test__strdec | 1 | unsigned char * | +| taint.cpp:626:6:626:17 | test__strdec | 2 | unsigned char * | +| taint.cpp:626:6:626:17 | test__strdec | 3 | unsigned char * | +| taint.cpp:626:6:626:17 | test__strdec | 4 | unsigned char * | +| taint.cpp:645:14:645:22 | _strnextc | 0 | const char * | +| taint.cpp:647:6:647:19 | test__strnextc | 0 | const char * | +| taint.cpp:659:7:659:7 | operator= | 0 | C_no_const_member_function && | +| taint.cpp:659:7:659:7 | operator= | 0 | const C_no_const_member_function & | +| taint.cpp:665:6:665:25 | test_no_const_member | 0 | char * | +| taint.cpp:671:7:671:7 | operator= | 0 | C_const_member_function && | +| taint.cpp:671:7:671:7 | operator= | 0 | const C_const_member_function & | +| taint.cpp:677:6:677:27 | test_with_const_member | 0 | char * | +| taint.cpp:683:6:683:20 | argument_source | 0 | void * | +| taint.cpp:685:8:685:8 | operator= | 0 | const two_members & | +| taint.cpp:685:8:685:8 | operator= | 0 | two_members && | +| taint.cpp:707:8:707:14 | strncpy | 0 | char * | +| taint.cpp:707:8:707:14 | strncpy | 1 | const char * | +| taint.cpp:707:8:707:14 | strncpy | 2 | unsigned long | +| taint.cpp:709:6:709:17 | test_strncpy | 0 | char * | +| taint.cpp:709:6:709:17 | test_strncpy | 1 | char * | +| taint.cpp:725:10:725:15 | strtol | 0 | const char * | +| taint.cpp:725:10:725:15 | strtol | 1 | char ** | +| taint.cpp:725:10:725:15 | strtol | 2 | int | +| taint.cpp:727:6:727:16 | test_strtol | 0 | char * | +| taint.cpp:735:7:735:12 | malloc | 0 | size_t | +| taint.cpp:736:7:736:13 | realloc | 0 | void * | +| taint.cpp:736:7:736:13 | realloc | 1 | size_t | +| taint.cpp:744:6:744:32 | test_realloc_2_indirections | 0 | int ** | +| taint.cpp:751:9:751:9 | operator= | 0 | A && | +| taint.cpp:751:9:751:9 | operator= | 0 | const A & | +| taint.cpp:758:5:758:11 | sprintf | 0 | char * | +| taint.cpp:758:5:758:11 | sprintf | 1 | const char * | +| taint.cpp:760:6:760:23 | call_sprintf_twice | 0 | char * | +| taint.cpp:760:6:760:23 | call_sprintf_twice | 1 | char * | +| taint.cpp:771:8:771:8 | operator= | 0 | TaintInheritingContentObject && | +| taint.cpp:771:8:771:8 | operator= | 0 | const TaintInheritingContentObject & | +| taint.cpp:775:30:775:35 | source | 0 | bool | +| taint.cpp:782:7:782:11 | fopen | 0 | const char * | +| taint.cpp:782:7:782:11 | fopen | 1 | const char * | +| taint.cpp:783:5:783:11 | fopen_s | 0 | FILE ** | +| taint.cpp:783:5:783:11 | fopen_s | 1 | const char * | +| taint.cpp:783:5:783:11 | fopen_s | 2 | const char * | +| taint.cpp:785:6:785:15 | fopen_test | 0 | char * | +| vector.cpp:13:6:13:9 | sink | 0 | int | +| vector.cpp:14:27:14:30 | sink | 0 | vector, allocator>, allocator, allocator>>> & | | vector.cpp:14:27:14:30 | sink | 0 | vector> & | | vector.cpp:14:27:14:30 | sink | 0 | vector> & | +| vector.cpp:16:6:16:37 | test_range_based_for_loop_vector | 0 | int | +| vector.cpp:37:6:37:23 | test_element_taint | 0 | int | +| vector.cpp:145:8:145:8 | operator= | 0 | MyPair && | +| vector.cpp:145:8:145:8 | operator= | 0 | const MyPair & | +| vector.cpp:150:8:150:8 | MyVectorContainer | 0 | const MyVectorContainer & | +| vector.cpp:150:8:150:8 | operator= | 0 | MyVectorContainer && | +| vector.cpp:150:8:150:8 | operator= | 0 | const MyVectorContainer & | +| vector.cpp:216:6:216:9 | sink | 0 | iterator & | +| vector.cpp:231:6:231:9 | sink | 0 | vector> & | +| vector.cpp:232:6:232:9 | sink | 0 | vector> & | +| vector.cpp:279:6:279:9 | sink | 0 | int * | +| vector.cpp:295:6:295:9 | sink | 0 | iterator | +| vector.cpp:329:6:329:33 | taint_vector_output_iterator | 0 | iterator | +| vector.cpp:333:6:333:35 | vector_iterator_assign_wrapper | 0 | iterator | +| vector.cpp:333:6:333:35 | vector_iterator_assign_wrapper | 1 | int | +| vector.cpp:337:6:337:32 | test_vector_output_iterator | 0 | int | +| vector.cpp:417:6:417:25 | test_vector_inserter | 0 | char * | +| vector.cpp:454:7:454:12 | memcpy | 0 | void * | +| vector.cpp:454:7:454:12 | memcpy | 1 | const void * | +| vector.cpp:454:7:454:12 | memcpy | 2 | size_t | +| vector.cpp:461:6:461:9 | sink | 0 | vector> & | +| vector.cpp:462:6:462:9 | sink | 0 | string & | +| zmq.cpp:9:8:9:8 | operator= | 0 | const zmq_msg_t & | +| zmq.cpp:9:8:9:8 | operator= | 0 | zmq_msg_t && | +| zmq.cpp:14:5:14:21 | zmq_msg_init_data | 0 | zmq_msg_t * | +| zmq.cpp:14:5:14:21 | zmq_msg_init_data | 1 | void * | +| zmq.cpp:14:5:14:21 | zmq_msg_init_data | 2 | size_t | +| zmq.cpp:14:5:14:21 | zmq_msg_init_data | 3 | zmq_free_fn * | +| zmq.cpp:14:5:14:21 | zmq_msg_init_data | 4 | void * | +| zmq.cpp:15:7:15:18 | zmq_msg_data | 0 | zmq_msg_t * | +| zmq.cpp:17:6:17:13 | test_zmc | 0 | void * | +| zmq.cpp:17:6:17:13 | test_zmc | 1 | char * | +| zmq.cpp:17:6:17:13 | test_zmc | 2 | size_t | From 02428745bdf126588ddb42522042dfa78a46ee67 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 16:12:58 +0000 Subject: [PATCH 038/213] C++: Add change note. --- cpp/ql/src/change-notes/2024-11-27-active-template-library.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-11-27-active-template-library.md diff --git a/cpp/ql/src/change-notes/2024-11-27-active-template-library.md b/cpp/ql/src/change-notes/2024-11-27-active-template-library.md new file mode 100644 index 000000000000..a677ac661077 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-11-27-active-template-library.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added dataflow models and flow sources for Microsoft's Active Template Library (ATL). \ No newline at end of file From 3c0af498db588c2fd3974fd64f58687b33360581 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 Nov 2024 19:04:25 +0000 Subject: [PATCH 039/213] C++: Fix bug introduced in an earlier commit and accept test changes. They all look good. --- .../semmle/code/cpp/dataflow/ExternalFlow.qll | 4 +- .../taint-tests/test_mad-signatures.expected | 193 ------------------ 2 files changed, 2 insertions(+), 195 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index ac10651b5519..9496bfe98ba1 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -437,13 +437,13 @@ private predicate elementSpec( private predicate isClassConstructedFrom(Class c, Class templateClass) { c.isConstructedFrom(templateClass) or - not any(Class c_).isConstructedFrom(templateClass) and c = templateClass + not c.isConstructedFrom(_) and c = templateClass } private predicate isFunctionConstructedFrom(Function f, Function templateFunc) { f.isConstructedFrom(templateFunc) or - not any(Function f_).isConstructedFrom(templateFunc) and f = templateFunc + not f.isConstructedFrom(_) and f = templateFunc } /** Gets the fully templated version of `f`. */ diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 1f84cd3379af..0d121219209a 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -76,15 +76,6 @@ signatureMatches | constructor_delegation.cpp:10:2:10:8 | MyValue | (LPCOLESTR,int) | CComBSTR | Append | 1 | | constructor_delegation.cpp:19:2:19:15 | MyDerivedValue | (LPCOLESTR,int) | CComBSTR | Append | 1 | | standalone_iterators.cpp:103:27:103:36 | operator+= | (LPCOLESTR,int) | CComBSTR | Append | 1 | -| stl.h:165:8:165:16 | push_back | (char) | CComBSTR | Append | 0 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | deque | assign | 0 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | deque | assign | 1 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | forward_list | assign | 0 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | forward_list | assign | 1 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | list | assign | 0 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | list | assign | 1 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | vector | assign | 0 | -| stl.h:181:47:181:52 | append | (InputIt,InputIt) | vector | assign | 1 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | deque | assign | 0 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | deque | assign | 1 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | forward_list | assign | 0 | @@ -93,14 +84,6 @@ signatureMatches | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | list | assign | 1 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | vector | assign | 0 | | stl.h:182:17:182:22 | assign | (InputIt,InputIt) | vector | assign | 1 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | deque | assign | 0 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | deque | assign | 1 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | forward_list | assign | 0 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | forward_list | assign | 1 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | list | assign | 0 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | list | assign | 1 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | vector | assign | 0 | -| stl.h:184:47:184:52 | assign | (InputIt,InputIt) | vector | assign | 1 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | deque | assign | 0 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | deque | assign | 1 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | forward_list | assign | 0 | @@ -109,18 +92,6 @@ signatureMatches | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | list | assign | 1 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | vector | assign | 0 | | stl.h:185:17:185:22 | insert | (InputIt,InputIt) | vector | assign | 1 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | deque | insert | 0 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | deque | insert | 1 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | deque | insert | 2 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | forward_list | insert_after | 0 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | forward_list | insert_after | 1 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | forward_list | insert_after | 2 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | list | insert | 0 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | list | insert | 1 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | list | insert | 2 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | vector | insert | 0 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | vector | insert | 1 | -| stl.h:189:42:189:47 | insert | (const_iterator,InputIt,InputIt) | vector | insert | 2 | | stl.h:190:17:190:23 | replace | (const_iterator,InputIt,InputIt) | deque | insert | 0 | | stl.h:190:17:190:23 | replace | (const_iterator,InputIt,InputIt) | deque | insert | 1 | | stl.h:190:17:190:23 | replace | (const_iterator,InputIt,InputIt) | deque | insert | 2 | @@ -561,13 +532,10 @@ getParameterTypeName | atl.cpp:69:3:69:15 | _U_STRINGorID | 0 | LPCTSTR | | atl.cpp:193:10:193:12 | Add | 0 | INARGTYPclass:0 | | atl.cpp:195:10:195:15 | Append | 0 | const CAtlArray & | -| atl.cpp:195:10:195:15 | Append | 0 | const CAtlArray> & | | atl.cpp:196:8:196:11 | Copy | 0 | const CAtlArray & | -| atl.cpp:196:8:196:11 | Copy | 0 | const CAtlArray> & | | atl.cpp:198:6:198:10 | GetAt | 0 | size_t | | atl.cpp:202:8:202:20 | InsertArrayAt | 0 | size_t | | atl.cpp:202:8:202:20 | InsertArrayAt | 1 | const CAtlArray * | -| atl.cpp:202:8:202:20 | InsertArrayAt | 1 | const CAtlArray> * | | atl.cpp:203:8:203:15 | InsertAt | 0 | size_t | | atl.cpp:203:8:203:15 | InsertAt | 1 | INARGTYPclass:0 | | atl.cpp:203:8:203:15 | InsertAt | 2 | size_t | @@ -577,10 +545,8 @@ getParameterTypeName | atl.cpp:256:3:256:10 | CAtlList | 0 | UINT | | atl.cpp:259:12:259:18 | AddHead | 0 | INARGTYPclass:0 | | atl.cpp:260:8:260:18 | AddHeadList | 0 | const CAtlList * | -| atl.cpp:260:8:260:18 | AddHeadList | 0 | const CAtlList> * | | atl.cpp:262:12:262:18 | AddTail | 0 | INARGTYPclass:0 | | atl.cpp:263:8:263:18 | AddTailList | 0 | const CAtlList * | -| atl.cpp:263:8:263:18 | AddTailList | 0 | const CAtlList> * | | atl.cpp:264:12:264:15 | Find | 0 | INARGTYPclass:0 | | atl.cpp:264:12:264:15 | Find | 1 | POSITION | | atl.cpp:265:12:265:20 | FindIndex | 0 | size_t | @@ -633,12 +599,10 @@ getParameterTypeName | atl.cpp:537:3:537:15 | CComSafeArray | 0 | const SAFEARRAY * | | atl.cpp:541:11:541:13 | Add | 0 | const SAFEARRAY * | | atl.cpp:543:11:543:13 | Add | 0 | const class:0 & | -| atl.cpp:543:11:543:13 | Add | 0 | const int & | | atl.cpp:543:11:543:13 | Add | 1 | BOOL | | atl.cpp:551:6:551:10 | GetAt | 0 | LONG | | atl.cpp:562:11:562:15 | SetAt | 0 | LONG | | atl.cpp:562:11:562:15 | SetAt | 1 | const class:0 & | -| atl.cpp:562:11:562:15 | SetAt | 1 | const int & | | atl.cpp:562:11:562:15 | SetAt | 2 | BOOL | | atl.cpp:564:6:564:15 | operator[] | 0 | long | | atl.cpp:565:6:565:15 | operator[] | 0 | int | @@ -651,33 +615,21 @@ getParameterTypeName | atl.cpp:619:22:619:33 | CommonPrefix | 0 | PCXSTR | | atl.cpp:656:23:656:32 | operator+= | 0 | PCXSTR | | atl.cpp:716:8:716:10 | Add | 0 | const class:0 & | -| atl.cpp:716:8:716:10 | Add | 0 | const int & | | atl.cpp:717:7:717:10 | Find | 0 | const class:0 & | -| atl.cpp:717:7:717:10 | Find | 0 | const int & | | atl.cpp:728:6:728:15 | operator[] | 0 | int | | atl.cpp:729:21:729:29 | operator= | 0 | const CSimpleArray & | -| atl.cpp:762:8:762:10 | Add | 0 | char *const & | | atl.cpp:762:8:762:10 | Add | 0 | const class:0 & | | atl.cpp:762:8:762:10 | Add | 1 | const class:1 & | -| atl.cpp:762:8:762:10 | Add | 1 | wchar_t *const & | -| atl.cpp:763:7:763:13 | FindKey | 0 | char *const & | | atl.cpp:763:7:763:13 | FindKey | 0 | const class:0 & | | atl.cpp:764:7:764:13 | FindVal | 0 | const class:1 & | -| atl.cpp:764:7:764:13 | FindVal | 0 | wchar_t *const & | | atl.cpp:767:9:767:18 | GetValueAt | 0 | int | -| atl.cpp:768:8:768:13 | Lookup | 0 | char *const & | | atl.cpp:768:8:768:13 | Lookup | 0 | const class:0 & | | atl.cpp:772:8:772:20 | ReverseLookup | 0 | const class:1 & | -| atl.cpp:772:8:772:20 | ReverseLookup | 0 | wchar_t *const & | -| atl.cpp:773:8:773:12 | SetAt | 0 | char *const & | | atl.cpp:773:8:773:12 | SetAt | 0 | const class:0 & | | atl.cpp:773:8:773:12 | SetAt | 1 | const class:1 & | -| atl.cpp:773:8:773:12 | SetAt | 1 | wchar_t *const & | | atl.cpp:774:8:774:17 | SetAtIndex | 0 | int | -| atl.cpp:774:8:774:17 | SetAtIndex | 1 | char *const & | | atl.cpp:774:8:774:17 | SetAtIndex | 1 | const class:0 & | | atl.cpp:774:8:774:17 | SetAtIndex | 2 | const class:1 & | -| atl.cpp:774:8:774:17 | SetAtIndex | 2 | wchar_t *const & | | atl.cpp:813:9:813:17 | operator= | 0 | const CUrl & | | atl.cpp:815:3:815:6 | CUrl | 0 | const CUrl & | | atl.cpp:818:15:818:26 | Canonicalize | 0 | DWORD | @@ -826,7 +778,6 @@ getParameterTypeName | stl.h:29:34:29:40 | forward | 0 | remove_reference_t & | | stl.h:29:34:29:40 | forward | 0 | remove_reference_t & | | stl.h:29:34:29:40 | forward | 0 | remove_reference_t & | -| stl.h:29:34:29:40 | forward | 0 | remove_reference_t> & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | @@ -835,8 +786,6 @@ getParameterTypeName | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | | stl.h:49:3:49:10 | iterator | 0 | const iterator & | -| stl.h:49:3:49:10 | iterator | 0 | const iterator, ptrdiff_t, pair *, pair &> & | -| stl.h:49:3:49:10 | iterator | 0 | const iterator, ptrdiff_t, pair *, pair &> & | | stl.h:52:12:52:21 | operator++ | 0 | int | | stl.h:52:12:52:21 | operator++ | 0 | int | | stl.h:52:12:52:21 | operator++ | 0 | int | @@ -849,7 +798,6 @@ getParameterTypeName | stl.h:56:8:56:17 | operator!= | 0 | iterator | | stl.h:56:8:56:17 | operator!= | 0 | iterator | | stl.h:56:8:56:17 | operator!= | 0 | iterator | -| stl.h:56:8:56:17 | operator!= | 0 | iterator, ptrdiff_t, pair *, pair &> | | stl.h:59:12:59:20 | operator+ | 0 | int | | stl.h:60:12:60:20 | operator- | 0 | int | | stl.h:61:13:61:22 | operator+= | 0 | int | @@ -868,92 +816,51 @@ getParameterTypeName | stl.h:72:9:72:9 | operator= | 0 | output_iterator_tag && | | stl.h:86:22:86:41 | back_insert_iterator | 0 | class:0 & | | stl.h:86:22:86:41 | back_insert_iterator | 0 | class:0 & | -| stl.h:86:22:86:41 | back_insert_iterator | 0 | vector, allocator>, allocator, allocator>>> & | -| stl.h:86:22:86:41 | back_insert_iterator | 0 | vector> & | | stl.h:88:25:88:33 | operator= | 0 | value_type && | | stl.h:88:25:88:33 | operator= | 0 | value_type && | | stl.h:91:24:91:33 | operator++ | 0 | int | | stl.h:91:24:91:33 | operator++ | 0 | int | | stl.h:95:44:95:44 | back_inserter | 0 | func:0 & | | stl.h:95:44:95:44 | back_inserter | 0 | func:0 & | -| stl.h:95:44:95:44 | back_inserter | 0 | vector, allocator>, allocator, allocator>>> & | -| stl.h:95:44:95:44 | back_inserter | 0 | vector> & | -| stl.h:147:12:147:23 | basic_string | 0 | const allocator & | -| stl.h:148:3:148:14 | basic_string | 0 | const char * | | stl.h:148:3:148:14 | basic_string | 0 | const class:2 & | -| stl.h:148:3:148:14 | basic_string | 1 | const allocator & | | stl.h:149:33:149:44 | basic_string | 0 | const class:0 * | -| stl.h:149:33:149:44 | basic_string | 0 | func:0 | | stl.h:149:33:149:44 | basic_string | 1 | const class:2 & | -| stl.h:149:33:149:44 | basic_string | 1 | func:0 | -| stl.h:149:33:149:44 | basic_string | 2 | const allocator & | | stl.h:151:16:151:20 | c_str | 0 | func:0 | | stl.h:151:16:151:20 | c_str | 1 | func:0 | | stl.h:151:16:151:20 | c_str | 2 | const class:2 & | -| stl.h:165:8:165:16 | push_back | 0 | char | | stl.h:173:13:173:22 | operator[] | 0 | size_type | | stl.h:175:13:175:14 | at | 0 | size_type | -| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & | -| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & | | stl.h:176:35:176:44 | operator+= | 0 | size_type | | stl.h:176:35:176:44 | operator+= | 0 | size_type | -| stl.h:177:17:177:26 | operator+= | 0 | const char * | | stl.h:177:17:177:26 | operator+= | 0 | const func:0 & | -| stl.h:178:17:178:22 | append | 0 | const basic_string, allocator> & | | stl.h:178:17:178:22 | append | 0 | const class:0 * | | stl.h:179:17:179:22 | append | 0 | const basic_string & | -| stl.h:179:17:179:22 | append | 0 | const char * | | stl.h:180:17:180:22 | append | 0 | const class:0 * | -| stl.h:180:17:180:22 | append | 0 | size_type | -| stl.h:180:17:180:22 | append | 1 | char | -| stl.h:181:47:181:52 | append | 0 | func:0 | | stl.h:181:47:181:52 | append | 0 | size_type | | stl.h:181:47:181:52 | append | 1 | class:0 | -| stl.h:181:47:181:52 | append | 1 | func:0 | -| stl.h:182:17:182:22 | assign | 0 | const basic_string, allocator> & | | stl.h:182:17:182:22 | assign | 0 | func:0 | | stl.h:182:17:182:22 | assign | 1 | func:0 | | stl.h:183:17:183:22 | assign | 0 | const basic_string & | -| stl.h:183:17:183:22 | assign | 0 | size_type | -| stl.h:183:17:183:22 | assign | 1 | char | -| stl.h:184:47:184:52 | assign | 0 | func:0 | | stl.h:184:47:184:52 | assign | 0 | size_type | | stl.h:184:47:184:52 | assign | 1 | class:0 | -| stl.h:184:47:184:52 | assign | 1 | func:0 | | stl.h:185:17:185:22 | insert | 0 | func:0 | -| stl.h:185:17:185:22 | insert | 0 | size_type | -| stl.h:185:17:185:22 | insert | 1 | const basic_string, allocator> & | | stl.h:185:17:185:22 | insert | 1 | func:0 | | stl.h:186:17:186:22 | insert | 0 | size_type | | stl.h:186:17:186:22 | insert | 1 | const basic_string & | -| stl.h:186:17:186:22 | insert | 1 | size_type | -| stl.h:186:17:186:22 | insert | 2 | char | | stl.h:187:17:187:22 | insert | 0 | size_type | -| stl.h:187:17:187:22 | insert | 1 | const char * | | stl.h:187:17:187:22 | insert | 1 | size_type | | stl.h:187:17:187:22 | insert | 2 | class:0 | -| stl.h:188:12:188:17 | insert | 0 | const_iterator | | stl.h:188:12:188:17 | insert | 0 | size_type | | stl.h:188:12:188:17 | insert | 1 | const class:0 * | -| stl.h:188:12:188:17 | insert | 1 | size_type | -| stl.h:188:12:188:17 | insert | 2 | char | | stl.h:189:42:189:47 | insert | 0 | const_iterator | -| stl.h:189:42:189:47 | insert | 1 | func:0 | | stl.h:189:42:189:47 | insert | 1 | size_type | | stl.h:189:42:189:47 | insert | 2 | class:0 | -| stl.h:189:42:189:47 | insert | 2 | func:0 | | stl.h:190:17:190:23 | replace | 0 | const_iterator | -| stl.h:190:17:190:23 | replace | 0 | size_type | | stl.h:190:17:190:23 | replace | 1 | func:0 | -| stl.h:190:17:190:23 | replace | 1 | size_type | -| stl.h:190:17:190:23 | replace | 2 | const basic_string, allocator> & | | stl.h:190:17:190:23 | replace | 2 | func:0 | | stl.h:191:17:191:23 | replace | 0 | size_type | | stl.h:191:17:191:23 | replace | 1 | size_type | | stl.h:191:17:191:23 | replace | 2 | const basic_string & | -| stl.h:191:17:191:23 | replace | 2 | size_type | -| stl.h:191:17:191:23 | replace | 3 | char | -| stl.h:192:13:192:16 | copy | 0 | char * | | stl.h:192:13:192:16 | copy | 0 | size_type | | stl.h:192:13:192:16 | copy | 1 | size_type | | stl.h:192:13:192:16 | copy | 2 | size_type | @@ -961,18 +868,11 @@ getParameterTypeName | stl.h:193:8:193:12 | clear | 0 | class:0 * | | stl.h:193:8:193:12 | clear | 1 | size_type | | stl.h:193:8:193:12 | clear | 2 | size_type | -| stl.h:194:16:194:21 | substr | 0 | size_type | -| stl.h:194:16:194:21 | substr | 1 | size_type | -| stl.h:195:8:195:11 | swap | 0 | basic_string, allocator> & | | stl.h:195:8:195:11 | swap | 0 | size_type | | stl.h:195:8:195:11 | swap | 1 | size_type | | stl.h:198:94:198:102 | operator+ | 0 | const basic_string & | -| stl.h:198:94:198:102 | operator+ | 0 | const basic_string, allocator> & | | stl.h:198:94:198:102 | operator+ | 1 | const basic_string & | -| stl.h:198:94:198:102 | operator+ | 1 | const basic_string, allocator> & | | stl.h:199:94:199:102 | operator+ | 0 | const basic_string & | -| stl.h:199:94:199:102 | operator+ | 0 | const basic_string, allocator> & | -| stl.h:199:94:199:102 | operator+ | 1 | const char * | | stl.h:199:94:199:102 | operator+ | 1 | const func:0 * | | stl.h:214:33:214:42 | operator>> | 0 | int & | | stl.h:217:33:217:35 | get | 0 | char_type & | @@ -989,49 +889,26 @@ getParameterTypeName | stl.h:226:32:226:38 | getline | 1 | streamsize | | stl.h:226:32:226:38 | getline | 2 | char_type | | stl.h:229:68:229:77 | operator>> | 0 | basic_istream & | -| stl.h:229:68:229:77 | operator>> | 0 | basic_istream> & | -| stl.h:229:68:229:77 | operator>> | 1 | char * | | stl.h:229:68:229:77 | operator>> | 1 | func:0 * | | stl.h:230:85:230:94 | operator>> | 0 | basic_istream & | -| stl.h:230:85:230:94 | operator>> | 0 | basic_istream> & | | stl.h:230:85:230:94 | operator>> | 1 | basic_string & | -| stl.h:230:85:230:94 | operator>> | 1 | basic_string, allocator> & | | stl.h:232:84:232:90 | getline | 0 | basic_istream & | -| stl.h:232:84:232:90 | getline | 0 | basic_istream> & | | stl.h:232:84:232:90 | getline | 1 | basic_string & | -| stl.h:232:84:232:90 | getline | 1 | basic_string, allocator> & | -| stl.h:232:84:232:90 | getline | 2 | char | | stl.h:232:84:232:90 | getline | 2 | func:0 | | stl.h:233:84:233:90 | getline | 0 | basic_istream & | -| stl.h:233:84:233:90 | getline | 0 | basic_istream> & | | stl.h:233:84:233:90 | getline | 1 | basic_string & | -| stl.h:233:84:233:90 | getline | 1 | basic_string, allocator> & | | stl.h:240:33:240:42 | operator<< | 0 | int | | stl.h:242:33:242:35 | put | 0 | char_type | | stl.h:243:33:243:37 | write | 0 | const char_type * | | stl.h:243:33:243:37 | write | 1 | streamsize | | stl.h:247:67:247:76 | operator<< | 0 | basic_ostream & | -| stl.h:247:67:247:76 | operator<< | 0 | basic_ostream> & | -| stl.h:247:67:247:76 | operator<< | 1 | const char * | | stl.h:247:67:247:76 | operator<< | 1 | const func:0 * | | stl.h:248:85:248:94 | operator<< | 0 | basic_ostream & | -| stl.h:248:85:248:94 | operator<< | 0 | basic_ostream> & | | stl.h:248:85:248:94 | operator<< | 1 | const basic_string & | -| stl.h:248:85:248:94 | operator<< | 1 | const basic_string, allocator> & | | stl.h:259:12:259:29 | basic_stringstream | 0 | const basic_string & | -| stl.h:259:12:259:29 | basic_stringstream | 0 | const basic_string, allocator> & | | stl.h:263:23:263:31 | operator= | 0 | basic_stringstream && | -| stl.h:263:23:263:31 | operator= | 0 | basic_stringstream, allocator> && | | stl.h:265:8:265:11 | swap | 0 | basic_stringstream & | -| stl.h:265:8:265:11 | swap | 0 | basic_stringstream, allocator> & | | stl.h:268:8:268:10 | str | 0 | const basic_string & | -| stl.h:268:8:268:10 | str | 0 | const basic_string, allocator> & | -| stl.h:293:12:293:17 | vector | 0 | const allocator & | -| stl.h:293:12:293:17 | vector | 0 | const allocator & | -| stl.h:293:12:293:17 | vector | 0 | const allocator & | -| stl.h:293:12:293:17 | vector | 0 | const allocator & | -| stl.h:293:12:293:17 | vector | 0 | const allocator & | -| stl.h:293:12:293:17 | vector | 0 | const allocator, allocator>> & | | stl.h:293:12:293:17 | vector | 0 | const class:1 & | | stl.h:293:12:293:17 | vector | 0 | const class:1 & | | stl.h:293:12:293:17 | vector | 0 | const class:1 & | @@ -1041,9 +918,6 @@ getParameterTypeName | stl.h:294:12:294:17 | vector | 0 | size_type | | stl.h:294:12:294:17 | vector | 0 | size_type | | stl.h:294:12:294:17 | vector | 0 | size_type | -| stl.h:294:12:294:17 | vector | 1 | const allocator & | -| stl.h:294:12:294:17 | vector | 1 | const allocator & | -| stl.h:294:12:294:17 | vector | 1 | const allocator>> & | | stl.h:294:12:294:17 | vector | 1 | const class:1 & | | stl.h:294:12:294:17 | vector | 1 | const class:1 & | | stl.h:294:12:294:17 | vector | 1 | const class:1 & | @@ -1051,20 +925,13 @@ getParameterTypeName | stl.h:295:3:295:8 | vector | 0 | size_type | | stl.h:295:3:295:8 | vector | 1 | const class:0 & | | stl.h:295:3:295:8 | vector | 1 | const class:0 & | -| stl.h:295:3:295:8 | vector | 1 | const int & | -| stl.h:295:3:295:8 | vector | 1 | const short & | -| stl.h:295:3:295:8 | vector | 2 | const allocator & | -| stl.h:295:3:295:8 | vector | 2 | const allocator & | | stl.h:295:3:295:8 | vector | 2 | const class:1 & | | stl.h:295:3:295:8 | vector | 2 | const class:1 & | | stl.h:296:101:296:106 | vector | 0 | func:0 | | stl.h:296:101:296:106 | vector | 1 | func:0 | -| stl.h:296:101:296:106 | vector | 2 | const allocator & | | stl.h:296:101:296:106 | vector | 2 | const class:1 & | | stl.h:301:11:301:19 | operator= | 0 | const vector & | -| stl.h:301:11:301:19 | operator= | 0 | const vector> & | | stl.h:302:11:302:19 | operator= | 0 | vector && | -| stl.h:302:11:302:19 | operator= | 0 | vector> && | | stl.h:303:106:303:111 | assign | 0 | func:0 | | stl.h:303:106:303:111 | assign | 1 | func:0 | | stl.h:306:8:306:13 | assign | 0 | size_type | @@ -1073,9 +940,6 @@ getParameterTypeName | stl.h:306:8:306:13 | assign | 1 | const class:0 & | | stl.h:306:8:306:13 | assign | 1 | const class:0 & | | stl.h:306:8:306:13 | assign | 1 | const class:0 & | -| stl.h:306:8:306:13 | assign | 1 | const float & | -| stl.h:306:8:306:13 | assign | 1 | const int & | -| stl.h:306:8:306:13 | assign | 1 | const int *const & | | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:315:13:315:22 | operator[] | 0 | size_type | @@ -1083,15 +947,11 @@ getParameterTypeName | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:315:13:315:22 | operator[] | 0 | size_type | | stl.h:318:13:318:14 | at | 0 | size_type | -| stl.h:327:8:327:16 | push_back | 0 | const MyPair & | -| stl.h:327:8:327:16 | push_back | 0 | const MyVectorContainer & | | stl.h:327:8:327:16 | push_back | 0 | const class:0 & | | stl.h:327:8:327:16 | push_back | 0 | const class:0 & | | stl.h:328:8:328:16 | push_back | 0 | class:0 && | -| stl.h:328:8:328:16 | push_back | 0 | int && | | stl.h:331:12:331:17 | insert | 0 | const_iterator | | stl.h:331:12:331:17 | insert | 1 | class:0 && | -| stl.h:331:12:331:17 | insert | 1 | int && | | stl.h:333:42:333:47 | insert | 0 | const_iterator | | stl.h:333:42:333:47 | insert | 0 | const_iterator | | stl.h:333:42:333:47 | insert | 1 | func:0 | @@ -1102,38 +962,21 @@ getParameterTypeName | stl.h:335:37:335:43 | emplace | 1 | func:0 && | | stl.h:336:33:336:44 | emplace_back | 0 | func:0 && | | stl.h:338:8:338:11 | swap | 0 | vector & | -| stl.h:338:8:338:11 | swap | 0 | vector> & | | stl.h:351:12:351:21 | shared_ptr | 0 | class:0 * | -| stl.h:351:12:351:21 | shared_ptr | 0 | int * | | stl.h:352:3:352:12 | shared_ptr | 0 | const shared_ptr & | | stl.h:352:3:352:12 | shared_ptr | 0 | const shared_ptr & | -| stl.h:369:12:369:21 | unique_ptr | 0 | A * | | stl.h:369:12:369:21 | unique_ptr | 0 | class:0 * | | stl.h:380:52:380:62 | make_unique | 0 | func:1 && | | stl.h:380:52:380:62 | make_unique | 0 | func:1 && | | stl.h:380:52:380:62 | make_unique | 0 | func:1 && | -| stl.h:380:52:380:62 | make_unique | 0 | int && | -| stl.h:380:52:380:62 | make_unique | 0 | int && | | stl.h:382:52:382:62 | make_shared | 0 | func:1 && | | stl.h:382:52:382:62 | make_shared | 0 | func:1 && | | stl.h:382:52:382:62 | make_shared | 0 | func:1 && | -| stl.h:382:52:382:62 | make_shared | 0 | int && | -| stl.h:382:52:382:62 | make_shared | 0 | int && | -| stl.h:396:3:396:3 | pair | 0 | char *const & | -| stl.h:396:3:396:3 | pair | 0 | char *const & | -| stl.h:396:3:396:3 | pair | 0 | const char *const & | -| stl.h:396:3:396:3 | pair | 0 | const char *const & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | | stl.h:396:3:396:3 | pair | 0 | const class:0 & | -| stl.h:396:3:396:3 | pair | 0 | const pair & | -| stl.h:396:3:396:3 | pair | 1 | char *const & | -| stl.h:396:3:396:3 | pair | 1 | char *const & | -| stl.h:396:3:396:3 | pair | 1 | const char *const & | -| stl.h:396:3:396:3 | pair | 1 | const char *const & | -| stl.h:396:3:396:3 | pair | 1 | const char *const & | | stl.h:396:3:396:3 | pair | 1 | const class:1 & | | stl.h:396:3:396:3 | pair | 1 | const class:1 & | | stl.h:396:3:396:3 | pair | 1 | const class:1 & | @@ -1152,24 +995,12 @@ getParameterTypeName | stl.h:397:30:397:33 | pair | 0 | const pair & | | stl.h:397:30:397:33 | pair | 0 | const pair & | | stl.h:399:8:399:11 | swap | 0 | pair & | -| stl.h:402:72:402:72 | make_pair | 0 | char *&& | -| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[2] | -| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[2] | -| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[4] | -| stl.h:402:72:402:72 | make_pair | 0 | const char(&)[4] | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | | stl.h:402:72:402:72 | make_pair | 0 | func:0 && | -| stl.h:402:72:402:72 | make_pair | 0 | pair && | -| stl.h:402:72:402:72 | make_pair | 1 | char *&& | -| stl.h:402:72:402:72 | make_pair | 1 | char *&& | -| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[2] | -| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[4] | -| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[4] | -| stl.h:402:72:402:72 | make_pair | 1 | const char(&)[4] | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | @@ -1177,9 +1008,7 @@ getParameterTypeName | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:402:72:402:72 | make_pair | 1 | func:1 && | | stl.h:422:3:422:5 | map | 0 | const map & | -| stl.h:422:3:422:5 | map | 0 | const map, allocator>> & | | stl.h:426:8:426:16 | operator= | 0 | const map & | -| stl.h:426:8:426:16 | operator= | 0 | const map, allocator>> & | | stl.h:435:6:435:15 | operator[] | 0 | key_type && | | stl.h:435:6:435:15 | operator[] | 0 | key_type && | | stl.h:436:6:436:7 | at | 0 | const key_type & | @@ -1209,19 +1038,14 @@ getParameterTypeName | stl.h:454:30:454:45 | insert_or_assign | 2 | func:0 && | | stl.h:456:12:456:16 | erase | 0 | iterator | | stl.h:459:8:459:11 | swap | 0 | map & | -| stl.h:459:8:459:11 | swap | 0 | map, allocator>> & | | stl.h:462:27:462:31 | merge | 0 | map & | -| stl.h:462:27:462:31 | merge | 0 | map>> & | | stl.h:465:12:465:15 | find | 0 | const key_type & | | stl.h:468:12:468:22 | lower_bound | 0 | const key_type & | | stl.h:470:12:470:22 | upper_bound | 0 | const key_type & | | stl.h:473:28:473:38 | equal_range | 0 | const key_type & | | stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map & | | stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map & | -| stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map, equal_to, allocator>> & | -| stl.h:490:3:490:15 | unordered_map | 0 | const unordered_map, hash, equal_to, allocator>>> & | | stl.h:494:18:494:26 | operator= | 0 | const unordered_map & | -| stl.h:494:18:494:26 | operator= | 0 | const unordered_map, equal_to, allocator>> & | | stl.h:503:16:503:25 | operator[] | 0 | key_type && | | stl.h:503:16:503:25 | operator[] | 0 | key_type && | | stl.h:504:16:504:17 | at | 0 | const key_type & | @@ -1260,17 +1084,13 @@ getParameterTypeName | stl.h:522:30:522:45 | insert_or_assign | 2 | func:0 && | | stl.h:524:12:524:16 | erase | 0 | iterator | | stl.h:527:8:527:11 | swap | 0 | unordered_map & | -| stl.h:527:8:527:11 | swap | 0 | unordered_map, equal_to, allocator>> & | | stl.h:530:37:530:41 | merge | 0 | unordered_map & | -| stl.h:530:37:530:41 | merge | 0 | unordered_map>> & | | stl.h:533:12:533:15 | find | 0 | const key_type & | | stl.h:536:28:536:38 | equal_range | 0 | const key_type & | | stl.h:555:3:555:5 | set | 0 | const set & | -| stl.h:555:3:555:5 | set | 0 | const set, allocator> & | | stl.h:557:33:557:35 | set | 0 | func:0 | | stl.h:557:33:557:35 | set | 1 | func:0 | | stl.h:560:8:560:16 | operator= | 0 | const set & | -| stl.h:560:8:560:16 | operator= | 0 | const set, allocator> & | | stl.h:568:48:568:54 | emplace | 0 | func:0 && | | stl.h:568:48:568:54 | emplace | 0 | func:0 && | | stl.h:569:36:569:47 | emplace_hint | 0 | const_iterator | @@ -1284,20 +1104,16 @@ getParameterTypeName | stl.h:574:38:574:43 | insert | 1 | func:0 | | stl.h:576:12:576:16 | erase | 0 | iterator | | stl.h:579:8:579:11 | swap | 0 | set & | -| stl.h:579:8:579:11 | swap | 0 | set, allocator> & | | stl.h:582:27:582:31 | merge | 0 | set & | -| stl.h:582:27:582:31 | merge | 0 | set> & | | stl.h:585:12:585:15 | find | 0 | const key_type & | | stl.h:588:12:588:22 | lower_bound | 0 | const key_type & | | stl.h:590:12:590:22 | upper_bound | 0 | const key_type & | | stl.h:592:28:592:38 | equal_range | 0 | const key_type & | | stl.h:609:3:609:15 | unordered_set | 0 | const unordered_set & | -| stl.h:609:3:609:15 | unordered_set | 0 | const unordered_set, equal_to, allocator> & | | stl.h:611:33:611:45 | unordered_set | 0 | func:0 | | stl.h:611:33:611:45 | unordered_set | 1 | func:0 | | stl.h:611:33:611:45 | unordered_set | 2 | size_type | | stl.h:614:18:614:26 | operator= | 0 | const unordered_set & | -| stl.h:614:18:614:26 | operator= | 0 | const unordered_set, equal_to, allocator> & | | stl.h:622:48:622:54 | emplace | 0 | func:0 && | | stl.h:622:48:622:54 | emplace | 0 | func:0 && | | stl.h:623:36:623:47 | emplace_hint | 0 | const_iterator | @@ -1311,21 +1127,17 @@ getParameterTypeName | stl.h:628:38:628:43 | insert | 1 | func:0 | | stl.h:630:12:630:16 | erase | 0 | iterator | | stl.h:633:8:633:11 | swap | 0 | unordered_set & | -| stl.h:633:8:633:11 | swap | 0 | unordered_set, equal_to, allocator> & | | stl.h:636:37:636:41 | merge | 0 | unordered_set & | -| stl.h:636:37:636:41 | merge | 0 | unordered_set> & | | stl.h:639:12:639:15 | find | 0 | const key_type & | | stl.h:641:28:641:38 | equal_range | 0 | const key_type & | | stl.h:671:21:671:39 | basic_format_string | 0 | const func:0 & | | stl.h:671:21:671:39 | basic_format_string | 0 | const func:0 & | | stl.h:678:33:678:38 | format | 0 | format_string | | stl.h:678:33:678:38 | format | 0 | format_string | -| stl.h:678:33:678:38 | format | 1 | char *&& | | stl.h:678:33:678:38 | format | 1 | func:0 && | | stl.h:678:33:678:38 | format | 1 | func:0 && | | stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 0 | format_string | | stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 1 | func:0 && | -| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 1 | int & | | string.cpp:17:6:17:9 | sink | 0 | const char * | | string.cpp:18:6:18:9 | sink | 0 | const string & | | string.cpp:19:6:19:9 | sink | 0 | const char * | @@ -1344,7 +1156,6 @@ getParameterTypeName | structlikeclass.cpp:5:7:5:7 | operator= | 0 | StructLikeClass && | | structlikeclass.cpp:5:7:5:7 | operator= | 0 | const StructLikeClass & | | structlikeclass.cpp:8:2:8:16 | StructLikeClass | 0 | int | -| swap1.cpp:14:9:14:9 | move | 0 | Class & | | swap1.cpp:14:9:14:9 | move | 0 | func:0 & | | swap1.cpp:24:9:24:13 | Class | 0 | Class && | | swap1.cpp:25:9:25:13 | Class | 0 | const Class & | @@ -1355,7 +1166,6 @@ getParameterTypeName | swap1.cpp:53:14:53:17 | swap | 0 | Class & | | swap1.cpp:61:10:61:13 | swap | 0 | Class & | | swap1.cpp:61:10:61:13 | swap | 1 | Class & | -| swap2.cpp:14:9:14:9 | move | 0 | Class & | | swap2.cpp:14:9:14:9 | move | 0 | func:0 & | | swap2.cpp:24:9:24:13 | Class | 0 | Class && | | swap2.cpp:25:9:25:13 | Class | 0 | const Class & | @@ -1367,9 +1177,7 @@ getParameterTypeName | swap2.cpp:61:10:61:13 | swap | 0 | Class & | | swap2.cpp:61:10:61:13 | swap | 1 | Class & | | swap.h:4:20:4:23 | swap | 0 | func:0 & | -| swap.h:4:20:4:23 | swap | 0 | int & | | swap.h:4:20:4:23 | swap | 1 | func:0 & | -| swap.h:4:20:4:23 | swap | 1 | int & | | taint.cpp:4:6:4:21 | arithAssignments | 0 | int | | taint.cpp:4:6:4:21 | arithAssignments | 1 | int | | taint.cpp:22:5:22:13 | increment | 0 | int | @@ -1554,7 +1362,6 @@ getParameterTypeName | taint.cpp:783:5:783:11 | fopen_s | 2 | const char * | | taint.cpp:785:6:785:15 | fopen_test | 0 | char * | | vector.cpp:13:6:13:9 | sink | 0 | int | -| vector.cpp:14:27:14:30 | sink | 0 | vector, allocator>, allocator, allocator>>> & | | vector.cpp:14:27:14:30 | sink | 0 | vector> & | | vector.cpp:14:27:14:30 | sink | 0 | vector> & | | vector.cpp:16:6:16:37 | test_range_based_for_loop_vector | 0 | int | From 65fb895ed5a4b8702a641051bc864f9300e05659 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 Nov 2024 15:51:01 +0000 Subject: [PATCH 040/213] (Unrelated) Fix typo in class name --- java/ql/lib/semmle/code/java/security/RequestForgery.qll | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index a4e824c1cfeb..a59bacb1fe76 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -81,8 +81,10 @@ private class HostnameSanitizingPrefix extends InterestingPrefix { * A value that is the result of prepending a string that prevents any value from controlling the * host of a URL. */ -private class HostnameSantizer extends RequestForgerySanitizer { - HostnameSantizer() { this.asExpr() = any(HostnameSanitizingPrefix hsp).getAnAppendedExpression() } +private class HostnameSanitizer extends RequestForgerySanitizer { + HostnameSanitizer() { + this.asExpr() = any(HostnameSanitizingPrefix hsp).getAnAppendedExpression() + } } /** From b5fbf2e9441dfcd5b424eb1fb9f4f52c420d9c9b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 Nov 2024 13:03:09 +0000 Subject: [PATCH 041/213] Add models for third arg of getForObject No attempt to stop FPs. --- java/ql/lib/ext/org.springframework.web.client.model.yml | 3 +++ .../ql/test/query-tests/security/CWE-918/SpringSSRF.java | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/java/ql/lib/ext/org.springframework.web.client.model.yml b/java/ql/lib/ext/org.springframework.web.client.model.yml index 79a7f577c3de..90abe1df71db 100644 --- a/java/ql/lib/ext/org.springframework.web.client.model.yml +++ b/java/ql/lib/ext/org.springframework.web.client.model.yml @@ -16,6 +16,9 @@ extensions: - ["org.springframework.web.client", "RestTemplate", False, "execute", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[2]", "request-forgery", "manual"] # This is a workaround for the fact that sink model can't currently have access paths + # - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[2].ArrayElement", "request-forgery", "manual"] + # - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[2].MapValue", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "headForHeaders", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "optionsForAllow", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "patchForObject", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java b/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java index 6af4829ba024..917d8b29ac08 100644 --- a/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java +++ b/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java @@ -13,6 +13,7 @@ import java.net.http.HttpRequest; import java.net.Proxy.Type; import java.io.InputStream; +import java.util.Map; import org.apache.http.client.methods.HttpGet; import javax.servlet.ServletException; @@ -32,6 +33,14 @@ protected void doGet(HttpServletRequest request2, HttpServletResponse response2) restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, String.class); // $ SSRF restTemplate.execute(fooResourceUrl, HttpMethod.POST, null, null, "test"); // $ SSRF restTemplate.getForObject(fooResourceUrl, String.class, "test"); // $ SSRF + restTemplate.getForObject("http://{foo}", String.class, fooResourceUrl); // $ SSRF + restTemplate.getForObject("http://{foo}/a/b", String.class, fooResourceUrl); // $ SSRF + restTemplate.getForObject("http://safe.com/{foo}", String.class, fooResourceUrl); // $ SPURIOUS: SSRF // not bad - the tainted value does not affect the host + restTemplate.getForObject("http://{foo}", String.class, "safe.com", fooResourceUrl); // $ SPURIOUS: SSRF // not bad - the tainted value is unused + restTemplate.getForObject("http://{foo}", String.class, Map.of("foo", fooResourceUrl)); // $ SSRF + restTemplate.getForObject("http://safe.com/{foo}", String.class, Map.of("foo", fooResourceUrl)); // $ SPURIOUS: SSRF // not bad - the tainted value does not affect the host + restTemplate.getForObject("http://{foo}", String.class, Map.of("foo", "safe.com", "unused", fooResourceUrl)); // $ SPURIOUS: SSRF // not bad - the key for the tainted value is unused + restTemplate.getForObject("http://{foo}", String.class, Map.of("foo", "safe.com", fooResourceUrl, "unused")); // not bad - the tainted value is in a map key restTemplate.patchForObject(fooResourceUrl, new String("object"), String.class, "hi"); // $ SSRF restTemplate.postForEntity(new URI(fooResourceUrl), new String("object"), String.class); // $ SSRF restTemplate.postForLocation(fooResourceUrl, new String("object")); // $ SSRF From ba3f9d61346689ba61e69ffd17090e49f2a20fd0 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 Nov 2024 13:44:55 +0000 Subject: [PATCH 042/213] Convert model to QL --- .../org.springframework.web.client.model.yml | 3 --- .../java/frameworks/spring/SpringWebClient.qll | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/ext/org.springframework.web.client.model.yml b/java/ql/lib/ext/org.springframework.web.client.model.yml index 90abe1df71db..79a7f577c3de 100644 --- a/java/ql/lib/ext/org.springframework.web.client.model.yml +++ b/java/ql/lib/ext/org.springframework.web.client.model.yml @@ -16,9 +16,6 @@ extensions: - ["org.springframework.web.client", "RestTemplate", False, "execute", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[0]", "request-forgery", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[2]", "request-forgery", "manual"] # This is a workaround for the fact that sink model can't currently have access paths - # - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[2].ArrayElement", "request-forgery", "manual"] - # - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[2].MapValue", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "headForHeaders", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "optionsForAllow", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.springframework.web.client", "RestTemplate", False, "patchForObject", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll index 3a8d4bb084a4..d245f5ed244d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll @@ -27,3 +27,21 @@ class SpringWebClient extends Interface { this.hasQualifiedName("org.springframework.web.reactive.function.client", "WebClient") } } + +private import semmle.code.java.security.RequestForgery + +private class SpringWebClientRestTemplateGetForObject extends RequestForgerySink { + SpringWebClientRestTemplateGetForObject() { + exists(Method m, MethodCall mc, int i | + m.getDeclaringType() instanceof SpringRestTemplate and + m.hasName("getForObject") and + mc.getMethod() = m + | + // Deal with two overloads, with third parameter type `Object...` and + // `Map`. We cannot deal with mapvalue content easily but + // there is a default implicit taint read at sinks that will catch it. + this.asExpr() = mc.getArgument(i) and + i >= 2 + ) + } +} From 617f4f140e9fb4b2c64c8c8b91257c4c138512fb Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 Nov 2024 15:51:37 +0000 Subject: [PATCH 043/213] Make HostnameSanitizingPrefix public --- java/ql/lib/semmle/code/java/security/RequestForgery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index a59bacb1fe76..c670d92b5ea5 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -63,7 +63,7 @@ abstract class RequestForgerySanitizer extends DataFlow::Node { } private class PrimitiveSanitizer extends RequestForgerySanitizer instanceof SimpleTypeSanitizer { } -private class HostnameSanitizingPrefix extends InterestingPrefix { +class HostnameSanitizingPrefix extends InterestingPrefix { int offset; HostnameSanitizingPrefix() { From 7648d397f8291e99e53f804b82d516ceb3cbb661 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 Nov 2024 16:50:26 +0000 Subject: [PATCH 044/213] Improve model to remove some false positives --- .../frameworks/spring/SpringWebClient.qll | 57 +++++++++++++++++-- .../security/CWE-918/SpringSSRF.java | 6 +- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll index d245f5ed244d..79f0cb9c8bb7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll @@ -35,13 +35,58 @@ private class SpringWebClientRestTemplateGetForObject extends RequestForgerySink exists(Method m, MethodCall mc, int i | m.getDeclaringType() instanceof SpringRestTemplate and m.hasName("getForObject") and - mc.getMethod() = m + mc.getMethod() = m and + // Note that mc.getArgument(0) is modeled separately. This model is for + // arguments beyond the first two. There are two relevant overloads, one + // with third parameter type `Object...` and one with third parameter + // type `Map`. For the latter we cannot deal with mapvalue + // content easily but there is a default implicit taint read at sinks + // that will catch it. + this.asExpr() = mc.getArgument(i + 2) and + i >= 0 | - // Deal with two overloads, with third parameter type `Object...` and - // `Map`. We cannot deal with mapvalue content easily but - // there is a default implicit taint read at sinks that will catch it. - this.asExpr() = mc.getArgument(i) and - i >= 2 + // If we can determine that part of mc.getArgument(0) is a hostname + // sanitizing prefix, then we count how many placeholders occur before it + // and only consider that many arguments beyond the first two as sinks. + // For the `Map` overload this has the effect of only + // considering the map values as sinks if there is at least one + // placeholder in the URL before the hostname sanitizing prefix. + exists(HostnameSanitizingPrefix hsp | + hsp = mc.getArgument(0) and + i <= + max(int occurrenceIndex, int occurrenceOffset | + exists( + hsp.getStringValue().regexpFind("\\{[^}]*\\}", occurrenceIndex, occurrenceOffset) + ) and + occurrenceOffset < hsp.getOffset() + | + occurrenceIndex + ) + ) + or + // If we cannot determine that part of mc.getArgument(0) is a hostname + // sanitizing prefix, but it is a compile time constant and we can get + // its string value, then we count how many placeholders occur in it + // and only consider that many arguments beyond the first two as sinks. + // For the `Map` overload this has the effect of only + // considering the map values as sinks if there is at least one + // placeholder in the URL. + not mc.getArgument(0) instanceof HostnameSanitizingPrefix and + i <= + max(int occurrenceIndex | + exists( + mc.getArgument(0) + .(CompileTimeConstantExpr) + .getStringValue() + .regexpFind("\\{[^}]*\\}", occurrenceIndex, _) + ) + | + occurrenceIndex + ) + or + // If we cannot determine the string value of mc.getArgument(0), then we + // conservatively consider all arguments as sinks. + not exists(mc.getArgument(0).(CompileTimeConstantExpr).getStringValue()) ) } } diff --git a/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java b/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java index 917d8b29ac08..895c68eda69a 100644 --- a/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java +++ b/java/ql/test/query-tests/security/CWE-918/SpringSSRF.java @@ -35,10 +35,10 @@ protected void doGet(HttpServletRequest request2, HttpServletResponse response2) restTemplate.getForObject(fooResourceUrl, String.class, "test"); // $ SSRF restTemplate.getForObject("http://{foo}", String.class, fooResourceUrl); // $ SSRF restTemplate.getForObject("http://{foo}/a/b", String.class, fooResourceUrl); // $ SSRF - restTemplate.getForObject("http://safe.com/{foo}", String.class, fooResourceUrl); // $ SPURIOUS: SSRF // not bad - the tainted value does not affect the host - restTemplate.getForObject("http://{foo}", String.class, "safe.com", fooResourceUrl); // $ SPURIOUS: SSRF // not bad - the tainted value is unused + restTemplate.getForObject("http://safe.com/{foo}", String.class, fooResourceUrl); // not bad - the tainted value does not affect the host + restTemplate.getForObject("http://{foo}", String.class, "safe.com", fooResourceUrl); // not bad - the tainted value is unused restTemplate.getForObject("http://{foo}", String.class, Map.of("foo", fooResourceUrl)); // $ SSRF - restTemplate.getForObject("http://safe.com/{foo}", String.class, Map.of("foo", fooResourceUrl)); // $ SPURIOUS: SSRF // not bad - the tainted value does not affect the host + restTemplate.getForObject("http://safe.com/{foo}", String.class, Map.of("foo", fooResourceUrl)); // not bad - the tainted value does not affect the host restTemplate.getForObject("http://{foo}", String.class, Map.of("foo", "safe.com", "unused", fooResourceUrl)); // $ SPURIOUS: SSRF // not bad - the key for the tainted value is unused restTemplate.getForObject("http://{foo}", String.class, Map.of("foo", "safe.com", fooResourceUrl, "unused")); // not bad - the tainted value is in a map key restTemplate.patchForObject(fooResourceUrl, new String("object"), String.class, "hi"); // $ SSRF From 7f8a1ae941703e6e01717f5777eb6b072df852a7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 Nov 2024 17:03:41 +0000 Subject: [PATCH 045/213] Add change note --- ...4-11-28-model-resttemplate-getforobject-third-parameter.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2024-11-28-model-resttemplate-getforobject-third-parameter.md diff --git a/java/ql/lib/change-notes/2024-11-28-model-resttemplate-getforobject-third-parameter.md b/java/ql/lib/change-notes/2024-11-28-model-resttemplate-getforobject-third-parameter.md new file mode 100644 index 000000000000..4f45d19e5e8c --- /dev/null +++ b/java/ql/lib/change-notes/2024-11-28-model-resttemplate-getforobject-third-parameter.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added a sink for "Server-side request forgery" (`java/ssrf`) for the third parameter to org.springframework.web.client.RestTemplate.getForObject, when we cannot statically determine that it does not affect the host in the URL. From 2c061b0d560dd8a0fd18e6cbabacf500428ab761 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 29 Nov 2024 09:46:08 +0000 Subject: [PATCH 046/213] Add QLDoc for HostnameSanitizingPrefix --- .../lib/semmle/code/java/security/RequestForgery.qll | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index c670d92b5ea5..1f3ce61406f7 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -63,14 +63,17 @@ abstract class RequestForgerySanitizer extends DataFlow::Node { } private class PrimitiveSanitizer extends RequestForgerySanitizer instanceof SimpleTypeSanitizer { } +/** + * A string constant that contains a prefix which looks like when it is prepended to untrusted + * input, it will restrict the host or entity addressed. + * + * For example, anything containing `?` or `#`, or a slash that doesn't appear to be a protocol + * specifier (e.g. `http://` is not sanitizing), or specifically the string "/". + */ class HostnameSanitizingPrefix extends InterestingPrefix { int offset; HostnameSanitizingPrefix() { - // Matches strings that look like when prepended to untrusted input, they will restrict - // the host or entity addressed: for example, anything containing `?` or `#`, or a slash that - // doesn't appear to be a protocol specifier (e.g. `http://` is not sanitizing), or specifically - // the string "/". exists(this.getStringValue().regexpFind("([?#]|[^?#:/\\\\][/\\\\])|^/$", 0, offset)) } From 2c58279137a2f3da9b3c71e18d7966e2b9c60ad2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 3 Dec 2024 17:52:29 +0000 Subject: [PATCH 047/213] C++: Add QLDoc to 'isClassConstructedFrom' and 'isFunctionConstructedFrom'. --- .../semmle/code/cpp/dataflow/ExternalFlow.qll | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index 9496bfe98ba1..d234dbc8e3ab 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -434,12 +434,30 @@ private predicate elementSpec( summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) } +/** + * Holds if `c` is an instantiation of a class template `templateClass`, or + * holds with `c = templateClass` if `c` is not an instantiation of any class + * template. + * + * This predicate is used instead of `Class.isConstructedFrom` (which only + * holds for template instantiations) in this file to allow for uniform + * treatment of non-templated classes and class template instantiations. + */ private predicate isClassConstructedFrom(Class c, Class templateClass) { c.isConstructedFrom(templateClass) or not c.isConstructedFrom(_) and c = templateClass } +/** + * Holds if `f` is an instantiation of a function template `templateFunc`, or + * holds with `f = templateFunc` if `f` is not an instantiation of any function + * template. + * + * This predicate is used instead of `Function.isConstructedFrom` (which only + * holds for template instantiations) in this file to allow for uniform + * treatment of non-templated classes and class template instantiations. + */ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) { f.isConstructedFrom(templateFunc) or From 0c8245f727e8fc7fac2b5731dcbc5e4d7bd86fdc Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 3 Dec 2024 17:53:01 +0000 Subject: [PATCH 048/213] Update cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com> --- cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index de3df30b2836..d8f5da016330 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -25,7 +25,8 @@ typedef wchar_t* LPWSTR, *PWSTR; typedef BSTR* LPBSTR; typedef unsigned short USHORT; typedef char *LPTSTR; -struct __POSITION { int unused; };typedef __POSITION* POSITION; +struct __POSITION { int unused; }; +typedef __POSITION* POSITION; typedef WORD ATL_URL_PORT; enum ATL_URL_SCHEME{ From 593e2233f827f63161c664be9c54ec556c59ddde Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 3 Dec 2024 17:55:59 +0000 Subject: [PATCH 049/213] C++: Update test changes after 0c8245f727e8fc7fac2b5731dcbc5e4d7bd86fdc. --- .../dataflow/taint-tests/localTaint.expected | 1608 ++++++++--------- .../taint-tests/test_mad-signatures.expected | 400 ++-- 2 files changed, 1004 insertions(+), 1004 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 3f77cb77b9cf..c8a2ee98665e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -140,820 +140,820 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT | | arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | | | arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT | -| atl.cpp:32:30:32:30 | 1 | atl.cpp:32:29:32:30 | - ... | TAINT | -| atl.cpp:76:14:76:25 | call to source | atl.cpp:77:21:77:21 | x | | -| atl.cpp:77:21:77:21 | x | atl.cpp:77:21:77:22 | call to _U_STRINGorID | TAINT | -| atl.cpp:77:21:77:22 | call to _U_STRINGorID | atl.cpp:78:10:78:10 | u | | -| atl.cpp:82:17:82:43 | call to indirect_source | atl.cpp:83:21:83:21 | y | | -| atl.cpp:83:21:83:21 | y | atl.cpp:83:21:83:22 | call to _U_STRINGorID | TAINT | -| atl.cpp:83:21:83:22 | call to _U_STRINGorID | atl.cpp:84:10:84:10 | u | | -| atl.cpp:103:15:103:35 | call to indirect_source | atl.cpp:104:19:104:19 | x | | -| atl.cpp:104:19:104:19 | x | atl.cpp:104:19:104:20 | call to CA2AEX | TAINT | -| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:105:29:105:29 | a | | -| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:106:10:106:10 | a | | -| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:107:10:107:10 | a | | -| atl.cpp:104:19:104:20 | call to CA2AEX | atl.cpp:108:3:108:3 | a | | -| atl.cpp:105:29:105:29 | ref arg a | atl.cpp:106:10:106:10 | a | | -| atl.cpp:105:29:105:29 | ref arg a | atl.cpp:107:10:107:10 | a | | -| atl.cpp:105:29:105:29 | ref arg a | atl.cpp:108:3:108:3 | a | | -| atl.cpp:106:10:106:10 | a [post update] | atl.cpp:107:10:107:10 | a | | -| atl.cpp:106:10:106:10 | a [post update] | atl.cpp:108:3:108:3 | a | | -| atl.cpp:107:10:107:10 | a [post update] | atl.cpp:108:3:108:3 | a | | -| atl.cpp:111:15:111:35 | call to indirect_source | atl.cpp:112:19:112:19 | x | | -| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:113:29:113:29 | a | | -| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:114:10:114:10 | a | | -| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:115:10:115:10 | a | | -| atl.cpp:112:19:112:23 | call to CA2AEX | atl.cpp:116:3:116:3 | a | | -| atl.cpp:113:29:113:29 | ref arg a | atl.cpp:114:10:114:10 | a | | -| atl.cpp:113:29:113:29 | ref arg a | atl.cpp:115:10:115:10 | a | | -| atl.cpp:113:29:113:29 | ref arg a | atl.cpp:116:3:116:3 | a | | -| atl.cpp:114:10:114:10 | a [post update] | atl.cpp:115:10:115:10 | a | | -| atl.cpp:114:10:114:10 | a [post update] | atl.cpp:116:3:116:3 | a | | -| atl.cpp:115:10:115:10 | a [post update] | atl.cpp:116:3:116:3 | a | | -| atl.cpp:129:14:129:34 | call to indirect_source | atl.cpp:131:20:131:20 | x | | -| atl.cpp:129:14:129:34 | call to indirect_source | atl.cpp:137:20:137:20 | x | | -| atl.cpp:131:20:131:20 | x | atl.cpp:131:20:131:21 | call to CA2CAEX | TAINT | -| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:132:30:132:30 | a | | -| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:133:10:133:10 | a | | -| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:134:10:134:10 | a | | -| atl.cpp:131:20:131:21 | call to CA2CAEX | atl.cpp:135:3:135:3 | a | | -| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:138:30:138:30 | a | | -| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:139:10:139:10 | a | | -| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:140:10:140:10 | a | | -| atl.cpp:137:20:137:24 | call to CA2CAEX | atl.cpp:141:3:141:3 | a | | -| atl.cpp:155:14:155:34 | call to indirect_source | atl.cpp:157:19:157:19 | x | | -| atl.cpp:155:14:155:34 | call to indirect_source | atl.cpp:163:19:163:19 | x | | -| atl.cpp:157:19:157:19 | x | atl.cpp:157:19:157:20 | call to CA2WEX | TAINT | -| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:158:30:158:30 | a | | -| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:159:10:159:10 | a | | -| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:160:10:160:10 | a | | -| atl.cpp:157:19:157:20 | call to CA2WEX | atl.cpp:161:3:161:3 | a | | -| atl.cpp:158:30:158:30 | ref arg a | atl.cpp:159:10:159:10 | a | | -| atl.cpp:158:30:158:30 | ref arg a | atl.cpp:160:10:160:10 | a | | -| atl.cpp:158:30:158:30 | ref arg a | atl.cpp:161:3:161:3 | a | | -| atl.cpp:159:10:159:10 | a [post update] | atl.cpp:160:10:160:10 | a | | -| atl.cpp:159:10:159:10 | a [post update] | atl.cpp:161:3:161:3 | a | | -| atl.cpp:159:12:159:16 | ref arg m_psz | atl.cpp:160:12:160:16 | m_psz | | -| atl.cpp:160:10:160:10 | a [post update] | atl.cpp:161:3:161:3 | a | | -| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:164:30:164:30 | a | | -| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:165:10:165:10 | a | | -| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:166:10:166:10 | a | | -| atl.cpp:163:19:163:23 | call to CA2WEX | atl.cpp:167:3:167:3 | a | | -| atl.cpp:164:30:164:30 | ref arg a | atl.cpp:165:10:165:10 | a | | -| atl.cpp:164:30:164:30 | ref arg a | atl.cpp:166:10:166:10 | a | | -| atl.cpp:164:30:164:30 | ref arg a | atl.cpp:167:3:167:3 | a | | -| atl.cpp:165:10:165:10 | a [post update] | atl.cpp:166:10:166:10 | a | | -| atl.cpp:165:10:165:10 | a [post update] | atl.cpp:167:3:167:3 | a | | -| atl.cpp:165:12:165:16 | ref arg m_psz | atl.cpp:166:12:166:16 | m_psz | | -| atl.cpp:166:10:166:10 | a [post update] | atl.cpp:167:3:167:3 | a | | -| atl.cpp:215:11:215:21 | call to source | atl.cpp:219:11:219:11 | x | | -| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:219:5:219:5 | a | | -| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:220:10:220:10 | a | | -| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:221:5:221:5 | a | | -| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:222:10:222:10 | a | | -| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:226:15:226:15 | a | | -| atl.cpp:218:20:218:20 | call to CAtlArray | atl.cpp:241:3:241:3 | a | | -| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:220:10:220:10 | a | | -| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:221:5:221:5 | a | | -| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:222:10:222:10 | a | | -| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:226:15:226:15 | a | | -| atl.cpp:219:5:219:5 | ref arg a | atl.cpp:241:3:241:3 | a | | -| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:221:5:221:5 | a | | -| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:222:10:222:10 | a | | -| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:226:15:226:15 | a | | -| atl.cpp:220:10:220:10 | ref arg a | atl.cpp:241:3:241:3 | a | | -| atl.cpp:221:5:221:5 | ref arg a | atl.cpp:222:10:222:10 | a | | -| atl.cpp:221:5:221:5 | ref arg a | atl.cpp:226:15:226:15 | a | | -| atl.cpp:221:5:221:5 | ref arg a | atl.cpp:241:3:241:3 | a | | -| atl.cpp:222:10:222:10 | ref arg a | atl.cpp:226:15:226:15 | a | | -| atl.cpp:222:10:222:10 | ref arg a | atl.cpp:241:3:241:3 | a | | -| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:225:10:225:11 | a2 | | -| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:226:5:226:6 | a2 | | -| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:227:10:227:11 | a2 | | -| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:231:13:231:14 | a2 | | -| atl.cpp:224:20:224:21 | call to CAtlArray | atl.cpp:241:3:241:3 | a2 | | -| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:226:5:226:6 | a2 | | -| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:227:10:227:11 | a2 | | -| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:231:13:231:14 | a2 | | -| atl.cpp:225:10:225:11 | ref arg a2 | atl.cpp:241:3:241:3 | a2 | | -| atl.cpp:226:5:226:6 | ref arg a2 | atl.cpp:227:10:227:11 | a2 | | -| atl.cpp:226:5:226:6 | ref arg a2 | atl.cpp:231:13:231:14 | a2 | | -| atl.cpp:226:5:226:6 | ref arg a2 | atl.cpp:241:3:241:3 | a2 | | -| atl.cpp:227:10:227:11 | ref arg a2 | atl.cpp:231:13:231:14 | a2 | | -| atl.cpp:227:10:227:11 | ref arg a2 | atl.cpp:241:3:241:3 | a2 | | -| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:230:10:230:11 | a3 | | -| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:231:5:231:6 | a3 | | -| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:232:10:232:11 | a3 | | -| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:234:10:234:11 | a3 | | -| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:235:11:235:12 | a3 | | -| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:239:26:239:27 | a3 | | -| atl.cpp:229:20:229:21 | call to CAtlArray | atl.cpp:241:3:241:3 | a3 | | -| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:231:5:231:6 | a3 | | -| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:232:10:232:11 | a3 | | -| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:234:10:234:11 | a3 | | -| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | -| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | -| atl.cpp:230:10:230:11 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | -| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:232:10:232:11 | a3 | | -| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:234:10:234:11 | a3 | | -| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | -| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | -| atl.cpp:231:5:231:6 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | -| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:234:10:234:11 | a3 | | -| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | -| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | -| atl.cpp:232:10:232:11 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | -| atl.cpp:234:10:234:11 | ref arg a3 | atl.cpp:235:11:235:12 | a3 | | -| atl.cpp:234:10:234:11 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | -| atl.cpp:234:10:234:11 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | -| atl.cpp:235:11:235:12 | ref arg a3 | atl.cpp:239:26:239:27 | a3 | | -| atl.cpp:235:11:235:12 | ref arg a3 | atl.cpp:241:3:241:3 | a3 | | -| atl.cpp:235:14:235:20 | call to GetData | atl.cpp:235:10:235:22 | * ... | TAINT | -| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:238:10:238:11 | a4 | | -| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:239:5:239:6 | a4 | | -| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:240:10:240:11 | a4 | | -| atl.cpp:237:20:237:21 | call to CAtlArray | atl.cpp:241:3:241:3 | a4 | | -| atl.cpp:238:10:238:11 | ref arg a4 | atl.cpp:239:5:239:6 | a4 | | -| atl.cpp:238:10:238:11 | ref arg a4 | atl.cpp:240:10:240:11 | a4 | | -| atl.cpp:238:10:238:11 | ref arg a4 | atl.cpp:241:3:241:3 | a4 | | -| atl.cpp:239:5:239:6 | ref arg a4 | atl.cpp:240:10:240:11 | a4 | | -| atl.cpp:239:5:239:6 | ref arg a4 | atl.cpp:241:3:241:3 | a4 | | -| atl.cpp:239:26:239:27 | a3 | atl.cpp:239:25:239:27 | & ... | | -| atl.cpp:240:10:240:11 | ref arg a4 | atl.cpp:241:3:241:3 | a4 | | -| atl.cpp:243:20:243:21 | call to CAtlArray | atl.cpp:244:5:244:6 | a5 | | -| atl.cpp:243:20:243:21 | call to CAtlArray | atl.cpp:245:10:245:11 | a5 | | -| atl.cpp:243:20:243:21 | call to CAtlArray | atl.cpp:250:3:250:3 | a5 | | -| atl.cpp:244:5:244:6 | ref arg a5 | atl.cpp:245:10:245:11 | a5 | | -| atl.cpp:244:5:244:6 | ref arg a5 | atl.cpp:250:3:250:3 | a5 | | -| atl.cpp:245:10:245:11 | ref arg a5 | atl.cpp:250:3:250:3 | a5 | | -| atl.cpp:247:20:247:21 | call to CAtlArray | atl.cpp:248:5:248:6 | a6 | | -| atl.cpp:247:20:247:21 | call to CAtlArray | atl.cpp:249:10:249:11 | a6 | | -| atl.cpp:247:20:247:21 | call to CAtlArray | atl.cpp:250:3:250:3 | a6 | | -| atl.cpp:248:5:248:6 | ref arg a6 | atl.cpp:249:10:249:11 | a6 | | -| atl.cpp:248:5:248:6 | ref arg a6 | atl.cpp:250:3:250:3 | a6 | | -| atl.cpp:249:10:249:11 | ref arg a6 | atl.cpp:250:3:250:3 | a6 | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:299:18:299:18 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:307:19:307:19 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:316:29:316:29 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:322:21:322:21 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:330:30:330:30 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:337:31:337:31 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:342:44:342:44 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:351:18:351:18 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:359:19:359:19 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:368:29:368:29 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:374:21:374:21 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:382:30:382:30 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:389:31:389:31 | x | | -| atl.cpp:295:11:295:21 | call to source | atl.cpp:394:44:394:44 | x | | -| atl.cpp:297:24:297:25 | 10 | atl.cpp:297:24:297:26 | call to CAtlList | TAINT | -| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:298:10:298:13 | list | | -| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:299:5:299:8 | list | | -| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:300:10:300:13 | list | | -| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:303:24:303:27 | list | | -| atl.cpp:297:24:297:26 | call to CAtlList | atl.cpp:345:3:345:3 | list | | -| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:299:5:299:8 | list | | -| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:300:10:300:13 | list | | -| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:303:24:303:27 | list | | -| atl.cpp:298:10:298:13 | ref arg list | atl.cpp:345:3:345:3 | list | | -| atl.cpp:299:5:299:8 | ref arg list | atl.cpp:300:10:300:13 | list | | -| atl.cpp:299:5:299:8 | ref arg list | atl.cpp:303:24:303:27 | list | | -| atl.cpp:299:5:299:8 | ref arg list | atl.cpp:345:3:345:3 | list | | -| atl.cpp:300:10:300:13 | ref arg list | atl.cpp:303:24:303:27 | list | | -| atl.cpp:300:10:300:13 | ref arg list | atl.cpp:345:3:345:3 | list | | -| atl.cpp:302:25:302:26 | 10 | atl.cpp:302:25:302:27 | call to CAtlList | TAINT | -| atl.cpp:302:25:302:27 | call to CAtlList | atl.cpp:303:5:303:9 | list2 | | -| atl.cpp:302:25:302:27 | call to CAtlList | atl.cpp:304:10:304:14 | list2 | | -| atl.cpp:302:25:302:27 | call to CAtlList | atl.cpp:345:3:345:3 | list2 | | -| atl.cpp:303:5:303:9 | ref arg list2 | atl.cpp:304:10:304:14 | list2 | | -| atl.cpp:303:5:303:9 | ref arg list2 | atl.cpp:345:3:345:3 | list2 | | -| atl.cpp:303:24:303:27 | list | atl.cpp:303:23:303:27 | & ... | | -| atl.cpp:304:10:304:14 | ref arg list2 | atl.cpp:345:3:345:3 | list2 | | -| atl.cpp:306:25:306:26 | 10 | atl.cpp:306:25:306:27 | call to CAtlList | TAINT | -| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:307:5:307:9 | list3 | | -| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:308:10:308:14 | list3 | | -| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:311:24:311:28 | list3 | | -| atl.cpp:306:25:306:27 | call to CAtlList | atl.cpp:345:3:345:3 | list3 | | -| atl.cpp:307:5:307:9 | ref arg list3 | atl.cpp:308:10:308:14 | list3 | | -| atl.cpp:307:5:307:9 | ref arg list3 | atl.cpp:311:24:311:28 | list3 | | -| atl.cpp:307:5:307:9 | ref arg list3 | atl.cpp:345:3:345:3 | list3 | | -| atl.cpp:308:10:308:14 | ref arg list3 | atl.cpp:311:24:311:28 | list3 | | -| atl.cpp:308:10:308:14 | ref arg list3 | atl.cpp:345:3:345:3 | list3 | | -| atl.cpp:310:25:310:26 | 10 | atl.cpp:310:25:310:27 | call to CAtlList | TAINT | -| atl.cpp:310:25:310:27 | call to CAtlList | atl.cpp:311:5:311:9 | list4 | | -| atl.cpp:310:25:310:27 | call to CAtlList | atl.cpp:312:10:312:14 | list4 | | -| atl.cpp:310:25:310:27 | call to CAtlList | atl.cpp:345:3:345:3 | list4 | | -| atl.cpp:311:5:311:9 | ref arg list4 | atl.cpp:312:10:312:14 | list4 | | -| atl.cpp:311:5:311:9 | ref arg list4 | atl.cpp:345:3:345:3 | list4 | | -| atl.cpp:311:24:311:28 | list3 | atl.cpp:311:23:311:28 | & ... | | -| atl.cpp:312:10:312:14 | ref arg list4 | atl.cpp:345:3:345:3 | list4 | | -| atl.cpp:315:27:315:28 | 10 | atl.cpp:315:27:315:29 | call to CAtlList | TAINT | -| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:316:18:316:22 | list5 | | -| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:316:32:316:36 | list5 | | -| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:317:12:317:16 | list5 | | -| atl.cpp:315:27:315:29 | call to CAtlList | atl.cpp:318:5:318:5 | list5 | | -| atl.cpp:316:18:316:22 | ref arg list5 | atl.cpp:317:12:317:16 | list5 | | -| atl.cpp:316:18:316:22 | ref arg list5 | atl.cpp:318:5:318:5 | list5 | | -| atl.cpp:316:24:316:27 | call to Find | atl.cpp:317:24:317:26 | pos | | -| atl.cpp:316:32:316:36 | ref arg list5 | atl.cpp:316:18:316:22 | list5 | | -| atl.cpp:316:32:316:36 | ref arg list5 | atl.cpp:317:12:317:16 | list5 | | -| atl.cpp:316:32:316:36 | ref arg list5 | atl.cpp:318:5:318:5 | list5 | | -| atl.cpp:317:12:317:16 | ref arg list5 | atl.cpp:318:5:318:5 | list5 | | -| atl.cpp:321:27:321:28 | 10 | atl.cpp:321:27:321:29 | call to CAtlList | TAINT | -| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:322:7:322:11 | list6 | | -| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:323:18:323:22 | list6 | | -| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:324:12:324:16 | list6 | | -| atl.cpp:321:27:321:29 | call to CAtlList | atl.cpp:325:5:325:5 | list6 | | -| atl.cpp:322:7:322:11 | ref arg list6 | atl.cpp:323:18:323:22 | list6 | | -| atl.cpp:322:7:322:11 | ref arg list6 | atl.cpp:324:12:324:16 | list6 | | -| atl.cpp:322:7:322:11 | ref arg list6 | atl.cpp:325:5:325:5 | list6 | | -| atl.cpp:323:18:323:22 | ref arg list6 | atl.cpp:324:12:324:16 | list6 | | -| atl.cpp:323:18:323:22 | ref arg list6 | atl.cpp:325:5:325:5 | list6 | | -| atl.cpp:323:24:323:32 | call to FindIndex | atl.cpp:324:24:324:26 | pos | | -| atl.cpp:324:12:324:16 | ref arg list6 | atl.cpp:325:5:325:5 | list6 | | -| atl.cpp:328:27:328:28 | 10 | atl.cpp:328:27:328:29 | call to CAtlList | TAINT | -| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:329:18:329:22 | list7 | | -| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:330:7:330:11 | list7 | | -| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:331:12:331:16 | list7 | | -| atl.cpp:328:27:328:29 | call to CAtlList | atl.cpp:332:5:332:5 | list7 | | -| atl.cpp:329:18:329:22 | ref arg list7 | atl.cpp:330:7:330:11 | list7 | | -| atl.cpp:329:18:329:22 | ref arg list7 | atl.cpp:331:12:331:16 | list7 | | -| atl.cpp:329:18:329:22 | ref arg list7 | atl.cpp:332:5:332:5 | list7 | | -| atl.cpp:329:24:329:38 | call to GetTailPosition | atl.cpp:330:25:330:27 | pos | | -| atl.cpp:330:7:330:11 | ref arg list7 | atl.cpp:331:12:331:16 | list7 | | -| atl.cpp:330:7:330:11 | ref arg list7 | atl.cpp:332:5:332:5 | list7 | | -| atl.cpp:331:12:331:16 | ref arg list7 | atl.cpp:332:5:332:5 | list7 | | -| atl.cpp:335:27:335:28 | 10 | atl.cpp:335:27:335:29 | call to CAtlList | TAINT | -| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:336:18:336:22 | list8 | | -| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:337:7:337:11 | list8 | | -| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:338:12:338:16 | list8 | | -| atl.cpp:335:27:335:29 | call to CAtlList | atl.cpp:339:5:339:5 | list8 | | -| atl.cpp:336:18:336:22 | ref arg list8 | atl.cpp:337:7:337:11 | list8 | | -| atl.cpp:336:18:336:22 | ref arg list8 | atl.cpp:338:12:338:16 | list8 | | -| atl.cpp:336:18:336:22 | ref arg list8 | atl.cpp:339:5:339:5 | list8 | | -| atl.cpp:336:24:336:38 | call to GetTailPosition | atl.cpp:337:26:337:28 | pos | | -| atl.cpp:337:7:337:11 | ref arg list8 | atl.cpp:338:12:338:16 | list8 | | -| atl.cpp:337:7:337:11 | ref arg list8 | atl.cpp:339:5:339:5 | list8 | | -| atl.cpp:338:12:338:16 | ref arg list8 | atl.cpp:339:5:339:5 | list8 | | -| atl.cpp:341:27:341:28 | 10 | atl.cpp:341:27:341:29 | call to CAtlList | TAINT | -| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:342:7:342:11 | list9 | | -| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:342:19:342:23 | list9 | | -| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:343:12:343:16 | list9 | | -| atl.cpp:341:27:341:29 | call to CAtlList | atl.cpp:344:5:344:5 | list9 | | -| atl.cpp:342:7:342:11 | ref arg list9 | atl.cpp:343:12:343:16 | list9 | | -| atl.cpp:342:7:342:11 | ref arg list9 | atl.cpp:344:5:344:5 | list9 | | -| atl.cpp:342:19:342:23 | ref arg list9 | atl.cpp:342:7:342:11 | list9 | | -| atl.cpp:342:19:342:23 | ref arg list9 | atl.cpp:343:12:343:16 | list9 | | -| atl.cpp:342:19:342:23 | ref arg list9 | atl.cpp:344:5:344:5 | list9 | | -| atl.cpp:343:12:343:16 | ref arg list9 | atl.cpp:344:5:344:5 | list9 | | -| atl.cpp:349:24:349:25 | 10 | atl.cpp:349:24:349:26 | call to CAtlList | TAINT | -| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:350:10:350:13 | list | | -| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:351:5:351:8 | list | | -| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:352:10:352:13 | list | | -| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:355:24:355:27 | list | | -| atl.cpp:349:24:349:26 | call to CAtlList | atl.cpp:397:3:397:3 | list | | -| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:351:5:351:8 | list | | -| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:352:10:352:13 | list | | -| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:355:24:355:27 | list | | -| atl.cpp:350:10:350:13 | ref arg list | atl.cpp:397:3:397:3 | list | | -| atl.cpp:351:5:351:8 | ref arg list | atl.cpp:352:10:352:13 | list | | -| atl.cpp:351:5:351:8 | ref arg list | atl.cpp:355:24:355:27 | list | | -| atl.cpp:351:5:351:8 | ref arg list | atl.cpp:397:3:397:3 | list | | -| atl.cpp:352:10:352:13 | ref arg list | atl.cpp:355:24:355:27 | list | | -| atl.cpp:352:10:352:13 | ref arg list | atl.cpp:397:3:397:3 | list | | -| atl.cpp:354:25:354:26 | 10 | atl.cpp:354:25:354:27 | call to CAtlList | TAINT | -| atl.cpp:354:25:354:27 | call to CAtlList | atl.cpp:355:5:355:9 | list2 | | -| atl.cpp:354:25:354:27 | call to CAtlList | atl.cpp:356:10:356:14 | list2 | | -| atl.cpp:354:25:354:27 | call to CAtlList | atl.cpp:397:3:397:3 | list2 | | -| atl.cpp:355:5:355:9 | ref arg list2 | atl.cpp:356:10:356:14 | list2 | | -| atl.cpp:355:5:355:9 | ref arg list2 | atl.cpp:397:3:397:3 | list2 | | -| atl.cpp:355:24:355:27 | list | atl.cpp:355:23:355:27 | & ... | | -| atl.cpp:356:10:356:14 | ref arg list2 | atl.cpp:397:3:397:3 | list2 | | -| atl.cpp:358:25:358:26 | 10 | atl.cpp:358:25:358:27 | call to CAtlList | TAINT | -| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:359:5:359:9 | list3 | | -| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:360:10:360:14 | list3 | | -| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:363:24:363:28 | list3 | | -| atl.cpp:358:25:358:27 | call to CAtlList | atl.cpp:397:3:397:3 | list3 | | -| atl.cpp:359:5:359:9 | ref arg list3 | atl.cpp:360:10:360:14 | list3 | | -| atl.cpp:359:5:359:9 | ref arg list3 | atl.cpp:363:24:363:28 | list3 | | -| atl.cpp:359:5:359:9 | ref arg list3 | atl.cpp:397:3:397:3 | list3 | | -| atl.cpp:360:10:360:14 | ref arg list3 | atl.cpp:363:24:363:28 | list3 | | -| atl.cpp:360:10:360:14 | ref arg list3 | atl.cpp:397:3:397:3 | list3 | | -| atl.cpp:362:25:362:26 | 10 | atl.cpp:362:25:362:27 | call to CAtlList | TAINT | -| atl.cpp:362:25:362:27 | call to CAtlList | atl.cpp:363:5:363:9 | list4 | | -| atl.cpp:362:25:362:27 | call to CAtlList | atl.cpp:364:10:364:14 | list4 | | -| atl.cpp:362:25:362:27 | call to CAtlList | atl.cpp:397:3:397:3 | list4 | | -| atl.cpp:363:5:363:9 | ref arg list4 | atl.cpp:364:10:364:14 | list4 | | -| atl.cpp:363:5:363:9 | ref arg list4 | atl.cpp:397:3:397:3 | list4 | | -| atl.cpp:363:24:363:28 | list3 | atl.cpp:363:23:363:28 | & ... | | -| atl.cpp:364:10:364:14 | ref arg list4 | atl.cpp:397:3:397:3 | list4 | | -| atl.cpp:367:27:367:28 | 10 | atl.cpp:367:27:367:29 | call to CAtlList | TAINT | -| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:368:18:368:22 | list5 | | -| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:368:32:368:36 | list5 | | -| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:369:12:369:16 | list5 | | -| atl.cpp:367:27:367:29 | call to CAtlList | atl.cpp:370:5:370:5 | list5 | | -| atl.cpp:368:18:368:22 | ref arg list5 | atl.cpp:369:12:369:16 | list5 | | -| atl.cpp:368:18:368:22 | ref arg list5 | atl.cpp:370:5:370:5 | list5 | | -| atl.cpp:368:24:368:27 | call to Find | atl.cpp:369:24:369:26 | pos | | -| atl.cpp:368:32:368:36 | ref arg list5 | atl.cpp:368:18:368:22 | list5 | | -| atl.cpp:368:32:368:36 | ref arg list5 | atl.cpp:369:12:369:16 | list5 | | -| atl.cpp:368:32:368:36 | ref arg list5 | atl.cpp:370:5:370:5 | list5 | | -| atl.cpp:369:12:369:16 | ref arg list5 | atl.cpp:370:5:370:5 | list5 | | -| atl.cpp:373:27:373:28 | 10 | atl.cpp:373:27:373:29 | call to CAtlList | TAINT | -| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:374:7:374:11 | list6 | | -| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:375:18:375:22 | list6 | | -| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:376:12:376:16 | list6 | | -| atl.cpp:373:27:373:29 | call to CAtlList | atl.cpp:377:5:377:5 | list6 | | -| atl.cpp:374:7:374:11 | ref arg list6 | atl.cpp:375:18:375:22 | list6 | | -| atl.cpp:374:7:374:11 | ref arg list6 | atl.cpp:376:12:376:16 | list6 | | -| atl.cpp:374:7:374:11 | ref arg list6 | atl.cpp:377:5:377:5 | list6 | | -| atl.cpp:375:18:375:22 | ref arg list6 | atl.cpp:376:12:376:16 | list6 | | -| atl.cpp:375:18:375:22 | ref arg list6 | atl.cpp:377:5:377:5 | list6 | | -| atl.cpp:375:24:375:32 | call to FindIndex | atl.cpp:376:24:376:26 | pos | | -| atl.cpp:376:12:376:16 | ref arg list6 | atl.cpp:377:5:377:5 | list6 | | -| atl.cpp:380:27:380:28 | 10 | atl.cpp:380:27:380:29 | call to CAtlList | TAINT | -| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:381:18:381:22 | list7 | | -| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:382:7:382:11 | list7 | | -| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:383:12:383:16 | list7 | | -| atl.cpp:380:27:380:29 | call to CAtlList | atl.cpp:384:5:384:5 | list7 | | -| atl.cpp:381:18:381:22 | ref arg list7 | atl.cpp:382:7:382:11 | list7 | | -| atl.cpp:381:18:381:22 | ref arg list7 | atl.cpp:383:12:383:16 | list7 | | -| atl.cpp:381:18:381:22 | ref arg list7 | atl.cpp:384:5:384:5 | list7 | | -| atl.cpp:381:24:381:38 | call to GetTailPosition | atl.cpp:382:25:382:27 | pos | | -| atl.cpp:382:7:382:11 | ref arg list7 | atl.cpp:383:12:383:16 | list7 | | -| atl.cpp:382:7:382:11 | ref arg list7 | atl.cpp:384:5:384:5 | list7 | | -| atl.cpp:383:12:383:16 | ref arg list7 | atl.cpp:384:5:384:5 | list7 | | -| atl.cpp:387:27:387:28 | 10 | atl.cpp:387:27:387:29 | call to CAtlList | TAINT | -| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:388:18:388:22 | list8 | | -| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:389:7:389:11 | list8 | | -| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:390:12:390:16 | list8 | | -| atl.cpp:387:27:387:29 | call to CAtlList | atl.cpp:391:5:391:5 | list8 | | -| atl.cpp:388:18:388:22 | ref arg list8 | atl.cpp:389:7:389:11 | list8 | | -| atl.cpp:388:18:388:22 | ref arg list8 | atl.cpp:390:12:390:16 | list8 | | -| atl.cpp:388:18:388:22 | ref arg list8 | atl.cpp:391:5:391:5 | list8 | | -| atl.cpp:388:24:388:38 | call to GetTailPosition | atl.cpp:389:26:389:28 | pos | | -| atl.cpp:389:7:389:11 | ref arg list8 | atl.cpp:390:12:390:16 | list8 | | -| atl.cpp:389:7:389:11 | ref arg list8 | atl.cpp:391:5:391:5 | list8 | | -| atl.cpp:390:12:390:16 | ref arg list8 | atl.cpp:391:5:391:5 | list8 | | -| atl.cpp:393:27:393:28 | 10 | atl.cpp:393:27:393:29 | call to CAtlList | TAINT | -| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:394:7:394:11 | list9 | | -| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:394:19:394:23 | list9 | | -| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:395:12:395:16 | list9 | | -| atl.cpp:393:27:393:29 | call to CAtlList | atl.cpp:396:5:396:5 | list9 | | -| atl.cpp:394:7:394:11 | ref arg list9 | atl.cpp:395:12:395:16 | list9 | | -| atl.cpp:394:7:394:11 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | -| atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:394:7:394:11 | list9 | | -| atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:395:12:395:16 | list9 | | -| atl.cpp:394:19:394:23 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | -| atl.cpp:395:12:395:16 | ref arg list9 | atl.cpp:396:5:396:5 | list9 | | -| atl.cpp:453:21:453:33 | new | atl.cpp:454:3:454:6 | safe | | -| atl.cpp:453:21:453:33 | new | atl.cpp:455:10:455:13 | safe | | -| atl.cpp:454:3:454:6 | safe [post update] | atl.cpp:455:10:455:13 | safe | | -| atl.cpp:454:3:454:40 | ... = ... | atl.cpp:454:9:454:14 | pvData [post update] | | -| atl.cpp:454:18:454:38 | call to indirect_source | atl.cpp:454:3:454:40 | ... = ... | | -| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:461:16:461:16 | x | | -| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:468:20:468:20 | x | | -| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:472:16:472:16 | x | | -| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:480:11:480:11 | x | | -| atl.cpp:459:13:459:33 | call to indirect_source | atl.cpp:494:20:494:20 | x | | -| atl.cpp:461:16:461:16 | x | atl.cpp:461:16:461:17 | call to CComBSTR | TAINT | -| atl.cpp:461:16:461:17 | call to CComBSTR | atl.cpp:462:10:462:10 | b | | -| atl.cpp:461:16:461:17 | call to CComBSTR | atl.cpp:464:17:464:17 | b | | -| atl.cpp:461:16:461:17 | call to CComBSTR | atl.cpp:466:3:466:3 | b | | -| atl.cpp:462:10:462:10 | b [post update] | atl.cpp:464:17:464:17 | b | | -| atl.cpp:462:10:462:10 | b [post update] | atl.cpp:466:3:466:3 | b | | -| atl.cpp:462:12:462:16 | ref arg m_str | atl.cpp:465:13:465:17 | m_str | | -| atl.cpp:464:17:464:17 | b | atl.cpp:464:17:464:18 | call to CComBSTR | | -| atl.cpp:464:17:464:18 | call to CComBSTR | atl.cpp:465:10:465:11 | b2 | | -| atl.cpp:464:17:464:18 | call to CComBSTR | atl.cpp:466:3:466:3 | b2 | | -| atl.cpp:465:10:465:11 | b2 [post update] | atl.cpp:466:3:466:3 | b2 | | -| atl.cpp:468:16:468:21 | call to CComBSTR | atl.cpp:469:10:469:10 | b | | -| atl.cpp:468:16:468:21 | call to CComBSTR | atl.cpp:470:3:470:3 | b | | -| atl.cpp:469:10:469:10 | b [post update] | atl.cpp:470:3:470:3 | b | | -| atl.cpp:472:16:472:16 | x | atl.cpp:472:16:472:17 | call to CComBSTR | TAINT | -| atl.cpp:472:16:472:17 | call to CComBSTR | atl.cpp:476:11:476:11 | b | | -| atl.cpp:472:16:472:17 | call to CComBSTR | atl.cpp:512:3:512:3 | b | | -| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:475:10:475:11 | b2 | | -| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:476:5:476:6 | b2 | | -| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:477:10:477:11 | b2 | | -| atl.cpp:474:14:474:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b2 | | -| atl.cpp:475:10:475:11 | b2 [post update] | atl.cpp:476:5:476:6 | b2 | | -| atl.cpp:475:10:475:11 | b2 [post update] | atl.cpp:477:10:477:11 | b2 | | -| atl.cpp:475:10:475:11 | b2 [post update] | atl.cpp:512:3:512:3 | b2 | | -| atl.cpp:475:13:475:17 | ref arg m_str | atl.cpp:477:13:477:17 | m_str | | -| atl.cpp:476:5:476:6 | ref arg b2 | atl.cpp:477:10:477:11 | b2 | | -| atl.cpp:476:5:476:6 | ref arg b2 | atl.cpp:512:3:512:3 | b2 | | -| atl.cpp:477:10:477:11 | b2 [post update] | atl.cpp:512:3:512:3 | b2 | | -| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:480:5:480:6 | b3 | | -| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:481:10:481:11 | b3 | | -| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:482:28:482:29 | b3 | | -| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:483:13:483:14 | b3 | | -| atl.cpp:479:14:479:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b3 | | -| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:481:10:481:11 | b3 | | -| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:482:28:482:29 | b3 | | -| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:483:13:483:14 | b3 | | -| atl.cpp:480:5:480:6 | ref arg b3 | atl.cpp:512:3:512:3 | b3 | | -| atl.cpp:480:11:480:11 | x | atl.cpp:480:11:480:11 | call to CComBSTR | TAINT | -| atl.cpp:481:10:481:11 | b3 [post update] | atl.cpp:482:28:482:29 | b3 | | -| atl.cpp:481:10:481:11 | b3 [post update] | atl.cpp:483:13:483:14 | b3 | | -| atl.cpp:481:10:481:11 | b3 [post update] | atl.cpp:512:3:512:3 | b3 | | -| atl.cpp:482:28:482:29 | ref arg b3 | atl.cpp:483:13:483:14 | b3 | | -| atl.cpp:482:28:482:29 | ref arg b3 | atl.cpp:512:3:512:3 | b3 | | -| atl.cpp:483:11:483:14 | * ... | atl.cpp:483:10:483:14 | * ... | TAINT | -| atl.cpp:483:12:483:12 | call to operator& | atl.cpp:483:11:483:14 | * ... | TAINT | -| atl.cpp:483:13:483:14 | ref arg b3 | atl.cpp:512:3:512:3 | b3 | | -| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:486:5:486:6 | b4 | | -| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:487:10:487:11 | b4 | | -| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:490:19:490:20 | b4 | | -| atl.cpp:485:14:485:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b4 | | -| atl.cpp:486:5:486:6 | ref arg b4 | atl.cpp:487:10:487:11 | b4 | | -| atl.cpp:486:5:486:6 | ref arg b4 | atl.cpp:490:19:490:20 | b4 | | -| atl.cpp:486:5:486:6 | ref arg b4 | atl.cpp:512:3:512:3 | b4 | | -| atl.cpp:487:10:487:11 | b4 [post update] | atl.cpp:490:19:490:20 | b4 | | -| atl.cpp:487:10:487:11 | b4 [post update] | atl.cpp:512:3:512:3 | b4 | | -| atl.cpp:487:13:487:17 | ref arg m_str | atl.cpp:490:22:490:26 | m_str | | -| atl.cpp:489:14:489:15 | call to CComBSTR | atl.cpp:490:5:490:6 | b5 | | -| atl.cpp:489:14:489:15 | call to CComBSTR | atl.cpp:491:10:491:11 | b5 | | -| atl.cpp:489:14:489:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b5 | | -| atl.cpp:490:5:490:6 | ref arg b5 | atl.cpp:491:10:491:11 | b5 | | -| atl.cpp:490:5:490:6 | ref arg b5 | atl.cpp:512:3:512:3 | b5 | | -| atl.cpp:490:19:490:20 | b4 [post update] | atl.cpp:512:3:512:3 | b4 | | -| atl.cpp:491:10:491:11 | b5 [post update] | atl.cpp:512:3:512:3 | b5 | | -| atl.cpp:493:14:493:15 | call to CComBSTR | atl.cpp:494:5:494:6 | b6 | | -| atl.cpp:493:14:493:15 | call to CComBSTR | atl.cpp:495:10:495:11 | b6 | | -| atl.cpp:493:14:493:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b6 | | -| atl.cpp:494:5:494:6 | ref arg b6 | atl.cpp:495:10:495:11 | b6 | | -| atl.cpp:494:5:494:6 | ref arg b6 | atl.cpp:512:3:512:3 | b6 | | -| atl.cpp:495:10:495:11 | b6 [post update] | atl.cpp:512:3:512:3 | b6 | | -| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:498:5:498:6 | b7 | | -| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:499:10:499:11 | b7 | | -| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:502:19:502:20 | b7 | | -| atl.cpp:497:14:497:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b7 | | -| atl.cpp:498:5:498:6 | ref arg b7 | atl.cpp:499:10:499:11 | b7 | | -| atl.cpp:498:5:498:6 | ref arg b7 | atl.cpp:502:19:502:20 | b7 | | -| atl.cpp:498:5:498:6 | ref arg b7 | atl.cpp:512:3:512:3 | b7 | | -| atl.cpp:499:10:499:11 | b7 [post update] | atl.cpp:502:19:502:20 | b7 | | -| atl.cpp:499:10:499:11 | b7 [post update] | atl.cpp:512:3:512:3 | b7 | | -| atl.cpp:499:13:499:17 | ref arg m_str | atl.cpp:502:22:502:26 | m_str | | -| atl.cpp:501:14:501:15 | call to CComBSTR | atl.cpp:502:5:502:6 | b8 | | -| atl.cpp:501:14:501:15 | call to CComBSTR | atl.cpp:503:10:503:11 | b8 | | -| atl.cpp:501:14:501:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b8 | | -| atl.cpp:502:5:502:6 | ref arg b8 | atl.cpp:503:10:503:11 | b8 | | -| atl.cpp:502:5:502:6 | ref arg b8 | atl.cpp:512:3:512:3 | b8 | | -| atl.cpp:502:19:502:20 | b7 [post update] | atl.cpp:512:3:512:3 | b7 | | -| atl.cpp:503:10:503:11 | b8 [post update] | atl.cpp:512:3:512:3 | b8 | | -| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:507:5:507:6 | b9 | | -| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:508:5:508:6 | b9 | | -| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:511:10:511:11 | b9 | | -| atl.cpp:505:14:505:15 | call to CComBSTR | atl.cpp:512:3:512:3 | b9 | | -| atl.cpp:506:15:506:18 | safe | atl.cpp:508:21:508:24 | safe | | -| atl.cpp:506:15:506:18 | safe | atl.cpp:509:10:509:13 | safe | | -| atl.cpp:507:5:507:6 | ref arg b9 | atl.cpp:508:5:508:6 | b9 | | -| atl.cpp:507:5:507:6 | ref arg b9 | atl.cpp:511:10:511:11 | b9 | | -| atl.cpp:507:5:507:6 | ref arg b9 | atl.cpp:512:3:512:3 | b9 | | -| atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:511:10:511:11 | b9 | | -| atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:512:3:512:3 | b9 | | -| atl.cpp:508:20:508:24 | ref arg & ... | atl.cpp:508:21:508:24 | safe [inner post update] | | -| atl.cpp:508:20:508:24 | ref arg & ... | atl.cpp:509:10:509:13 | safe | | -| atl.cpp:508:21:508:24 | safe | atl.cpp:508:20:508:24 | & ... | | -| atl.cpp:511:10:511:11 | ref arg b9 | atl.cpp:512:3:512:3 | b9 | | -| atl.cpp:514:16:514:39 | call to indirect_source | atl.cpp:516:16:516:16 | w | | -| atl.cpp:514:16:514:39 | call to indirect_source | atl.cpp:520:15:520:15 | w | | -| atl.cpp:514:16:514:39 | call to indirect_source | atl.cpp:524:20:524:20 | w | | -| atl.cpp:516:16:516:16 | ref arg w | atl.cpp:520:15:520:15 | w | | -| atl.cpp:516:16:516:16 | ref arg w | atl.cpp:524:20:524:20 | w | | -| atl.cpp:516:16:516:16 | w | atl.cpp:516:16:516:17 | call to CComBSTR | TAINT | -| atl.cpp:516:16:516:17 | call to CComBSTR | atl.cpp:517:10:517:10 | b | | -| atl.cpp:516:16:516:17 | call to CComBSTR | atl.cpp:522:3:522:3 | b | | -| atl.cpp:517:10:517:10 | b [post update] | atl.cpp:522:3:522:3 | b | | -| atl.cpp:519:14:519:15 | call to CComBSTR | atl.cpp:520:5:520:6 | b2 | | -| atl.cpp:519:14:519:15 | call to CComBSTR | atl.cpp:521:10:521:11 | b2 | | -| atl.cpp:519:14:519:15 | call to CComBSTR | atl.cpp:522:3:522:3 | b2 | | -| atl.cpp:520:5:520:6 | ref arg b2 | atl.cpp:521:10:521:11 | b2 | | -| atl.cpp:520:5:520:6 | ref arg b2 | atl.cpp:522:3:522:3 | b2 | | -| atl.cpp:520:15:520:15 | ref arg w | atl.cpp:524:20:524:20 | w | | -| atl.cpp:521:10:521:11 | b2 [post update] | atl.cpp:522:3:522:3 | b2 | | -| atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:525:10:525:10 | b | | -| atl.cpp:524:16:524:21 | call to CComBSTR | atl.cpp:526:3:526:3 | b | | -| atl.cpp:525:10:525:10 | b [post update] | atl.cpp:526:3:526:3 | b | | -| atl.cpp:571:22:571:33 | call to getSafeArray | atl.cpp:572:8:572:11 | safe | | -| atl.cpp:571:22:571:33 | call to getSafeArray | atl.cpp:574:24:574:27 | safe | | -| atl.cpp:571:22:571:33 | call to getSafeArray | atl.cpp:585:11:585:14 | safe | | -| atl.cpp:572:8:572:11 | safe [post update] | atl.cpp:574:24:574:27 | safe | | -| atl.cpp:572:8:572:11 | safe [post update] | atl.cpp:585:11:585:14 | safe | | -| atl.cpp:574:24:574:27 | safe | atl.cpp:574:24:574:28 | call to CComSafeArray | TAINT | -| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:575:8:575:8 | c | | -| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:576:8:576:8 | c | | -| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:577:8:577:8 | c | | -| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:578:8:578:8 | c | | -| atl.cpp:574:24:574:28 | call to CComSafeArray | atl.cpp:579:3:579:3 | c | | -| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:576:8:576:8 | c | | -| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:577:8:577:8 | c | | -| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:578:8:578:8 | c | | -| atl.cpp:575:8:575:8 | ref arg c | atl.cpp:579:3:579:3 | c | | +| atl.cpp:33:30:33:30 | 1 | atl.cpp:33:29:33:30 | - ... | TAINT | +| atl.cpp:77:14:77:25 | call to source | atl.cpp:78:21:78:21 | x | | +| atl.cpp:78:21:78:21 | x | atl.cpp:78:21:78:22 | call to _U_STRINGorID | TAINT | +| atl.cpp:78:21:78:22 | call to _U_STRINGorID | atl.cpp:79:10:79:10 | u | | +| atl.cpp:83:17:83:43 | call to indirect_source | atl.cpp:84:21:84:21 | y | | +| atl.cpp:84:21:84:21 | y | atl.cpp:84:21:84:22 | call to _U_STRINGorID | TAINT | +| atl.cpp:84:21:84:22 | call to _U_STRINGorID | atl.cpp:85:10:85:10 | u | | +| atl.cpp:104:15:104:35 | call to indirect_source | atl.cpp:105:19:105:19 | x | | +| atl.cpp:105:19:105:19 | x | atl.cpp:105:19:105:20 | call to CA2AEX | TAINT | +| atl.cpp:105:19:105:20 | call to CA2AEX | atl.cpp:106:29:106:29 | a | | +| atl.cpp:105:19:105:20 | call to CA2AEX | atl.cpp:107:10:107:10 | a | | +| atl.cpp:105:19:105:20 | call to CA2AEX | atl.cpp:108:10:108:10 | a | | +| atl.cpp:105:19:105:20 | call to CA2AEX | atl.cpp:109:3:109:3 | a | | +| atl.cpp:106:29:106:29 | ref arg a | atl.cpp:107:10:107:10 | a | | +| atl.cpp:106:29:106:29 | ref arg a | atl.cpp:108:10:108:10 | a | | +| atl.cpp:106:29:106:29 | ref arg a | atl.cpp:109:3:109:3 | a | | +| atl.cpp:107:10:107:10 | a [post update] | atl.cpp:108:10:108:10 | a | | +| atl.cpp:107:10:107:10 | a [post update] | atl.cpp:109:3:109:3 | a | | +| atl.cpp:108:10:108:10 | a [post update] | atl.cpp:109:3:109:3 | a | | +| atl.cpp:112:15:112:35 | call to indirect_source | atl.cpp:113:19:113:19 | x | | +| atl.cpp:113:19:113:23 | call to CA2AEX | atl.cpp:114:29:114:29 | a | | +| atl.cpp:113:19:113:23 | call to CA2AEX | atl.cpp:115:10:115:10 | a | | +| atl.cpp:113:19:113:23 | call to CA2AEX | atl.cpp:116:10:116:10 | a | | +| atl.cpp:113:19:113:23 | call to CA2AEX | atl.cpp:117:3:117:3 | a | | +| atl.cpp:114:29:114:29 | ref arg a | atl.cpp:115:10:115:10 | a | | +| atl.cpp:114:29:114:29 | ref arg a | atl.cpp:116:10:116:10 | a | | +| atl.cpp:114:29:114:29 | ref arg a | atl.cpp:117:3:117:3 | a | | +| atl.cpp:115:10:115:10 | a [post update] | atl.cpp:116:10:116:10 | a | | +| atl.cpp:115:10:115:10 | a [post update] | atl.cpp:117:3:117:3 | a | | +| atl.cpp:116:10:116:10 | a [post update] | atl.cpp:117:3:117:3 | a | | +| atl.cpp:130:14:130:34 | call to indirect_source | atl.cpp:132:20:132:20 | x | | +| atl.cpp:130:14:130:34 | call to indirect_source | atl.cpp:138:20:138:20 | x | | +| atl.cpp:132:20:132:20 | x | atl.cpp:132:20:132:21 | call to CA2CAEX | TAINT | +| atl.cpp:132:20:132:21 | call to CA2CAEX | atl.cpp:133:30:133:30 | a | | +| atl.cpp:132:20:132:21 | call to CA2CAEX | atl.cpp:134:10:134:10 | a | | +| atl.cpp:132:20:132:21 | call to CA2CAEX | atl.cpp:135:10:135:10 | a | | +| atl.cpp:132:20:132:21 | call to CA2CAEX | atl.cpp:136:3:136:3 | a | | +| atl.cpp:138:20:138:24 | call to CA2CAEX | atl.cpp:139:30:139:30 | a | | +| atl.cpp:138:20:138:24 | call to CA2CAEX | atl.cpp:140:10:140:10 | a | | +| atl.cpp:138:20:138:24 | call to CA2CAEX | atl.cpp:141:10:141:10 | a | | +| atl.cpp:138:20:138:24 | call to CA2CAEX | atl.cpp:142:3:142:3 | a | | +| atl.cpp:156:14:156:34 | call to indirect_source | atl.cpp:158:19:158:19 | x | | +| atl.cpp:156:14:156:34 | call to indirect_source | atl.cpp:164:19:164:19 | x | | +| atl.cpp:158:19:158:19 | x | atl.cpp:158:19:158:20 | call to CA2WEX | TAINT | +| atl.cpp:158:19:158:20 | call to CA2WEX | atl.cpp:159:30:159:30 | a | | +| atl.cpp:158:19:158:20 | call to CA2WEX | atl.cpp:160:10:160:10 | a | | +| atl.cpp:158:19:158:20 | call to CA2WEX | atl.cpp:161:10:161:10 | a | | +| atl.cpp:158:19:158:20 | call to CA2WEX | atl.cpp:162:3:162:3 | a | | +| atl.cpp:159:30:159:30 | ref arg a | atl.cpp:160:10:160:10 | a | | +| atl.cpp:159:30:159:30 | ref arg a | atl.cpp:161:10:161:10 | a | | +| atl.cpp:159:30:159:30 | ref arg a | atl.cpp:162:3:162:3 | a | | +| atl.cpp:160:10:160:10 | a [post update] | atl.cpp:161:10:161:10 | a | | +| atl.cpp:160:10:160:10 | a [post update] | atl.cpp:162:3:162:3 | a | | +| atl.cpp:160:12:160:16 | ref arg m_psz | atl.cpp:161:12:161:16 | m_psz | | +| atl.cpp:161:10:161:10 | a [post update] | atl.cpp:162:3:162:3 | a | | +| atl.cpp:164:19:164:23 | call to CA2WEX | atl.cpp:165:30:165:30 | a | | +| atl.cpp:164:19:164:23 | call to CA2WEX | atl.cpp:166:10:166:10 | a | | +| atl.cpp:164:19:164:23 | call to CA2WEX | atl.cpp:167:10:167:10 | a | | +| atl.cpp:164:19:164:23 | call to CA2WEX | atl.cpp:168:3:168:3 | a | | +| atl.cpp:165:30:165:30 | ref arg a | atl.cpp:166:10:166:10 | a | | +| atl.cpp:165:30:165:30 | ref arg a | atl.cpp:167:10:167:10 | a | | +| atl.cpp:165:30:165:30 | ref arg a | atl.cpp:168:3:168:3 | a | | +| atl.cpp:166:10:166:10 | a [post update] | atl.cpp:167:10:167:10 | a | | +| atl.cpp:166:10:166:10 | a [post update] | atl.cpp:168:3:168:3 | a | | +| atl.cpp:166:12:166:16 | ref arg m_psz | atl.cpp:167:12:167:16 | m_psz | | +| atl.cpp:167:10:167:10 | a [post update] | atl.cpp:168:3:168:3 | a | | +| atl.cpp:216:11:216:21 | call to source | atl.cpp:220:11:220:11 | x | | +| atl.cpp:219:20:219:20 | call to CAtlArray | atl.cpp:220:5:220:5 | a | | +| atl.cpp:219:20:219:20 | call to CAtlArray | atl.cpp:221:10:221:10 | a | | +| atl.cpp:219:20:219:20 | call to CAtlArray | atl.cpp:222:5:222:5 | a | | +| atl.cpp:219:20:219:20 | call to CAtlArray | atl.cpp:223:10:223:10 | a | | +| atl.cpp:219:20:219:20 | call to CAtlArray | atl.cpp:227:15:227:15 | a | | +| atl.cpp:219:20:219:20 | call to CAtlArray | atl.cpp:242:3:242:3 | a | | +| atl.cpp:220:5:220:5 | ref arg a | atl.cpp:221:10:221:10 | a | | +| atl.cpp:220:5:220:5 | ref arg a | atl.cpp:222:5:222:5 | a | | +| atl.cpp:220:5:220:5 | ref arg a | atl.cpp:223:10:223:10 | a | | +| atl.cpp:220:5:220:5 | ref arg a | atl.cpp:227:15:227:15 | a | | +| atl.cpp:220:5:220:5 | ref arg a | atl.cpp:242:3:242:3 | a | | +| atl.cpp:221:10:221:10 | ref arg a | atl.cpp:222:5:222:5 | a | | +| atl.cpp:221:10:221:10 | ref arg a | atl.cpp:223:10:223:10 | a | | +| atl.cpp:221:10:221:10 | ref arg a | atl.cpp:227:15:227:15 | a | | +| atl.cpp:221:10:221:10 | ref arg a | atl.cpp:242:3:242:3 | a | | +| atl.cpp:222:5:222:5 | ref arg a | atl.cpp:223:10:223:10 | a | | +| atl.cpp:222:5:222:5 | ref arg a | atl.cpp:227:15:227:15 | a | | +| atl.cpp:222:5:222:5 | ref arg a | atl.cpp:242:3:242:3 | a | | +| atl.cpp:223:10:223:10 | ref arg a | atl.cpp:227:15:227:15 | a | | +| atl.cpp:223:10:223:10 | ref arg a | atl.cpp:242:3:242:3 | a | | +| atl.cpp:225:20:225:21 | call to CAtlArray | atl.cpp:226:10:226:11 | a2 | | +| atl.cpp:225:20:225:21 | call to CAtlArray | atl.cpp:227:5:227:6 | a2 | | +| atl.cpp:225:20:225:21 | call to CAtlArray | atl.cpp:228:10:228:11 | a2 | | +| atl.cpp:225:20:225:21 | call to CAtlArray | atl.cpp:232:13:232:14 | a2 | | +| atl.cpp:225:20:225:21 | call to CAtlArray | atl.cpp:242:3:242:3 | a2 | | +| atl.cpp:226:10:226:11 | ref arg a2 | atl.cpp:227:5:227:6 | a2 | | +| atl.cpp:226:10:226:11 | ref arg a2 | atl.cpp:228:10:228:11 | a2 | | +| atl.cpp:226:10:226:11 | ref arg a2 | atl.cpp:232:13:232:14 | a2 | | +| atl.cpp:226:10:226:11 | ref arg a2 | atl.cpp:242:3:242:3 | a2 | | +| atl.cpp:227:5:227:6 | ref arg a2 | atl.cpp:228:10:228:11 | a2 | | +| atl.cpp:227:5:227:6 | ref arg a2 | atl.cpp:232:13:232:14 | a2 | | +| atl.cpp:227:5:227:6 | ref arg a2 | atl.cpp:242:3:242:3 | a2 | | +| atl.cpp:228:10:228:11 | ref arg a2 | atl.cpp:232:13:232:14 | a2 | | +| atl.cpp:228:10:228:11 | ref arg a2 | atl.cpp:242:3:242:3 | a2 | | +| atl.cpp:230:20:230:21 | call to CAtlArray | atl.cpp:231:10:231:11 | a3 | | +| atl.cpp:230:20:230:21 | call to CAtlArray | atl.cpp:232:5:232:6 | a3 | | +| atl.cpp:230:20:230:21 | call to CAtlArray | atl.cpp:233:10:233:11 | a3 | | +| atl.cpp:230:20:230:21 | call to CAtlArray | atl.cpp:235:10:235:11 | a3 | | +| atl.cpp:230:20:230:21 | call to CAtlArray | atl.cpp:236:11:236:12 | a3 | | +| atl.cpp:230:20:230:21 | call to CAtlArray | atl.cpp:240:26:240:27 | a3 | | +| atl.cpp:230:20:230:21 | call to CAtlArray | atl.cpp:242:3:242:3 | a3 | | +| atl.cpp:231:10:231:11 | ref arg a3 | atl.cpp:232:5:232:6 | a3 | | +| atl.cpp:231:10:231:11 | ref arg a3 | atl.cpp:233:10:233:11 | a3 | | +| atl.cpp:231:10:231:11 | ref arg a3 | atl.cpp:235:10:235:11 | a3 | | +| atl.cpp:231:10:231:11 | ref arg a3 | atl.cpp:236:11:236:12 | a3 | | +| atl.cpp:231:10:231:11 | ref arg a3 | atl.cpp:240:26:240:27 | a3 | | +| atl.cpp:231:10:231:11 | ref arg a3 | atl.cpp:242:3:242:3 | a3 | | +| atl.cpp:232:5:232:6 | ref arg a3 | atl.cpp:233:10:233:11 | a3 | | +| atl.cpp:232:5:232:6 | ref arg a3 | atl.cpp:235:10:235:11 | a3 | | +| atl.cpp:232:5:232:6 | ref arg a3 | atl.cpp:236:11:236:12 | a3 | | +| atl.cpp:232:5:232:6 | ref arg a3 | atl.cpp:240:26:240:27 | a3 | | +| atl.cpp:232:5:232:6 | ref arg a3 | atl.cpp:242:3:242:3 | a3 | | +| atl.cpp:233:10:233:11 | ref arg a3 | atl.cpp:235:10:235:11 | a3 | | +| atl.cpp:233:10:233:11 | ref arg a3 | atl.cpp:236:11:236:12 | a3 | | +| atl.cpp:233:10:233:11 | ref arg a3 | atl.cpp:240:26:240:27 | a3 | | +| atl.cpp:233:10:233:11 | ref arg a3 | atl.cpp:242:3:242:3 | a3 | | +| atl.cpp:235:10:235:11 | ref arg a3 | atl.cpp:236:11:236:12 | a3 | | +| atl.cpp:235:10:235:11 | ref arg a3 | atl.cpp:240:26:240:27 | a3 | | +| atl.cpp:235:10:235:11 | ref arg a3 | atl.cpp:242:3:242:3 | a3 | | +| atl.cpp:236:11:236:12 | ref arg a3 | atl.cpp:240:26:240:27 | a3 | | +| atl.cpp:236:11:236:12 | ref arg a3 | atl.cpp:242:3:242:3 | a3 | | +| atl.cpp:236:14:236:20 | call to GetData | atl.cpp:236:10:236:22 | * ... | TAINT | +| atl.cpp:238:20:238:21 | call to CAtlArray | atl.cpp:239:10:239:11 | a4 | | +| atl.cpp:238:20:238:21 | call to CAtlArray | atl.cpp:240:5:240:6 | a4 | | +| atl.cpp:238:20:238:21 | call to CAtlArray | atl.cpp:241:10:241:11 | a4 | | +| atl.cpp:238:20:238:21 | call to CAtlArray | atl.cpp:242:3:242:3 | a4 | | +| atl.cpp:239:10:239:11 | ref arg a4 | atl.cpp:240:5:240:6 | a4 | | +| atl.cpp:239:10:239:11 | ref arg a4 | atl.cpp:241:10:241:11 | a4 | | +| atl.cpp:239:10:239:11 | ref arg a4 | atl.cpp:242:3:242:3 | a4 | | +| atl.cpp:240:5:240:6 | ref arg a4 | atl.cpp:241:10:241:11 | a4 | | +| atl.cpp:240:5:240:6 | ref arg a4 | atl.cpp:242:3:242:3 | a4 | | +| atl.cpp:240:26:240:27 | a3 | atl.cpp:240:25:240:27 | & ... | | +| atl.cpp:241:10:241:11 | ref arg a4 | atl.cpp:242:3:242:3 | a4 | | +| atl.cpp:244:20:244:21 | call to CAtlArray | atl.cpp:245:5:245:6 | a5 | | +| atl.cpp:244:20:244:21 | call to CAtlArray | atl.cpp:246:10:246:11 | a5 | | +| atl.cpp:244:20:244:21 | call to CAtlArray | atl.cpp:251:3:251:3 | a5 | | +| atl.cpp:245:5:245:6 | ref arg a5 | atl.cpp:246:10:246:11 | a5 | | +| atl.cpp:245:5:245:6 | ref arg a5 | atl.cpp:251:3:251:3 | a5 | | +| atl.cpp:246:10:246:11 | ref arg a5 | atl.cpp:251:3:251:3 | a5 | | +| atl.cpp:248:20:248:21 | call to CAtlArray | atl.cpp:249:5:249:6 | a6 | | +| atl.cpp:248:20:248:21 | call to CAtlArray | atl.cpp:250:10:250:11 | a6 | | +| atl.cpp:248:20:248:21 | call to CAtlArray | atl.cpp:251:3:251:3 | a6 | | +| atl.cpp:249:5:249:6 | ref arg a6 | atl.cpp:250:10:250:11 | a6 | | +| atl.cpp:249:5:249:6 | ref arg a6 | atl.cpp:251:3:251:3 | a6 | | +| atl.cpp:250:10:250:11 | ref arg a6 | atl.cpp:251:3:251:3 | a6 | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:300:18:300:18 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:308:19:308:19 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:317:29:317:29 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:323:21:323:21 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:331:30:331:30 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:338:31:338:31 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:343:44:343:44 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:352:18:352:18 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:360:19:360:19 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:369:29:369:29 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:375:21:375:21 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:383:30:383:30 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:390:31:390:31 | x | | +| atl.cpp:296:11:296:21 | call to source | atl.cpp:395:44:395:44 | x | | +| atl.cpp:298:24:298:25 | 10 | atl.cpp:298:24:298:26 | call to CAtlList | TAINT | +| atl.cpp:298:24:298:26 | call to CAtlList | atl.cpp:299:10:299:13 | list | | +| atl.cpp:298:24:298:26 | call to CAtlList | atl.cpp:300:5:300:8 | list | | +| atl.cpp:298:24:298:26 | call to CAtlList | atl.cpp:301:10:301:13 | list | | +| atl.cpp:298:24:298:26 | call to CAtlList | atl.cpp:304:24:304:27 | list | | +| atl.cpp:298:24:298:26 | call to CAtlList | atl.cpp:346:3:346:3 | list | | +| atl.cpp:299:10:299:13 | ref arg list | atl.cpp:300:5:300:8 | list | | +| atl.cpp:299:10:299:13 | ref arg list | atl.cpp:301:10:301:13 | list | | +| atl.cpp:299:10:299:13 | ref arg list | atl.cpp:304:24:304:27 | list | | +| atl.cpp:299:10:299:13 | ref arg list | atl.cpp:346:3:346:3 | list | | +| atl.cpp:300:5:300:8 | ref arg list | atl.cpp:301:10:301:13 | list | | +| atl.cpp:300:5:300:8 | ref arg list | atl.cpp:304:24:304:27 | list | | +| atl.cpp:300:5:300:8 | ref arg list | atl.cpp:346:3:346:3 | list | | +| atl.cpp:301:10:301:13 | ref arg list | atl.cpp:304:24:304:27 | list | | +| atl.cpp:301:10:301:13 | ref arg list | atl.cpp:346:3:346:3 | list | | +| atl.cpp:303:25:303:26 | 10 | atl.cpp:303:25:303:27 | call to CAtlList | TAINT | +| atl.cpp:303:25:303:27 | call to CAtlList | atl.cpp:304:5:304:9 | list2 | | +| atl.cpp:303:25:303:27 | call to CAtlList | atl.cpp:305:10:305:14 | list2 | | +| atl.cpp:303:25:303:27 | call to CAtlList | atl.cpp:346:3:346:3 | list2 | | +| atl.cpp:304:5:304:9 | ref arg list2 | atl.cpp:305:10:305:14 | list2 | | +| atl.cpp:304:5:304:9 | ref arg list2 | atl.cpp:346:3:346:3 | list2 | | +| atl.cpp:304:24:304:27 | list | atl.cpp:304:23:304:27 | & ... | | +| atl.cpp:305:10:305:14 | ref arg list2 | atl.cpp:346:3:346:3 | list2 | | +| atl.cpp:307:25:307:26 | 10 | atl.cpp:307:25:307:27 | call to CAtlList | TAINT | +| atl.cpp:307:25:307:27 | call to CAtlList | atl.cpp:308:5:308:9 | list3 | | +| atl.cpp:307:25:307:27 | call to CAtlList | atl.cpp:309:10:309:14 | list3 | | +| atl.cpp:307:25:307:27 | call to CAtlList | atl.cpp:312:24:312:28 | list3 | | +| atl.cpp:307:25:307:27 | call to CAtlList | atl.cpp:346:3:346:3 | list3 | | +| atl.cpp:308:5:308:9 | ref arg list3 | atl.cpp:309:10:309:14 | list3 | | +| atl.cpp:308:5:308:9 | ref arg list3 | atl.cpp:312:24:312:28 | list3 | | +| atl.cpp:308:5:308:9 | ref arg list3 | atl.cpp:346:3:346:3 | list3 | | +| atl.cpp:309:10:309:14 | ref arg list3 | atl.cpp:312:24:312:28 | list3 | | +| atl.cpp:309:10:309:14 | ref arg list3 | atl.cpp:346:3:346:3 | list3 | | +| atl.cpp:311:25:311:26 | 10 | atl.cpp:311:25:311:27 | call to CAtlList | TAINT | +| atl.cpp:311:25:311:27 | call to CAtlList | atl.cpp:312:5:312:9 | list4 | | +| atl.cpp:311:25:311:27 | call to CAtlList | atl.cpp:313:10:313:14 | list4 | | +| atl.cpp:311:25:311:27 | call to CAtlList | atl.cpp:346:3:346:3 | list4 | | +| atl.cpp:312:5:312:9 | ref arg list4 | atl.cpp:313:10:313:14 | list4 | | +| atl.cpp:312:5:312:9 | ref arg list4 | atl.cpp:346:3:346:3 | list4 | | +| atl.cpp:312:24:312:28 | list3 | atl.cpp:312:23:312:28 | & ... | | +| atl.cpp:313:10:313:14 | ref arg list4 | atl.cpp:346:3:346:3 | list4 | | +| atl.cpp:316:27:316:28 | 10 | atl.cpp:316:27:316:29 | call to CAtlList | TAINT | +| atl.cpp:316:27:316:29 | call to CAtlList | atl.cpp:317:18:317:22 | list5 | | +| atl.cpp:316:27:316:29 | call to CAtlList | atl.cpp:317:32:317:36 | list5 | | +| atl.cpp:316:27:316:29 | call to CAtlList | atl.cpp:318:12:318:16 | list5 | | +| atl.cpp:316:27:316:29 | call to CAtlList | atl.cpp:319:5:319:5 | list5 | | +| atl.cpp:317:18:317:22 | ref arg list5 | atl.cpp:318:12:318:16 | list5 | | +| atl.cpp:317:18:317:22 | ref arg list5 | atl.cpp:319:5:319:5 | list5 | | +| atl.cpp:317:24:317:27 | call to Find | atl.cpp:318:24:318:26 | pos | | +| atl.cpp:317:32:317:36 | ref arg list5 | atl.cpp:317:18:317:22 | list5 | | +| atl.cpp:317:32:317:36 | ref arg list5 | atl.cpp:318:12:318:16 | list5 | | +| atl.cpp:317:32:317:36 | ref arg list5 | atl.cpp:319:5:319:5 | list5 | | +| atl.cpp:318:12:318:16 | ref arg list5 | atl.cpp:319:5:319:5 | list5 | | +| atl.cpp:322:27:322:28 | 10 | atl.cpp:322:27:322:29 | call to CAtlList | TAINT | +| atl.cpp:322:27:322:29 | call to CAtlList | atl.cpp:323:7:323:11 | list6 | | +| atl.cpp:322:27:322:29 | call to CAtlList | atl.cpp:324:18:324:22 | list6 | | +| atl.cpp:322:27:322:29 | call to CAtlList | atl.cpp:325:12:325:16 | list6 | | +| atl.cpp:322:27:322:29 | call to CAtlList | atl.cpp:326:5:326:5 | list6 | | +| atl.cpp:323:7:323:11 | ref arg list6 | atl.cpp:324:18:324:22 | list6 | | +| atl.cpp:323:7:323:11 | ref arg list6 | atl.cpp:325:12:325:16 | list6 | | +| atl.cpp:323:7:323:11 | ref arg list6 | atl.cpp:326:5:326:5 | list6 | | +| atl.cpp:324:18:324:22 | ref arg list6 | atl.cpp:325:12:325:16 | list6 | | +| atl.cpp:324:18:324:22 | ref arg list6 | atl.cpp:326:5:326:5 | list6 | | +| atl.cpp:324:24:324:32 | call to FindIndex | atl.cpp:325:24:325:26 | pos | | +| atl.cpp:325:12:325:16 | ref arg list6 | atl.cpp:326:5:326:5 | list6 | | +| atl.cpp:329:27:329:28 | 10 | atl.cpp:329:27:329:29 | call to CAtlList | TAINT | +| atl.cpp:329:27:329:29 | call to CAtlList | atl.cpp:330:18:330:22 | list7 | | +| atl.cpp:329:27:329:29 | call to CAtlList | atl.cpp:331:7:331:11 | list7 | | +| atl.cpp:329:27:329:29 | call to CAtlList | atl.cpp:332:12:332:16 | list7 | | +| atl.cpp:329:27:329:29 | call to CAtlList | atl.cpp:333:5:333:5 | list7 | | +| atl.cpp:330:18:330:22 | ref arg list7 | atl.cpp:331:7:331:11 | list7 | | +| atl.cpp:330:18:330:22 | ref arg list7 | atl.cpp:332:12:332:16 | list7 | | +| atl.cpp:330:18:330:22 | ref arg list7 | atl.cpp:333:5:333:5 | list7 | | +| atl.cpp:330:24:330:38 | call to GetTailPosition | atl.cpp:331:25:331:27 | pos | | +| atl.cpp:331:7:331:11 | ref arg list7 | atl.cpp:332:12:332:16 | list7 | | +| atl.cpp:331:7:331:11 | ref arg list7 | atl.cpp:333:5:333:5 | list7 | | +| atl.cpp:332:12:332:16 | ref arg list7 | atl.cpp:333:5:333:5 | list7 | | +| atl.cpp:336:27:336:28 | 10 | atl.cpp:336:27:336:29 | call to CAtlList | TAINT | +| atl.cpp:336:27:336:29 | call to CAtlList | atl.cpp:337:18:337:22 | list8 | | +| atl.cpp:336:27:336:29 | call to CAtlList | atl.cpp:338:7:338:11 | list8 | | +| atl.cpp:336:27:336:29 | call to CAtlList | atl.cpp:339:12:339:16 | list8 | | +| atl.cpp:336:27:336:29 | call to CAtlList | atl.cpp:340:5:340:5 | list8 | | +| atl.cpp:337:18:337:22 | ref arg list8 | atl.cpp:338:7:338:11 | list8 | | +| atl.cpp:337:18:337:22 | ref arg list8 | atl.cpp:339:12:339:16 | list8 | | +| atl.cpp:337:18:337:22 | ref arg list8 | atl.cpp:340:5:340:5 | list8 | | +| atl.cpp:337:24:337:38 | call to GetTailPosition | atl.cpp:338:26:338:28 | pos | | +| atl.cpp:338:7:338:11 | ref arg list8 | atl.cpp:339:12:339:16 | list8 | | +| atl.cpp:338:7:338:11 | ref arg list8 | atl.cpp:340:5:340:5 | list8 | | +| atl.cpp:339:12:339:16 | ref arg list8 | atl.cpp:340:5:340:5 | list8 | | +| atl.cpp:342:27:342:28 | 10 | atl.cpp:342:27:342:29 | call to CAtlList | TAINT | +| atl.cpp:342:27:342:29 | call to CAtlList | atl.cpp:343:7:343:11 | list9 | | +| atl.cpp:342:27:342:29 | call to CAtlList | atl.cpp:343:19:343:23 | list9 | | +| atl.cpp:342:27:342:29 | call to CAtlList | atl.cpp:344:12:344:16 | list9 | | +| atl.cpp:342:27:342:29 | call to CAtlList | atl.cpp:345:5:345:5 | list9 | | +| atl.cpp:343:7:343:11 | ref arg list9 | atl.cpp:344:12:344:16 | list9 | | +| atl.cpp:343:7:343:11 | ref arg list9 | atl.cpp:345:5:345:5 | list9 | | +| atl.cpp:343:19:343:23 | ref arg list9 | atl.cpp:343:7:343:11 | list9 | | +| atl.cpp:343:19:343:23 | ref arg list9 | atl.cpp:344:12:344:16 | list9 | | +| atl.cpp:343:19:343:23 | ref arg list9 | atl.cpp:345:5:345:5 | list9 | | +| atl.cpp:344:12:344:16 | ref arg list9 | atl.cpp:345:5:345:5 | list9 | | +| atl.cpp:350:24:350:25 | 10 | atl.cpp:350:24:350:26 | call to CAtlList | TAINT | +| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:351:10:351:13 | list | | +| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:352:5:352:8 | list | | +| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:353:10:353:13 | list | | +| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:356:24:356:27 | list | | +| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:398:3:398:3 | list | | +| atl.cpp:351:10:351:13 | ref arg list | atl.cpp:352:5:352:8 | list | | +| atl.cpp:351:10:351:13 | ref arg list | atl.cpp:353:10:353:13 | list | | +| atl.cpp:351:10:351:13 | ref arg list | atl.cpp:356:24:356:27 | list | | +| atl.cpp:351:10:351:13 | ref arg list | atl.cpp:398:3:398:3 | list | | +| atl.cpp:352:5:352:8 | ref arg list | atl.cpp:353:10:353:13 | list | | +| atl.cpp:352:5:352:8 | ref arg list | atl.cpp:356:24:356:27 | list | | +| atl.cpp:352:5:352:8 | ref arg list | atl.cpp:398:3:398:3 | list | | +| atl.cpp:353:10:353:13 | ref arg list | atl.cpp:356:24:356:27 | list | | +| atl.cpp:353:10:353:13 | ref arg list | atl.cpp:398:3:398:3 | list | | +| atl.cpp:355:25:355:26 | 10 | atl.cpp:355:25:355:27 | call to CAtlList | TAINT | +| atl.cpp:355:25:355:27 | call to CAtlList | atl.cpp:356:5:356:9 | list2 | | +| atl.cpp:355:25:355:27 | call to CAtlList | atl.cpp:357:10:357:14 | list2 | | +| atl.cpp:355:25:355:27 | call to CAtlList | atl.cpp:398:3:398:3 | list2 | | +| atl.cpp:356:5:356:9 | ref arg list2 | atl.cpp:357:10:357:14 | list2 | | +| atl.cpp:356:5:356:9 | ref arg list2 | atl.cpp:398:3:398:3 | list2 | | +| atl.cpp:356:24:356:27 | list | atl.cpp:356:23:356:27 | & ... | | +| atl.cpp:357:10:357:14 | ref arg list2 | atl.cpp:398:3:398:3 | list2 | | +| atl.cpp:359:25:359:26 | 10 | atl.cpp:359:25:359:27 | call to CAtlList | TAINT | +| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:360:5:360:9 | list3 | | +| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:361:10:361:14 | list3 | | +| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:364:24:364:28 | list3 | | +| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:398:3:398:3 | list3 | | +| atl.cpp:360:5:360:9 | ref arg list3 | atl.cpp:361:10:361:14 | list3 | | +| atl.cpp:360:5:360:9 | ref arg list3 | atl.cpp:364:24:364:28 | list3 | | +| atl.cpp:360:5:360:9 | ref arg list3 | atl.cpp:398:3:398:3 | list3 | | +| atl.cpp:361:10:361:14 | ref arg list3 | atl.cpp:364:24:364:28 | list3 | | +| atl.cpp:361:10:361:14 | ref arg list3 | atl.cpp:398:3:398:3 | list3 | | +| atl.cpp:363:25:363:26 | 10 | atl.cpp:363:25:363:27 | call to CAtlList | TAINT | +| atl.cpp:363:25:363:27 | call to CAtlList | atl.cpp:364:5:364:9 | list4 | | +| atl.cpp:363:25:363:27 | call to CAtlList | atl.cpp:365:10:365:14 | list4 | | +| atl.cpp:363:25:363:27 | call to CAtlList | atl.cpp:398:3:398:3 | list4 | | +| atl.cpp:364:5:364:9 | ref arg list4 | atl.cpp:365:10:365:14 | list4 | | +| atl.cpp:364:5:364:9 | ref arg list4 | atl.cpp:398:3:398:3 | list4 | | +| atl.cpp:364:24:364:28 | list3 | atl.cpp:364:23:364:28 | & ... | | +| atl.cpp:365:10:365:14 | ref arg list4 | atl.cpp:398:3:398:3 | list4 | | +| atl.cpp:368:27:368:28 | 10 | atl.cpp:368:27:368:29 | call to CAtlList | TAINT | +| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:369:18:369:22 | list5 | | +| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:369:32:369:36 | list5 | | +| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:370:12:370:16 | list5 | | +| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:371:5:371:5 | list5 | | +| atl.cpp:369:18:369:22 | ref arg list5 | atl.cpp:370:12:370:16 | list5 | | +| atl.cpp:369:18:369:22 | ref arg list5 | atl.cpp:371:5:371:5 | list5 | | +| atl.cpp:369:24:369:27 | call to Find | atl.cpp:370:24:370:26 | pos | | +| atl.cpp:369:32:369:36 | ref arg list5 | atl.cpp:369:18:369:22 | list5 | | +| atl.cpp:369:32:369:36 | ref arg list5 | atl.cpp:370:12:370:16 | list5 | | +| atl.cpp:369:32:369:36 | ref arg list5 | atl.cpp:371:5:371:5 | list5 | | +| atl.cpp:370:12:370:16 | ref arg list5 | atl.cpp:371:5:371:5 | list5 | | +| atl.cpp:374:27:374:28 | 10 | atl.cpp:374:27:374:29 | call to CAtlList | TAINT | +| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:375:7:375:11 | list6 | | +| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:376:18:376:22 | list6 | | +| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:377:12:377:16 | list6 | | +| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:378:5:378:5 | list6 | | +| atl.cpp:375:7:375:11 | ref arg list6 | atl.cpp:376:18:376:22 | list6 | | +| atl.cpp:375:7:375:11 | ref arg list6 | atl.cpp:377:12:377:16 | list6 | | +| atl.cpp:375:7:375:11 | ref arg list6 | atl.cpp:378:5:378:5 | list6 | | +| atl.cpp:376:18:376:22 | ref arg list6 | atl.cpp:377:12:377:16 | list6 | | +| atl.cpp:376:18:376:22 | ref arg list6 | atl.cpp:378:5:378:5 | list6 | | +| atl.cpp:376:24:376:32 | call to FindIndex | atl.cpp:377:24:377:26 | pos | | +| atl.cpp:377:12:377:16 | ref arg list6 | atl.cpp:378:5:378:5 | list6 | | +| atl.cpp:381:27:381:28 | 10 | atl.cpp:381:27:381:29 | call to CAtlList | TAINT | +| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:382:18:382:22 | list7 | | +| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:383:7:383:11 | list7 | | +| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:384:12:384:16 | list7 | | +| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:385:5:385:5 | list7 | | +| atl.cpp:382:18:382:22 | ref arg list7 | atl.cpp:383:7:383:11 | list7 | | +| atl.cpp:382:18:382:22 | ref arg list7 | atl.cpp:384:12:384:16 | list7 | | +| atl.cpp:382:18:382:22 | ref arg list7 | atl.cpp:385:5:385:5 | list7 | | +| atl.cpp:382:24:382:38 | call to GetTailPosition | atl.cpp:383:25:383:27 | pos | | +| atl.cpp:383:7:383:11 | ref arg list7 | atl.cpp:384:12:384:16 | list7 | | +| atl.cpp:383:7:383:11 | ref arg list7 | atl.cpp:385:5:385:5 | list7 | | +| atl.cpp:384:12:384:16 | ref arg list7 | atl.cpp:385:5:385:5 | list7 | | +| atl.cpp:388:27:388:28 | 10 | atl.cpp:388:27:388:29 | call to CAtlList | TAINT | +| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:389:18:389:22 | list8 | | +| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:390:7:390:11 | list8 | | +| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:391:12:391:16 | list8 | | +| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:392:5:392:5 | list8 | | +| atl.cpp:389:18:389:22 | ref arg list8 | atl.cpp:390:7:390:11 | list8 | | +| atl.cpp:389:18:389:22 | ref arg list8 | atl.cpp:391:12:391:16 | list8 | | +| atl.cpp:389:18:389:22 | ref arg list8 | atl.cpp:392:5:392:5 | list8 | | +| atl.cpp:389:24:389:38 | call to GetTailPosition | atl.cpp:390:26:390:28 | pos | | +| atl.cpp:390:7:390:11 | ref arg list8 | atl.cpp:391:12:391:16 | list8 | | +| atl.cpp:390:7:390:11 | ref arg list8 | atl.cpp:392:5:392:5 | list8 | | +| atl.cpp:391:12:391:16 | ref arg list8 | atl.cpp:392:5:392:5 | list8 | | +| atl.cpp:394:27:394:28 | 10 | atl.cpp:394:27:394:29 | call to CAtlList | TAINT | +| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:395:7:395:11 | list9 | | +| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:395:19:395:23 | list9 | | +| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:396:12:396:16 | list9 | | +| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:397:5:397:5 | list9 | | +| atl.cpp:395:7:395:11 | ref arg list9 | atl.cpp:396:12:396:16 | list9 | | +| atl.cpp:395:7:395:11 | ref arg list9 | atl.cpp:397:5:397:5 | list9 | | +| atl.cpp:395:19:395:23 | ref arg list9 | atl.cpp:395:7:395:11 | list9 | | +| atl.cpp:395:19:395:23 | ref arg list9 | atl.cpp:396:12:396:16 | list9 | | +| atl.cpp:395:19:395:23 | ref arg list9 | atl.cpp:397:5:397:5 | list9 | | +| atl.cpp:396:12:396:16 | ref arg list9 | atl.cpp:397:5:397:5 | list9 | | +| atl.cpp:454:21:454:33 | new | atl.cpp:455:3:455:6 | safe | | +| atl.cpp:454:21:454:33 | new | atl.cpp:456:10:456:13 | safe | | +| atl.cpp:455:3:455:6 | safe [post update] | atl.cpp:456:10:456:13 | safe | | +| atl.cpp:455:3:455:40 | ... = ... | atl.cpp:455:9:455:14 | pvData [post update] | | +| atl.cpp:455:18:455:38 | call to indirect_source | atl.cpp:455:3:455:40 | ... = ... | | +| atl.cpp:460:13:460:33 | call to indirect_source | atl.cpp:462:16:462:16 | x | | +| atl.cpp:460:13:460:33 | call to indirect_source | atl.cpp:469:20:469:20 | x | | +| atl.cpp:460:13:460:33 | call to indirect_source | atl.cpp:473:16:473:16 | x | | +| atl.cpp:460:13:460:33 | call to indirect_source | atl.cpp:481:11:481:11 | x | | +| atl.cpp:460:13:460:33 | call to indirect_source | atl.cpp:495:20:495:20 | x | | +| atl.cpp:462:16:462:16 | x | atl.cpp:462:16:462:17 | call to CComBSTR | TAINT | +| atl.cpp:462:16:462:17 | call to CComBSTR | atl.cpp:463:10:463:10 | b | | +| atl.cpp:462:16:462:17 | call to CComBSTR | atl.cpp:465:17:465:17 | b | | +| atl.cpp:462:16:462:17 | call to CComBSTR | atl.cpp:467:3:467:3 | b | | +| atl.cpp:463:10:463:10 | b [post update] | atl.cpp:465:17:465:17 | b | | +| atl.cpp:463:10:463:10 | b [post update] | atl.cpp:467:3:467:3 | b | | +| atl.cpp:463:12:463:16 | ref arg m_str | atl.cpp:466:13:466:17 | m_str | | +| atl.cpp:465:17:465:17 | b | atl.cpp:465:17:465:18 | call to CComBSTR | | +| atl.cpp:465:17:465:18 | call to CComBSTR | atl.cpp:466:10:466:11 | b2 | | +| atl.cpp:465:17:465:18 | call to CComBSTR | atl.cpp:467:3:467:3 | b2 | | +| atl.cpp:466:10:466:11 | b2 [post update] | atl.cpp:467:3:467:3 | b2 | | +| atl.cpp:469:16:469:21 | call to CComBSTR | atl.cpp:470:10:470:10 | b | | +| atl.cpp:469:16:469:21 | call to CComBSTR | atl.cpp:471:3:471:3 | b | | +| atl.cpp:470:10:470:10 | b [post update] | atl.cpp:471:3:471:3 | b | | +| atl.cpp:473:16:473:16 | x | atl.cpp:473:16:473:17 | call to CComBSTR | TAINT | +| atl.cpp:473:16:473:17 | call to CComBSTR | atl.cpp:477:11:477:11 | b | | +| atl.cpp:473:16:473:17 | call to CComBSTR | atl.cpp:513:3:513:3 | b | | +| atl.cpp:475:14:475:15 | call to CComBSTR | atl.cpp:476:10:476:11 | b2 | | +| atl.cpp:475:14:475:15 | call to CComBSTR | atl.cpp:477:5:477:6 | b2 | | +| atl.cpp:475:14:475:15 | call to CComBSTR | atl.cpp:478:10:478:11 | b2 | | +| atl.cpp:475:14:475:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b2 | | +| atl.cpp:476:10:476:11 | b2 [post update] | atl.cpp:477:5:477:6 | b2 | | +| atl.cpp:476:10:476:11 | b2 [post update] | atl.cpp:478:10:478:11 | b2 | | +| atl.cpp:476:10:476:11 | b2 [post update] | atl.cpp:513:3:513:3 | b2 | | +| atl.cpp:476:13:476:17 | ref arg m_str | atl.cpp:478:13:478:17 | m_str | | +| atl.cpp:477:5:477:6 | ref arg b2 | atl.cpp:478:10:478:11 | b2 | | +| atl.cpp:477:5:477:6 | ref arg b2 | atl.cpp:513:3:513:3 | b2 | | +| atl.cpp:478:10:478:11 | b2 [post update] | atl.cpp:513:3:513:3 | b2 | | +| atl.cpp:480:14:480:15 | call to CComBSTR | atl.cpp:481:5:481:6 | b3 | | +| atl.cpp:480:14:480:15 | call to CComBSTR | atl.cpp:482:10:482:11 | b3 | | +| atl.cpp:480:14:480:15 | call to CComBSTR | atl.cpp:483:28:483:29 | b3 | | +| atl.cpp:480:14:480:15 | call to CComBSTR | atl.cpp:484:13:484:14 | b3 | | +| atl.cpp:480:14:480:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b3 | | +| atl.cpp:481:5:481:6 | ref arg b3 | atl.cpp:482:10:482:11 | b3 | | +| atl.cpp:481:5:481:6 | ref arg b3 | atl.cpp:483:28:483:29 | b3 | | +| atl.cpp:481:5:481:6 | ref arg b3 | atl.cpp:484:13:484:14 | b3 | | +| atl.cpp:481:5:481:6 | ref arg b3 | atl.cpp:513:3:513:3 | b3 | | +| atl.cpp:481:11:481:11 | x | atl.cpp:481:11:481:11 | call to CComBSTR | TAINT | +| atl.cpp:482:10:482:11 | b3 [post update] | atl.cpp:483:28:483:29 | b3 | | +| atl.cpp:482:10:482:11 | b3 [post update] | atl.cpp:484:13:484:14 | b3 | | +| atl.cpp:482:10:482:11 | b3 [post update] | atl.cpp:513:3:513:3 | b3 | | +| atl.cpp:483:28:483:29 | ref arg b3 | atl.cpp:484:13:484:14 | b3 | | +| atl.cpp:483:28:483:29 | ref arg b3 | atl.cpp:513:3:513:3 | b3 | | +| atl.cpp:484:11:484:14 | * ... | atl.cpp:484:10:484:14 | * ... | TAINT | +| atl.cpp:484:12:484:12 | call to operator& | atl.cpp:484:11:484:14 | * ... | TAINT | +| atl.cpp:484:13:484:14 | ref arg b3 | atl.cpp:513:3:513:3 | b3 | | +| atl.cpp:486:14:486:15 | call to CComBSTR | atl.cpp:487:5:487:6 | b4 | | +| atl.cpp:486:14:486:15 | call to CComBSTR | atl.cpp:488:10:488:11 | b4 | | +| atl.cpp:486:14:486:15 | call to CComBSTR | atl.cpp:491:19:491:20 | b4 | | +| atl.cpp:486:14:486:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b4 | | +| atl.cpp:487:5:487:6 | ref arg b4 | atl.cpp:488:10:488:11 | b4 | | +| atl.cpp:487:5:487:6 | ref arg b4 | atl.cpp:491:19:491:20 | b4 | | +| atl.cpp:487:5:487:6 | ref arg b4 | atl.cpp:513:3:513:3 | b4 | | +| atl.cpp:488:10:488:11 | b4 [post update] | atl.cpp:491:19:491:20 | b4 | | +| atl.cpp:488:10:488:11 | b4 [post update] | atl.cpp:513:3:513:3 | b4 | | +| atl.cpp:488:13:488:17 | ref arg m_str | atl.cpp:491:22:491:26 | m_str | | +| atl.cpp:490:14:490:15 | call to CComBSTR | atl.cpp:491:5:491:6 | b5 | | +| atl.cpp:490:14:490:15 | call to CComBSTR | atl.cpp:492:10:492:11 | b5 | | +| atl.cpp:490:14:490:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b5 | | +| atl.cpp:491:5:491:6 | ref arg b5 | atl.cpp:492:10:492:11 | b5 | | +| atl.cpp:491:5:491:6 | ref arg b5 | atl.cpp:513:3:513:3 | b5 | | +| atl.cpp:491:19:491:20 | b4 [post update] | atl.cpp:513:3:513:3 | b4 | | +| atl.cpp:492:10:492:11 | b5 [post update] | atl.cpp:513:3:513:3 | b5 | | +| atl.cpp:494:14:494:15 | call to CComBSTR | atl.cpp:495:5:495:6 | b6 | | +| atl.cpp:494:14:494:15 | call to CComBSTR | atl.cpp:496:10:496:11 | b6 | | +| atl.cpp:494:14:494:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b6 | | +| atl.cpp:495:5:495:6 | ref arg b6 | atl.cpp:496:10:496:11 | b6 | | +| atl.cpp:495:5:495:6 | ref arg b6 | atl.cpp:513:3:513:3 | b6 | | +| atl.cpp:496:10:496:11 | b6 [post update] | atl.cpp:513:3:513:3 | b6 | | +| atl.cpp:498:14:498:15 | call to CComBSTR | atl.cpp:499:5:499:6 | b7 | | +| atl.cpp:498:14:498:15 | call to CComBSTR | atl.cpp:500:10:500:11 | b7 | | +| atl.cpp:498:14:498:15 | call to CComBSTR | atl.cpp:503:19:503:20 | b7 | | +| atl.cpp:498:14:498:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b7 | | +| atl.cpp:499:5:499:6 | ref arg b7 | atl.cpp:500:10:500:11 | b7 | | +| atl.cpp:499:5:499:6 | ref arg b7 | atl.cpp:503:19:503:20 | b7 | | +| atl.cpp:499:5:499:6 | ref arg b7 | atl.cpp:513:3:513:3 | b7 | | +| atl.cpp:500:10:500:11 | b7 [post update] | atl.cpp:503:19:503:20 | b7 | | +| atl.cpp:500:10:500:11 | b7 [post update] | atl.cpp:513:3:513:3 | b7 | | +| atl.cpp:500:13:500:17 | ref arg m_str | atl.cpp:503:22:503:26 | m_str | | +| atl.cpp:502:14:502:15 | call to CComBSTR | atl.cpp:503:5:503:6 | b8 | | +| atl.cpp:502:14:502:15 | call to CComBSTR | atl.cpp:504:10:504:11 | b8 | | +| atl.cpp:502:14:502:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b8 | | +| atl.cpp:503:5:503:6 | ref arg b8 | atl.cpp:504:10:504:11 | b8 | | +| atl.cpp:503:5:503:6 | ref arg b8 | atl.cpp:513:3:513:3 | b8 | | +| atl.cpp:503:19:503:20 | b7 [post update] | atl.cpp:513:3:513:3 | b7 | | +| atl.cpp:504:10:504:11 | b8 [post update] | atl.cpp:513:3:513:3 | b8 | | +| atl.cpp:506:14:506:15 | call to CComBSTR | atl.cpp:508:5:508:6 | b9 | | +| atl.cpp:506:14:506:15 | call to CComBSTR | atl.cpp:509:5:509:6 | b9 | | +| atl.cpp:506:14:506:15 | call to CComBSTR | atl.cpp:512:10:512:11 | b9 | | +| atl.cpp:506:14:506:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b9 | | +| atl.cpp:507:15:507:18 | safe | atl.cpp:509:21:509:24 | safe | | +| atl.cpp:507:15:507:18 | safe | atl.cpp:510:10:510:13 | safe | | +| atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:509:5:509:6 | b9 | | +| atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:512:10:512:11 | b9 | | +| atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:513:3:513:3 | b9 | | +| atl.cpp:509:5:509:6 | ref arg b9 | atl.cpp:512:10:512:11 | b9 | | +| atl.cpp:509:5:509:6 | ref arg b9 | atl.cpp:513:3:513:3 | b9 | | +| atl.cpp:509:20:509:24 | ref arg & ... | atl.cpp:509:21:509:24 | safe [inner post update] | | +| atl.cpp:509:20:509:24 | ref arg & ... | atl.cpp:510:10:510:13 | safe | | +| atl.cpp:509:21:509:24 | safe | atl.cpp:509:20:509:24 | & ... | | +| atl.cpp:512:10:512:11 | ref arg b9 | atl.cpp:513:3:513:3 | b9 | | +| atl.cpp:515:16:515:39 | call to indirect_source | atl.cpp:517:16:517:16 | w | | +| atl.cpp:515:16:515:39 | call to indirect_source | atl.cpp:521:15:521:15 | w | | +| atl.cpp:515:16:515:39 | call to indirect_source | atl.cpp:525:20:525:20 | w | | +| atl.cpp:517:16:517:16 | ref arg w | atl.cpp:521:15:521:15 | w | | +| atl.cpp:517:16:517:16 | ref arg w | atl.cpp:525:20:525:20 | w | | +| atl.cpp:517:16:517:16 | w | atl.cpp:517:16:517:17 | call to CComBSTR | TAINT | +| atl.cpp:517:16:517:17 | call to CComBSTR | atl.cpp:518:10:518:10 | b | | +| atl.cpp:517:16:517:17 | call to CComBSTR | atl.cpp:523:3:523:3 | b | | +| atl.cpp:518:10:518:10 | b [post update] | atl.cpp:523:3:523:3 | b | | +| atl.cpp:520:14:520:15 | call to CComBSTR | atl.cpp:521:5:521:6 | b2 | | +| atl.cpp:520:14:520:15 | call to CComBSTR | atl.cpp:522:10:522:11 | b2 | | +| atl.cpp:520:14:520:15 | call to CComBSTR | atl.cpp:523:3:523:3 | b2 | | +| atl.cpp:521:5:521:6 | ref arg b2 | atl.cpp:522:10:522:11 | b2 | | +| atl.cpp:521:5:521:6 | ref arg b2 | atl.cpp:523:3:523:3 | b2 | | +| atl.cpp:521:15:521:15 | ref arg w | atl.cpp:525:20:525:20 | w | | +| atl.cpp:522:10:522:11 | b2 [post update] | atl.cpp:523:3:523:3 | b2 | | +| atl.cpp:525:16:525:21 | call to CComBSTR | atl.cpp:526:10:526:10 | b | | +| atl.cpp:525:16:525:21 | call to CComBSTR | atl.cpp:527:3:527:3 | b | | +| atl.cpp:526:10:526:10 | b [post update] | atl.cpp:527:3:527:3 | b | | +| atl.cpp:572:22:572:33 | call to getSafeArray | atl.cpp:573:8:573:11 | safe | | +| atl.cpp:572:22:572:33 | call to getSafeArray | atl.cpp:575:24:575:27 | safe | | +| atl.cpp:572:22:572:33 | call to getSafeArray | atl.cpp:586:11:586:14 | safe | | +| atl.cpp:573:8:573:11 | safe [post update] | atl.cpp:575:24:575:27 | safe | | +| atl.cpp:573:8:573:11 | safe [post update] | atl.cpp:586:11:586:14 | safe | | +| atl.cpp:575:24:575:27 | safe | atl.cpp:575:24:575:28 | call to CComSafeArray | TAINT | +| atl.cpp:575:24:575:28 | call to CComSafeArray | atl.cpp:576:8:576:8 | c | | +| atl.cpp:575:24:575:28 | call to CComSafeArray | atl.cpp:577:8:577:8 | c | | +| atl.cpp:575:24:575:28 | call to CComSafeArray | atl.cpp:578:8:578:8 | c | | +| atl.cpp:575:24:575:28 | call to CComSafeArray | atl.cpp:579:8:579:8 | c | | +| atl.cpp:575:24:575:28 | call to CComSafeArray | atl.cpp:580:3:580:3 | c | | | atl.cpp:576:8:576:8 | ref arg c | atl.cpp:577:8:577:8 | c | | | atl.cpp:576:8:576:8 | ref arg c | atl.cpp:578:8:578:8 | c | | -| atl.cpp:576:8:576:8 | ref arg c | atl.cpp:579:3:579:3 | c | | +| atl.cpp:576:8:576:8 | ref arg c | atl.cpp:579:8:579:8 | c | | +| atl.cpp:576:8:576:8 | ref arg c | atl.cpp:580:3:580:3 | c | | | atl.cpp:577:8:577:8 | ref arg c | atl.cpp:578:8:578:8 | c | | -| atl.cpp:577:8:577:8 | ref arg c | atl.cpp:579:3:579:3 | c | | -| atl.cpp:578:8:578:8 | c [post update] | atl.cpp:579:3:579:3 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:582:10:582:10 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:583:10:583:10 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:584:10:584:10 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:585:5:585:5 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:586:10:586:10 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:587:10:587:10 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:588:10:588:10 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:589:35:589:35 | c | | -| atl.cpp:581:24:581:24 | call to CComSafeArray | atl.cpp:590:3:590:3 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:583:10:583:10 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:584:10:584:10 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:585:5:585:5 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:586:10:586:10 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:587:10:587:10 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:588:10:588:10 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:589:35:589:35 | c | | -| atl.cpp:582:10:582:10 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:577:8:577:8 | ref arg c | atl.cpp:579:8:579:8 | c | | +| atl.cpp:577:8:577:8 | ref arg c | atl.cpp:580:3:580:3 | c | | +| atl.cpp:578:8:578:8 | ref arg c | atl.cpp:579:8:579:8 | c | | +| atl.cpp:578:8:578:8 | ref arg c | atl.cpp:580:3:580:3 | c | | +| atl.cpp:579:8:579:8 | c [post update] | atl.cpp:580:3:580:3 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:583:10:583:10 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:584:10:584:10 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:585:10:585:10 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:586:5:586:5 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:587:10:587:10 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:588:10:588:10 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:589:10:589:10 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:590:35:590:35 | c | | +| atl.cpp:582:24:582:24 | call to CComSafeArray | atl.cpp:591:3:591:3 | c | | | atl.cpp:583:10:583:10 | ref arg c | atl.cpp:584:10:584:10 | c | | -| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:585:5:585:5 | c | | -| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:586:10:586:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:586:5:586:5 | c | | | atl.cpp:583:10:583:10 | ref arg c | atl.cpp:587:10:587:10 | c | | | atl.cpp:583:10:583:10 | ref arg c | atl.cpp:588:10:588:10 | c | | -| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:589:35:589:35 | c | | -| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:590:3:590:3 | c | | -| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:585:5:585:5 | c | | -| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:586:10:586:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:589:10:589:10 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:590:35:590:35 | c | | +| atl.cpp:583:10:583:10 | ref arg c | atl.cpp:591:3:591:3 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:585:10:585:10 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:586:5:586:5 | c | | | atl.cpp:584:10:584:10 | ref arg c | atl.cpp:587:10:587:10 | c | | | atl.cpp:584:10:584:10 | ref arg c | atl.cpp:588:10:588:10 | c | | -| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:589:35:589:35 | c | | -| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:590:3:590:3 | c | | -| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:586:10:586:10 | c | | -| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:587:10:587:10 | c | | -| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:588:10:588:10 | c | | -| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:589:35:589:35 | c | | -| atl.cpp:585:5:585:5 | ref arg c | atl.cpp:590:3:590:3 | c | | -| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:587:10:587:10 | c | | -| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:588:10:588:10 | c | | -| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:589:35:589:35 | c | | -| atl.cpp:586:10:586:10 | ref arg c | atl.cpp:590:3:590:3 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:589:10:589:10 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:590:35:590:35 | c | | +| atl.cpp:584:10:584:10 | ref arg c | atl.cpp:591:3:591:3 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:586:5:586:5 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:587:10:587:10 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:589:10:589:10 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:590:35:590:35 | c | | +| atl.cpp:585:10:585:10 | ref arg c | atl.cpp:591:3:591:3 | c | | +| atl.cpp:586:5:586:5 | ref arg c | atl.cpp:587:10:587:10 | c | | +| atl.cpp:586:5:586:5 | ref arg c | atl.cpp:588:10:588:10 | c | | +| atl.cpp:586:5:586:5 | ref arg c | atl.cpp:589:10:589:10 | c | | +| atl.cpp:586:5:586:5 | ref arg c | atl.cpp:590:35:590:35 | c | | +| atl.cpp:586:5:586:5 | ref arg c | atl.cpp:591:3:591:3 | c | | | atl.cpp:587:10:587:10 | ref arg c | atl.cpp:588:10:588:10 | c | | -| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:589:35:589:35 | c | | -| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:590:3:590:3 | c | | -| atl.cpp:588:10:588:10 | ref arg c | atl.cpp:589:35:589:35 | c | | -| atl.cpp:588:10:588:10 | ref arg c | atl.cpp:590:3:590:3 | c | | -| atl.cpp:589:35:589:35 | ref arg c | atl.cpp:590:3:590:3 | c | | -| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:593:5:593:5 | c | | -| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:594:10:594:10 | c | | -| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:595:10:595:10 | c | | -| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:596:10:596:10 | c | | -| atl.cpp:592:24:592:24 | call to CComSafeArray | atl.cpp:597:3:597:3 | c | | -| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:594:10:594:10 | c | | -| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:595:10:595:10 | c | | -| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:596:10:596:10 | c | | -| atl.cpp:593:5:593:5 | ref arg c | atl.cpp:597:3:597:3 | c | | -| atl.cpp:594:10:594:10 | ref arg c | atl.cpp:595:10:595:10 | c | | -| atl.cpp:594:10:594:10 | ref arg c | atl.cpp:596:10:596:10 | c | | -| atl.cpp:594:10:594:10 | ref arg c | atl.cpp:597:3:597:3 | c | | +| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:589:10:589:10 | c | | +| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:590:35:590:35 | c | | +| atl.cpp:587:10:587:10 | ref arg c | atl.cpp:591:3:591:3 | c | | +| atl.cpp:588:10:588:10 | ref arg c | atl.cpp:589:10:589:10 | c | | +| atl.cpp:588:10:588:10 | ref arg c | atl.cpp:590:35:590:35 | c | | +| atl.cpp:588:10:588:10 | ref arg c | atl.cpp:591:3:591:3 | c | | +| atl.cpp:589:10:589:10 | ref arg c | atl.cpp:590:35:590:35 | c | | +| atl.cpp:589:10:589:10 | ref arg c | atl.cpp:591:3:591:3 | c | | +| atl.cpp:590:35:590:35 | ref arg c | atl.cpp:591:3:591:3 | c | | +| atl.cpp:593:24:593:24 | call to CComSafeArray | atl.cpp:594:5:594:5 | c | | +| atl.cpp:593:24:593:24 | call to CComSafeArray | atl.cpp:595:10:595:10 | c | | +| atl.cpp:593:24:593:24 | call to CComSafeArray | atl.cpp:596:10:596:10 | c | | +| atl.cpp:593:24:593:24 | call to CComSafeArray | atl.cpp:597:10:597:10 | c | | +| atl.cpp:593:24:593:24 | call to CComSafeArray | atl.cpp:598:3:598:3 | c | | +| atl.cpp:594:5:594:5 | ref arg c | atl.cpp:595:10:595:10 | c | | +| atl.cpp:594:5:594:5 | ref arg c | atl.cpp:596:10:596:10 | c | | +| atl.cpp:594:5:594:5 | ref arg c | atl.cpp:597:10:597:10 | c | | +| atl.cpp:594:5:594:5 | ref arg c | atl.cpp:598:3:598:3 | c | | | atl.cpp:595:10:595:10 | ref arg c | atl.cpp:596:10:596:10 | c | | -| atl.cpp:595:10:595:10 | ref arg c | atl.cpp:597:3:597:3 | c | | -| atl.cpp:596:10:596:10 | ref arg c | atl.cpp:597:3:597:3 | c | | -| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:600:5:600:5 | c | | -| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:601:10:601:10 | c | | -| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:602:10:602:10 | c | | -| atl.cpp:599:24:599:24 | call to CComSafeArray | atl.cpp:603:3:603:3 | c | | -| atl.cpp:600:5:600:5 | ref arg c | atl.cpp:601:10:601:10 | c | | -| atl.cpp:600:5:600:5 | ref arg c | atl.cpp:602:10:602:10 | c | | -| atl.cpp:600:5:600:5 | ref arg c | atl.cpp:603:3:603:3 | c | | -| atl.cpp:601:10:601:10 | ref arg c | atl.cpp:602:10:602:10 | c | | -| atl.cpp:601:10:601:10 | ref arg c | atl.cpp:603:3:603:3 | c | | -| atl.cpp:602:10:602:10 | ref arg c | atl.cpp:603:3:603:3 | c | | -| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:665:11:665:11 | x | | -| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:674:20:674:20 | x | | -| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:679:14:679:14 | x | | -| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:687:11:687:11 | x | | -| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:693:15:693:15 | x | | -| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:698:24:698:24 | x | | -| atl.cpp:664:13:664:33 | call to indirect_source | atl.cpp:704:30:704:30 | x | | -| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:674:20:674:20 | x | | -| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:679:14:679:14 | x | | -| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:687:11:687:11 | x | | -| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:693:15:693:15 | x | | -| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:698:24:698:24 | x | | -| atl.cpp:665:11:665:11 | ref arg x | atl.cpp:704:30:704:30 | x | | -| atl.cpp:665:11:665:11 | x | atl.cpp:665:11:665:12 | call to CPathT | TAINT | -| atl.cpp:665:11:665:12 | call to CPathT | atl.cpp:666:27:666:27 | p | | -| atl.cpp:665:11:665:12 | call to CPathT | atl.cpp:667:8:667:8 | p | | -| atl.cpp:665:11:665:12 | call to CPathT | atl.cpp:669:12:669:12 | p | | -| atl.cpp:666:27:666:27 | ref arg p | atl.cpp:667:8:667:8 | p | | -| atl.cpp:666:27:666:27 | ref arg p | atl.cpp:669:12:669:12 | p | | -| atl.cpp:667:8:667:8 | p [post update] | atl.cpp:669:12:669:12 | p | | -| atl.cpp:667:10:667:18 | ref arg m_strPath | atl.cpp:670:11:670:19 | m_strPath | | -| atl.cpp:669:12:669:12 | p | atl.cpp:669:12:669:13 | call to CPathT | | -| atl.cpp:669:12:669:13 | call to CPathT | atl.cpp:670:8:670:9 | p2 | | -| atl.cpp:673:11:673:11 | call to CPathT | atl.cpp:674:5:674:5 | p | | -| atl.cpp:673:11:673:11 | call to CPathT | atl.cpp:675:10:675:10 | p | | -| atl.cpp:674:5:674:5 | ref arg p | atl.cpp:675:10:675:10 | p | | -| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:679:14:679:14 | x | | -| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:687:11:687:11 | x | | -| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:693:15:693:15 | x | | -| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:698:24:698:24 | x | | -| atl.cpp:674:20:674:20 | ref arg x | atl.cpp:704:30:704:30 | x | | -| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:679:5:679:5 | p | | -| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:680:10:680:10 | p | | -| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:683:11:683:11 | p | | -| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:684:10:684:10 | p | | -| atl.cpp:678:11:678:11 | call to CPathT | atl.cpp:688:10:688:10 | p | | -| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:680:10:680:10 | p | | -| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:683:11:683:11 | p | | -| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:684:10:684:10 | p | | -| atl.cpp:679:5:679:5 | ref arg p | atl.cpp:688:10:688:10 | p | | -| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:687:11:687:11 | x | | -| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:693:15:693:15 | x | | -| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:698:24:698:24 | x | | -| atl.cpp:679:14:679:14 | ref arg x | atl.cpp:704:30:704:30 | x | | -| atl.cpp:680:10:680:10 | p [post update] | atl.cpp:683:11:683:11 | p | | -| atl.cpp:680:10:680:10 | p [post update] | atl.cpp:684:10:684:10 | p | | -| atl.cpp:680:10:680:10 | p [post update] | atl.cpp:688:10:688:10 | p | | -| atl.cpp:680:12:680:20 | ref arg m_strPath | atl.cpp:684:12:684:20 | m_strPath | | -| atl.cpp:680:12:680:20 | ref arg m_strPath | atl.cpp:688:12:688:20 | m_strPath | | -| atl.cpp:682:11:682:12 | call to CPathT | atl.cpp:683:5:683:6 | p2 | | -| atl.cpp:683:11:683:11 | call to operator char *& | atl.cpp:683:8:683:8 | call to operator+= | TAINT | -| atl.cpp:683:11:683:11 | ref arg p | atl.cpp:684:10:684:10 | p | | -| atl.cpp:683:11:683:11 | ref arg p | atl.cpp:688:10:688:10 | p | | -| atl.cpp:684:10:684:10 | p [post update] | atl.cpp:688:10:688:10 | p | | -| atl.cpp:684:12:684:20 | ref arg m_strPath | atl.cpp:688:12:688:20 | m_strPath | | -| atl.cpp:686:11:686:12 | call to CPathT | atl.cpp:687:5:687:6 | p3 | | -| atl.cpp:687:11:687:11 | ref arg x | atl.cpp:693:15:693:15 | x | | -| atl.cpp:687:11:687:11 | ref arg x | atl.cpp:698:24:698:24 | x | | -| atl.cpp:687:11:687:11 | ref arg x | atl.cpp:704:30:704:30 | x | | -| atl.cpp:687:11:687:11 | x | atl.cpp:687:8:687:8 | call to operator+= | TAINT | -| atl.cpp:692:11:692:11 | call to CPathT | atl.cpp:693:5:693:5 | p | | -| atl.cpp:692:11:692:11 | call to CPathT | atl.cpp:694:10:694:10 | p | | -| atl.cpp:693:5:693:5 | ref arg p | atl.cpp:694:10:694:10 | p | | -| atl.cpp:693:15:693:15 | ref arg x | atl.cpp:698:24:698:24 | x | | -| atl.cpp:693:15:693:15 | ref arg x | atl.cpp:704:30:704:30 | x | | -| atl.cpp:697:11:697:11 | call to CPathT | atl.cpp:698:5:698:5 | p | | -| atl.cpp:697:11:697:11 | call to CPathT | atl.cpp:699:10:699:10 | p | | -| atl.cpp:698:5:698:5 | ref arg p | atl.cpp:699:10:699:10 | p | | -| atl.cpp:698:24:698:24 | ref arg x | atl.cpp:704:30:704:30 | x | | -| atl.cpp:703:11:703:11 | call to CPathT | atl.cpp:704:15:704:15 | p | | -| atl.cpp:704:17:704:28 | call to CommonPrefix | atl.cpp:705:10:705:11 | p2 | | -| atl.cpp:704:17:704:28 | call to CommonPrefix | atl.cpp:706:10:706:11 | p2 | | -| atl.cpp:705:10:705:11 | p2 [post update] | atl.cpp:706:10:706:11 | p2 | | -| atl.cpp:733:11:733:21 | call to source | atl.cpp:736:11:736:11 | x | | -| atl.cpp:733:11:733:21 | call to source | atl.cpp:748:11:748:11 | x | | -| atl.cpp:733:11:733:21 | call to source | atl.cpp:752:23:752:23 | x | | -| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:736:5:736:5 | a | | -| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:737:10:737:10 | a | | -| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:738:5:738:5 | a | | -| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:739:10:739:10 | a | | -| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:743:10:743:10 | a | | -| atl.cpp:735:23:735:23 | call to CSimpleArray | atl.cpp:745:3:745:3 | a | | -| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:737:10:737:10 | a | | -| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:738:5:738:5 | a | | -| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:739:10:739:10 | a | | -| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:743:10:743:10 | a | | -| atl.cpp:736:5:736:5 | ref arg a | atl.cpp:745:3:745:3 | a | | -| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:738:5:738:5 | a | | -| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:739:10:739:10 | a | | -| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:743:10:743:10 | a | | -| atl.cpp:737:10:737:10 | ref arg a | atl.cpp:745:3:745:3 | a | | -| atl.cpp:738:5:738:5 | ref arg a | atl.cpp:739:10:739:10 | a | | -| atl.cpp:738:5:738:5 | ref arg a | atl.cpp:743:10:743:10 | a | | -| atl.cpp:738:5:738:5 | ref arg a | atl.cpp:745:3:745:3 | a | | -| atl.cpp:739:10:739:10 | ref arg a | atl.cpp:743:10:743:10 | a | | -| atl.cpp:739:10:739:10 | ref arg a | atl.cpp:745:3:745:3 | a | | -| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:742:10:742:11 | a2 | | -| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:743:5:743:6 | a2 | | -| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:744:10:744:11 | a2 | | -| atl.cpp:741:23:741:24 | call to CSimpleArray | atl.cpp:745:3:745:3 | a2 | | -| atl.cpp:742:10:742:11 | ref arg a2 | atl.cpp:743:5:743:6 | a2 | | -| atl.cpp:742:10:742:11 | ref arg a2 | atl.cpp:744:10:744:11 | a2 | | -| atl.cpp:742:10:742:11 | ref arg a2 | atl.cpp:745:3:745:3 | a2 | | -| atl.cpp:743:5:743:6 | ref arg a2 | atl.cpp:744:10:744:11 | a2 | | -| atl.cpp:743:5:743:6 | ref arg a2 | atl.cpp:745:3:745:3 | a2 | | -| atl.cpp:743:10:743:10 | a | atl.cpp:743:5:743:6 | ref arg a2 | TAINT | -| atl.cpp:743:10:743:10 | a | atl.cpp:743:8:743:8 | call to operator= | TAINT | -| atl.cpp:744:10:744:11 | ref arg a2 | atl.cpp:745:3:745:3 | a2 | | -| atl.cpp:747:23:747:23 | call to CSimpleArray | atl.cpp:748:5:748:5 | a | | -| atl.cpp:747:23:747:23 | call to CSimpleArray | atl.cpp:749:10:749:10 | a | | -| atl.cpp:747:23:747:23 | call to CSimpleArray | atl.cpp:754:3:754:3 | a | | -| atl.cpp:748:5:748:5 | ref arg a | atl.cpp:749:10:749:10 | a | | -| atl.cpp:748:5:748:5 | ref arg a | atl.cpp:754:3:754:3 | a | | -| atl.cpp:749:10:749:10 | ref arg a | atl.cpp:754:3:754:3 | a | | -| atl.cpp:751:23:751:24 | call to CSimpleArray | atl.cpp:752:15:752:16 | a2 | | -| atl.cpp:751:23:751:24 | call to CSimpleArray | atl.cpp:753:10:753:11 | a2 | | -| atl.cpp:751:23:751:24 | call to CSimpleArray | atl.cpp:754:3:754:3 | a2 | | -| atl.cpp:752:18:752:21 | call to Find | atl.cpp:753:13:753:15 | pos | | -| atl.cpp:753:10:753:11 | ref arg a2 | atl.cpp:754:3:754:3 | a2 | | -| atl.cpp:778:16:778:31 | call to source | atl.cpp:781:20:781:20 | x | | -| atl.cpp:778:16:778:31 | call to source | atl.cpp:791:26:791:26 | x | | -| atl.cpp:778:16:778:31 | call to source | atl.cpp:796:32:796:32 | x | | -| atl.cpp:778:16:778:31 | call to source | atl.cpp:802:22:802:22 | x | | -| atl.cpp:778:16:778:31 | call to source | atl.cpp:807:30:807:30 | x | | -| atl.cpp:780:33:780:33 | call to CSimpleMap | atl.cpp:781:5:781:5 | a | | -| atl.cpp:780:33:780:33 | call to CSimpleMap | atl.cpp:782:10:782:10 | a | | -| atl.cpp:780:33:780:33 | call to CSimpleMap | atl.cpp:783:3:783:3 | a | | -| atl.cpp:781:5:781:5 | ref arg a | atl.cpp:782:10:782:10 | a | | -| atl.cpp:781:5:781:5 | ref arg a | atl.cpp:783:3:783:3 | a | | -| atl.cpp:782:10:782:10 | ref arg a | atl.cpp:783:3:783:3 | a | | -| atl.cpp:785:33:785:33 | call to CSimpleMap | atl.cpp:786:16:786:16 | a | | -| atl.cpp:785:33:785:33 | call to CSimpleMap | atl.cpp:787:10:787:10 | a | | -| atl.cpp:785:33:785:33 | call to CSimpleMap | atl.cpp:788:3:788:3 | a | | -| atl.cpp:786:18:786:24 | call to FindKey | atl.cpp:787:23:787:25 | pos | | -| atl.cpp:787:10:787:10 | ref arg a | atl.cpp:788:3:788:3 | a | | -| atl.cpp:790:33:790:33 | call to CSimpleMap | atl.cpp:791:16:791:16 | a | | -| atl.cpp:790:33:790:33 | call to CSimpleMap | atl.cpp:792:10:792:10 | a | | -| atl.cpp:790:33:790:33 | call to CSimpleMap | atl.cpp:793:3:793:3 | a | | -| atl.cpp:791:18:791:24 | call to FindVal | atl.cpp:792:23:792:25 | pos | | -| atl.cpp:792:10:792:10 | ref arg a | atl.cpp:793:3:793:3 | a | | -| atl.cpp:795:33:795:33 | call to CSimpleMap | atl.cpp:796:16:796:16 | a | | -| atl.cpp:795:33:795:33 | call to CSimpleMap | atl.cpp:798:10:798:10 | a | | -| atl.cpp:795:33:795:33 | call to CSimpleMap | atl.cpp:799:3:799:3 | a | | -| atl.cpp:796:16:796:16 | ref arg a | atl.cpp:798:10:798:10 | a | | -| atl.cpp:796:16:796:16 | ref arg a | atl.cpp:799:3:799:3 | a | | -| atl.cpp:796:18:796:30 | call to ReverseLookup | atl.cpp:797:10:797:12 | key | | -| atl.cpp:796:18:796:30 | call to ReverseLookup | atl.cpp:798:19:798:21 | key | | -| atl.cpp:797:10:797:12 | ref arg key | atl.cpp:798:19:798:21 | key | | -| atl.cpp:798:10:798:10 | ref arg a | atl.cpp:799:3:799:3 | a | | -| atl.cpp:801:33:801:33 | call to CSimpleMap | atl.cpp:802:5:802:5 | a | | -| atl.cpp:801:33:801:33 | call to CSimpleMap | atl.cpp:803:10:803:10 | a | | -| atl.cpp:801:33:801:33 | call to CSimpleMap | atl.cpp:804:3:804:3 | a | | -| atl.cpp:802:5:802:5 | ref arg a | atl.cpp:803:10:803:10 | a | | -| atl.cpp:802:5:802:5 | ref arg a | atl.cpp:804:3:804:3 | a | | -| atl.cpp:803:10:803:10 | ref arg a | atl.cpp:804:3:804:3 | a | | -| atl.cpp:806:33:806:33 | call to CSimpleMap | atl.cpp:807:5:807:5 | a | | -| atl.cpp:806:33:806:33 | call to CSimpleMap | atl.cpp:808:10:808:10 | a | | -| atl.cpp:806:33:806:33 | call to CSimpleMap | atl.cpp:809:3:809:3 | a | | -| atl.cpp:807:5:807:5 | ref arg a | atl.cpp:808:10:808:10 | a | | -| atl.cpp:807:5:807:5 | ref arg a | atl.cpp:809:3:809:3 | a | | -| atl.cpp:808:10:808:10 | ref arg a | atl.cpp:809:3:809:3 | a | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:852:16:852:16 | x | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:865:19:865:19 | x | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:871:23:871:23 | x | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:876:22:876:22 | x | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:881:22:881:22 | x | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:886:24:886:24 | x | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:891:21:891:21 | x | | -| atl.cpp:850:13:850:33 | call to indirect_source | atl.cpp:896:22:896:22 | x | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:852:3:852:5 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:853:8:853:10 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:854:8:854:10 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:855:8:855:10 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:856:8:856:10 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:857:8:857:10 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:858:8:858:10 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:859:8:859:10 | url | | -| atl.cpp:851:8:851:10 | call to CUrl | atl.cpp:899:1:899:1 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:853:8:853:10 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:854:8:854:10 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:855:8:855:10 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:856:8:856:10 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:857:8:857:10 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:858:8:858:10 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:859:8:859:10 | url | | -| atl.cpp:852:3:852:5 | ref arg url | atl.cpp:899:1:899:1 | url | | -| atl.cpp:862:10:862:13 | call to CUrl | atl.cpp:865:5:865:8 | url2 | | -| atl.cpp:862:10:862:13 | call to CUrl | atl.cpp:866:5:866:8 | url2 | | -| atl.cpp:862:10:862:13 | call to CUrl | atl.cpp:868:3:868:3 | url2 | | -| atl.cpp:863:11:863:13 | len | atl.cpp:866:29:866:31 | len | | -| atl.cpp:864:10:864:15 | buffer | atl.cpp:866:20:866:25 | buffer | | -| atl.cpp:864:10:864:15 | buffer | atl.cpp:867:10:867:15 | buffer | | -| atl.cpp:865:5:865:8 | ref arg url2 | atl.cpp:866:5:866:8 | url2 | | -| atl.cpp:865:5:865:8 | ref arg url2 | atl.cpp:868:3:868:3 | url2 | | -| atl.cpp:866:20:866:25 | ref arg buffer | atl.cpp:867:10:867:15 | buffer | | -| atl.cpp:866:28:866:31 | ref arg & ... | atl.cpp:866:29:866:31 | len [inner post update] | | -| atl.cpp:866:29:866:31 | len | atl.cpp:866:28:866:31 | & ... | | -| atl.cpp:870:10:870:13 | call to CUrl | atl.cpp:871:5:871:8 | url2 | | -| atl.cpp:870:10:870:13 | call to CUrl | atl.cpp:872:10:872:13 | url2 | | -| atl.cpp:870:10:870:13 | call to CUrl | atl.cpp:873:3:873:3 | url2 | | -| atl.cpp:871:5:871:8 | ref arg url2 | atl.cpp:872:10:872:13 | url2 | | -| atl.cpp:871:5:871:8 | ref arg url2 | atl.cpp:873:3:873:3 | url2 | | -| atl.cpp:875:10:875:13 | call to CUrl | atl.cpp:876:5:876:8 | url2 | | -| atl.cpp:875:10:875:13 | call to CUrl | atl.cpp:877:10:877:13 | url2 | | -| atl.cpp:875:10:875:13 | call to CUrl | atl.cpp:878:3:878:3 | url2 | | -| atl.cpp:876:5:876:8 | ref arg url2 | atl.cpp:877:10:877:13 | url2 | | -| atl.cpp:876:5:876:8 | ref arg url2 | atl.cpp:878:3:878:3 | url2 | | -| atl.cpp:880:10:880:13 | call to CUrl | atl.cpp:881:5:881:8 | url2 | | -| atl.cpp:880:10:880:13 | call to CUrl | atl.cpp:882:10:882:13 | url2 | | -| atl.cpp:880:10:880:13 | call to CUrl | atl.cpp:883:3:883:3 | url2 | | -| atl.cpp:881:5:881:8 | ref arg url2 | atl.cpp:882:10:882:13 | url2 | | -| atl.cpp:881:5:881:8 | ref arg url2 | atl.cpp:883:3:883:3 | url2 | | -| atl.cpp:885:10:885:13 | call to CUrl | atl.cpp:886:5:886:8 | url2 | | -| atl.cpp:885:10:885:13 | call to CUrl | atl.cpp:887:10:887:13 | url2 | | -| atl.cpp:885:10:885:13 | call to CUrl | atl.cpp:888:3:888:3 | url2 | | -| atl.cpp:886:5:886:8 | ref arg url2 | atl.cpp:887:10:887:13 | url2 | | -| atl.cpp:886:5:886:8 | ref arg url2 | atl.cpp:888:3:888:3 | url2 | | -| atl.cpp:890:10:890:13 | call to CUrl | atl.cpp:891:5:891:8 | url2 | | -| atl.cpp:890:10:890:13 | call to CUrl | atl.cpp:892:10:892:13 | url2 | | -| atl.cpp:890:10:890:13 | call to CUrl | atl.cpp:893:3:893:3 | url2 | | -| atl.cpp:891:5:891:8 | ref arg url2 | atl.cpp:892:10:892:13 | url2 | | -| atl.cpp:891:5:891:8 | ref arg url2 | atl.cpp:893:3:893:3 | url2 | | -| atl.cpp:895:10:895:13 | call to CUrl | atl.cpp:896:5:896:8 | url2 | | -| atl.cpp:895:10:895:13 | call to CUrl | atl.cpp:897:10:897:13 | url2 | | -| atl.cpp:895:10:895:13 | call to CUrl | atl.cpp:898:3:898:3 | url2 | | -| atl.cpp:896:5:896:8 | ref arg url2 | atl.cpp:897:10:897:13 | url2 | | -| atl.cpp:896:5:896:8 | ref arg url2 | atl.cpp:898:3:898:3 | url2 | | +| atl.cpp:595:10:595:10 | ref arg c | atl.cpp:597:10:597:10 | c | | +| atl.cpp:595:10:595:10 | ref arg c | atl.cpp:598:3:598:3 | c | | +| atl.cpp:596:10:596:10 | ref arg c | atl.cpp:597:10:597:10 | c | | +| atl.cpp:596:10:596:10 | ref arg c | atl.cpp:598:3:598:3 | c | | +| atl.cpp:597:10:597:10 | ref arg c | atl.cpp:598:3:598:3 | c | | +| atl.cpp:600:24:600:24 | call to CComSafeArray | atl.cpp:601:5:601:5 | c | | +| atl.cpp:600:24:600:24 | call to CComSafeArray | atl.cpp:602:10:602:10 | c | | +| atl.cpp:600:24:600:24 | call to CComSafeArray | atl.cpp:603:10:603:10 | c | | +| atl.cpp:600:24:600:24 | call to CComSafeArray | atl.cpp:604:3:604:3 | c | | +| atl.cpp:601:5:601:5 | ref arg c | atl.cpp:602:10:602:10 | c | | +| atl.cpp:601:5:601:5 | ref arg c | atl.cpp:603:10:603:10 | c | | +| atl.cpp:601:5:601:5 | ref arg c | atl.cpp:604:3:604:3 | c | | +| atl.cpp:602:10:602:10 | ref arg c | atl.cpp:603:10:603:10 | c | | +| atl.cpp:602:10:602:10 | ref arg c | atl.cpp:604:3:604:3 | c | | +| atl.cpp:603:10:603:10 | ref arg c | atl.cpp:604:3:604:3 | c | | +| atl.cpp:665:13:665:33 | call to indirect_source | atl.cpp:666:11:666:11 | x | | +| atl.cpp:665:13:665:33 | call to indirect_source | atl.cpp:675:20:675:20 | x | | +| atl.cpp:665:13:665:33 | call to indirect_source | atl.cpp:680:14:680:14 | x | | +| atl.cpp:665:13:665:33 | call to indirect_source | atl.cpp:688:11:688:11 | x | | +| atl.cpp:665:13:665:33 | call to indirect_source | atl.cpp:694:15:694:15 | x | | +| atl.cpp:665:13:665:33 | call to indirect_source | atl.cpp:699:24:699:24 | x | | +| atl.cpp:665:13:665:33 | call to indirect_source | atl.cpp:705:30:705:30 | x | | +| atl.cpp:666:11:666:11 | ref arg x | atl.cpp:675:20:675:20 | x | | +| atl.cpp:666:11:666:11 | ref arg x | atl.cpp:680:14:680:14 | x | | +| atl.cpp:666:11:666:11 | ref arg x | atl.cpp:688:11:688:11 | x | | +| atl.cpp:666:11:666:11 | ref arg x | atl.cpp:694:15:694:15 | x | | +| atl.cpp:666:11:666:11 | ref arg x | atl.cpp:699:24:699:24 | x | | +| atl.cpp:666:11:666:11 | ref arg x | atl.cpp:705:30:705:30 | x | | +| atl.cpp:666:11:666:11 | x | atl.cpp:666:11:666:12 | call to CPathT | TAINT | +| atl.cpp:666:11:666:12 | call to CPathT | atl.cpp:667:27:667:27 | p | | +| atl.cpp:666:11:666:12 | call to CPathT | atl.cpp:668:8:668:8 | p | | +| atl.cpp:666:11:666:12 | call to CPathT | atl.cpp:670:12:670:12 | p | | +| atl.cpp:667:27:667:27 | ref arg p | atl.cpp:668:8:668:8 | p | | +| atl.cpp:667:27:667:27 | ref arg p | atl.cpp:670:12:670:12 | p | | +| atl.cpp:668:8:668:8 | p [post update] | atl.cpp:670:12:670:12 | p | | +| atl.cpp:668:10:668:18 | ref arg m_strPath | atl.cpp:671:11:671:19 | m_strPath | | +| atl.cpp:670:12:670:12 | p | atl.cpp:670:12:670:13 | call to CPathT | | +| atl.cpp:670:12:670:13 | call to CPathT | atl.cpp:671:8:671:9 | p2 | | +| atl.cpp:674:11:674:11 | call to CPathT | atl.cpp:675:5:675:5 | p | | +| atl.cpp:674:11:674:11 | call to CPathT | atl.cpp:676:10:676:10 | p | | +| atl.cpp:675:5:675:5 | ref arg p | atl.cpp:676:10:676:10 | p | | +| atl.cpp:675:20:675:20 | ref arg x | atl.cpp:680:14:680:14 | x | | +| atl.cpp:675:20:675:20 | ref arg x | atl.cpp:688:11:688:11 | x | | +| atl.cpp:675:20:675:20 | ref arg x | atl.cpp:694:15:694:15 | x | | +| atl.cpp:675:20:675:20 | ref arg x | atl.cpp:699:24:699:24 | x | | +| atl.cpp:675:20:675:20 | ref arg x | atl.cpp:705:30:705:30 | x | | +| atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:680:5:680:5 | p | | +| atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:681:10:681:10 | p | | +| atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:684:11:684:11 | p | | +| atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:685:10:685:10 | p | | +| atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:689:10:689:10 | p | | +| atl.cpp:680:5:680:5 | ref arg p | atl.cpp:681:10:681:10 | p | | +| atl.cpp:680:5:680:5 | ref arg p | atl.cpp:684:11:684:11 | p | | +| atl.cpp:680:5:680:5 | ref arg p | atl.cpp:685:10:685:10 | p | | +| atl.cpp:680:5:680:5 | ref arg p | atl.cpp:689:10:689:10 | p | | +| atl.cpp:680:14:680:14 | ref arg x | atl.cpp:688:11:688:11 | x | | +| atl.cpp:680:14:680:14 | ref arg x | atl.cpp:694:15:694:15 | x | | +| atl.cpp:680:14:680:14 | ref arg x | atl.cpp:699:24:699:24 | x | | +| atl.cpp:680:14:680:14 | ref arg x | atl.cpp:705:30:705:30 | x | | +| atl.cpp:681:10:681:10 | p [post update] | atl.cpp:684:11:684:11 | p | | +| atl.cpp:681:10:681:10 | p [post update] | atl.cpp:685:10:685:10 | p | | +| atl.cpp:681:10:681:10 | p [post update] | atl.cpp:689:10:689:10 | p | | +| atl.cpp:681:12:681:20 | ref arg m_strPath | atl.cpp:685:12:685:20 | m_strPath | | +| atl.cpp:681:12:681:20 | ref arg m_strPath | atl.cpp:689:12:689:20 | m_strPath | | +| atl.cpp:683:11:683:12 | call to CPathT | atl.cpp:684:5:684:6 | p2 | | +| atl.cpp:684:11:684:11 | call to operator char *& | atl.cpp:684:8:684:8 | call to operator+= | TAINT | +| atl.cpp:684:11:684:11 | ref arg p | atl.cpp:685:10:685:10 | p | | +| atl.cpp:684:11:684:11 | ref arg p | atl.cpp:689:10:689:10 | p | | +| atl.cpp:685:10:685:10 | p [post update] | atl.cpp:689:10:689:10 | p | | +| atl.cpp:685:12:685:20 | ref arg m_strPath | atl.cpp:689:12:689:20 | m_strPath | | +| atl.cpp:687:11:687:12 | call to CPathT | atl.cpp:688:5:688:6 | p3 | | +| atl.cpp:688:11:688:11 | ref arg x | atl.cpp:694:15:694:15 | x | | +| atl.cpp:688:11:688:11 | ref arg x | atl.cpp:699:24:699:24 | x | | +| atl.cpp:688:11:688:11 | ref arg x | atl.cpp:705:30:705:30 | x | | +| atl.cpp:688:11:688:11 | x | atl.cpp:688:8:688:8 | call to operator+= | TAINT | +| atl.cpp:693:11:693:11 | call to CPathT | atl.cpp:694:5:694:5 | p | | +| atl.cpp:693:11:693:11 | call to CPathT | atl.cpp:695:10:695:10 | p | | +| atl.cpp:694:5:694:5 | ref arg p | atl.cpp:695:10:695:10 | p | | +| atl.cpp:694:15:694:15 | ref arg x | atl.cpp:699:24:699:24 | x | | +| atl.cpp:694:15:694:15 | ref arg x | atl.cpp:705:30:705:30 | x | | +| atl.cpp:698:11:698:11 | call to CPathT | atl.cpp:699:5:699:5 | p | | +| atl.cpp:698:11:698:11 | call to CPathT | atl.cpp:700:10:700:10 | p | | +| atl.cpp:699:5:699:5 | ref arg p | atl.cpp:700:10:700:10 | p | | +| atl.cpp:699:24:699:24 | ref arg x | atl.cpp:705:30:705:30 | x | | +| atl.cpp:704:11:704:11 | call to CPathT | atl.cpp:705:15:705:15 | p | | +| atl.cpp:705:17:705:28 | call to CommonPrefix | atl.cpp:706:10:706:11 | p2 | | +| atl.cpp:705:17:705:28 | call to CommonPrefix | atl.cpp:707:10:707:11 | p2 | | +| atl.cpp:706:10:706:11 | p2 [post update] | atl.cpp:707:10:707:11 | p2 | | +| atl.cpp:734:11:734:21 | call to source | atl.cpp:737:11:737:11 | x | | +| atl.cpp:734:11:734:21 | call to source | atl.cpp:749:11:749:11 | x | | +| atl.cpp:734:11:734:21 | call to source | atl.cpp:753:23:753:23 | x | | +| atl.cpp:736:23:736:23 | call to CSimpleArray | atl.cpp:737:5:737:5 | a | | +| atl.cpp:736:23:736:23 | call to CSimpleArray | atl.cpp:738:10:738:10 | a | | +| atl.cpp:736:23:736:23 | call to CSimpleArray | atl.cpp:739:5:739:5 | a | | +| atl.cpp:736:23:736:23 | call to CSimpleArray | atl.cpp:740:10:740:10 | a | | +| atl.cpp:736:23:736:23 | call to CSimpleArray | atl.cpp:744:10:744:10 | a | | +| atl.cpp:736:23:736:23 | call to CSimpleArray | atl.cpp:746:3:746:3 | a | | +| atl.cpp:737:5:737:5 | ref arg a | atl.cpp:738:10:738:10 | a | | +| atl.cpp:737:5:737:5 | ref arg a | atl.cpp:739:5:739:5 | a | | +| atl.cpp:737:5:737:5 | ref arg a | atl.cpp:740:10:740:10 | a | | +| atl.cpp:737:5:737:5 | ref arg a | atl.cpp:744:10:744:10 | a | | +| atl.cpp:737:5:737:5 | ref arg a | atl.cpp:746:3:746:3 | a | | +| atl.cpp:738:10:738:10 | ref arg a | atl.cpp:739:5:739:5 | a | | +| atl.cpp:738:10:738:10 | ref arg a | atl.cpp:740:10:740:10 | a | | +| atl.cpp:738:10:738:10 | ref arg a | atl.cpp:744:10:744:10 | a | | +| atl.cpp:738:10:738:10 | ref arg a | atl.cpp:746:3:746:3 | a | | +| atl.cpp:739:5:739:5 | ref arg a | atl.cpp:740:10:740:10 | a | | +| atl.cpp:739:5:739:5 | ref arg a | atl.cpp:744:10:744:10 | a | | +| atl.cpp:739:5:739:5 | ref arg a | atl.cpp:746:3:746:3 | a | | +| atl.cpp:740:10:740:10 | ref arg a | atl.cpp:744:10:744:10 | a | | +| atl.cpp:740:10:740:10 | ref arg a | atl.cpp:746:3:746:3 | a | | +| atl.cpp:742:23:742:24 | call to CSimpleArray | atl.cpp:743:10:743:11 | a2 | | +| atl.cpp:742:23:742:24 | call to CSimpleArray | atl.cpp:744:5:744:6 | a2 | | +| atl.cpp:742:23:742:24 | call to CSimpleArray | atl.cpp:745:10:745:11 | a2 | | +| atl.cpp:742:23:742:24 | call to CSimpleArray | atl.cpp:746:3:746:3 | a2 | | +| atl.cpp:743:10:743:11 | ref arg a2 | atl.cpp:744:5:744:6 | a2 | | +| atl.cpp:743:10:743:11 | ref arg a2 | atl.cpp:745:10:745:11 | a2 | | +| atl.cpp:743:10:743:11 | ref arg a2 | atl.cpp:746:3:746:3 | a2 | | +| atl.cpp:744:5:744:6 | ref arg a2 | atl.cpp:745:10:745:11 | a2 | | +| atl.cpp:744:5:744:6 | ref arg a2 | atl.cpp:746:3:746:3 | a2 | | +| atl.cpp:744:10:744:10 | a | atl.cpp:744:5:744:6 | ref arg a2 | TAINT | +| atl.cpp:744:10:744:10 | a | atl.cpp:744:8:744:8 | call to operator= | TAINT | +| atl.cpp:745:10:745:11 | ref arg a2 | atl.cpp:746:3:746:3 | a2 | | +| atl.cpp:748:23:748:23 | call to CSimpleArray | atl.cpp:749:5:749:5 | a | | +| atl.cpp:748:23:748:23 | call to CSimpleArray | atl.cpp:750:10:750:10 | a | | +| atl.cpp:748:23:748:23 | call to CSimpleArray | atl.cpp:755:3:755:3 | a | | +| atl.cpp:749:5:749:5 | ref arg a | atl.cpp:750:10:750:10 | a | | +| atl.cpp:749:5:749:5 | ref arg a | atl.cpp:755:3:755:3 | a | | +| atl.cpp:750:10:750:10 | ref arg a | atl.cpp:755:3:755:3 | a | | +| atl.cpp:752:23:752:24 | call to CSimpleArray | atl.cpp:753:15:753:16 | a2 | | +| atl.cpp:752:23:752:24 | call to CSimpleArray | atl.cpp:754:10:754:11 | a2 | | +| atl.cpp:752:23:752:24 | call to CSimpleArray | atl.cpp:755:3:755:3 | a2 | | +| atl.cpp:753:18:753:21 | call to Find | atl.cpp:754:13:754:15 | pos | | +| atl.cpp:754:10:754:11 | ref arg a2 | atl.cpp:755:3:755:3 | a2 | | +| atl.cpp:779:16:779:31 | call to source | atl.cpp:782:20:782:20 | x | | +| atl.cpp:779:16:779:31 | call to source | atl.cpp:792:26:792:26 | x | | +| atl.cpp:779:16:779:31 | call to source | atl.cpp:797:32:797:32 | x | | +| atl.cpp:779:16:779:31 | call to source | atl.cpp:803:22:803:22 | x | | +| atl.cpp:779:16:779:31 | call to source | atl.cpp:808:30:808:30 | x | | +| atl.cpp:781:33:781:33 | call to CSimpleMap | atl.cpp:782:5:782:5 | a | | +| atl.cpp:781:33:781:33 | call to CSimpleMap | atl.cpp:783:10:783:10 | a | | +| atl.cpp:781:33:781:33 | call to CSimpleMap | atl.cpp:784:3:784:3 | a | | +| atl.cpp:782:5:782:5 | ref arg a | atl.cpp:783:10:783:10 | a | | +| atl.cpp:782:5:782:5 | ref arg a | atl.cpp:784:3:784:3 | a | | +| atl.cpp:783:10:783:10 | ref arg a | atl.cpp:784:3:784:3 | a | | +| atl.cpp:786:33:786:33 | call to CSimpleMap | atl.cpp:787:16:787:16 | a | | +| atl.cpp:786:33:786:33 | call to CSimpleMap | atl.cpp:788:10:788:10 | a | | +| atl.cpp:786:33:786:33 | call to CSimpleMap | atl.cpp:789:3:789:3 | a | | +| atl.cpp:787:18:787:24 | call to FindKey | atl.cpp:788:23:788:25 | pos | | +| atl.cpp:788:10:788:10 | ref arg a | atl.cpp:789:3:789:3 | a | | +| atl.cpp:791:33:791:33 | call to CSimpleMap | atl.cpp:792:16:792:16 | a | | +| atl.cpp:791:33:791:33 | call to CSimpleMap | atl.cpp:793:10:793:10 | a | | +| atl.cpp:791:33:791:33 | call to CSimpleMap | atl.cpp:794:3:794:3 | a | | +| atl.cpp:792:18:792:24 | call to FindVal | atl.cpp:793:23:793:25 | pos | | +| atl.cpp:793:10:793:10 | ref arg a | atl.cpp:794:3:794:3 | a | | +| atl.cpp:796:33:796:33 | call to CSimpleMap | atl.cpp:797:16:797:16 | a | | +| atl.cpp:796:33:796:33 | call to CSimpleMap | atl.cpp:799:10:799:10 | a | | +| atl.cpp:796:33:796:33 | call to CSimpleMap | atl.cpp:800:3:800:3 | a | | +| atl.cpp:797:16:797:16 | ref arg a | atl.cpp:799:10:799:10 | a | | +| atl.cpp:797:16:797:16 | ref arg a | atl.cpp:800:3:800:3 | a | | +| atl.cpp:797:18:797:30 | call to ReverseLookup | atl.cpp:798:10:798:12 | key | | +| atl.cpp:797:18:797:30 | call to ReverseLookup | atl.cpp:799:19:799:21 | key | | +| atl.cpp:798:10:798:12 | ref arg key | atl.cpp:799:19:799:21 | key | | +| atl.cpp:799:10:799:10 | ref arg a | atl.cpp:800:3:800:3 | a | | +| atl.cpp:802:33:802:33 | call to CSimpleMap | atl.cpp:803:5:803:5 | a | | +| atl.cpp:802:33:802:33 | call to CSimpleMap | atl.cpp:804:10:804:10 | a | | +| atl.cpp:802:33:802:33 | call to CSimpleMap | atl.cpp:805:3:805:3 | a | | +| atl.cpp:803:5:803:5 | ref arg a | atl.cpp:804:10:804:10 | a | | +| atl.cpp:803:5:803:5 | ref arg a | atl.cpp:805:3:805:3 | a | | +| atl.cpp:804:10:804:10 | ref arg a | atl.cpp:805:3:805:3 | a | | +| atl.cpp:807:33:807:33 | call to CSimpleMap | atl.cpp:808:5:808:5 | a | | +| atl.cpp:807:33:807:33 | call to CSimpleMap | atl.cpp:809:10:809:10 | a | | +| atl.cpp:807:33:807:33 | call to CSimpleMap | atl.cpp:810:3:810:3 | a | | +| atl.cpp:808:5:808:5 | ref arg a | atl.cpp:809:10:809:10 | a | | +| atl.cpp:808:5:808:5 | ref arg a | atl.cpp:810:3:810:3 | a | | +| atl.cpp:809:10:809:10 | ref arg a | atl.cpp:810:3:810:3 | a | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:853:16:853:16 | x | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:866:19:866:19 | x | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:872:23:872:23 | x | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:877:22:877:22 | x | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:882:22:882:22 | x | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:887:24:887:24 | x | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:892:21:892:21 | x | | +| atl.cpp:851:13:851:33 | call to indirect_source | atl.cpp:897:22:897:22 | x | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:853:3:853:5 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:854:8:854:10 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:855:8:855:10 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:856:8:856:10 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:857:8:857:10 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:858:8:858:10 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:859:8:859:10 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:860:8:860:10 | url | | +| atl.cpp:852:8:852:10 | call to CUrl | atl.cpp:900:1:900:1 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:854:8:854:10 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:855:8:855:10 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:856:8:856:10 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:857:8:857:10 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:858:8:858:10 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:859:8:859:10 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:860:8:860:10 | url | | +| atl.cpp:853:3:853:5 | ref arg url | atl.cpp:900:1:900:1 | url | | +| atl.cpp:863:10:863:13 | call to CUrl | atl.cpp:866:5:866:8 | url2 | | +| atl.cpp:863:10:863:13 | call to CUrl | atl.cpp:867:5:867:8 | url2 | | +| atl.cpp:863:10:863:13 | call to CUrl | atl.cpp:869:3:869:3 | url2 | | +| atl.cpp:864:11:864:13 | len | atl.cpp:867:29:867:31 | len | | +| atl.cpp:865:10:865:15 | buffer | atl.cpp:867:20:867:25 | buffer | | +| atl.cpp:865:10:865:15 | buffer | atl.cpp:868:10:868:15 | buffer | | +| atl.cpp:866:5:866:8 | ref arg url2 | atl.cpp:867:5:867:8 | url2 | | +| atl.cpp:866:5:866:8 | ref arg url2 | atl.cpp:869:3:869:3 | url2 | | +| atl.cpp:867:20:867:25 | ref arg buffer | atl.cpp:868:10:868:15 | buffer | | +| atl.cpp:867:28:867:31 | ref arg & ... | atl.cpp:867:29:867:31 | len [inner post update] | | +| atl.cpp:867:29:867:31 | len | atl.cpp:867:28:867:31 | & ... | | +| atl.cpp:871:10:871:13 | call to CUrl | atl.cpp:872:5:872:8 | url2 | | +| atl.cpp:871:10:871:13 | call to CUrl | atl.cpp:873:10:873:13 | url2 | | +| atl.cpp:871:10:871:13 | call to CUrl | atl.cpp:874:3:874:3 | url2 | | +| atl.cpp:872:5:872:8 | ref arg url2 | atl.cpp:873:10:873:13 | url2 | | +| atl.cpp:872:5:872:8 | ref arg url2 | atl.cpp:874:3:874:3 | url2 | | +| atl.cpp:876:10:876:13 | call to CUrl | atl.cpp:877:5:877:8 | url2 | | +| atl.cpp:876:10:876:13 | call to CUrl | atl.cpp:878:10:878:13 | url2 | | +| atl.cpp:876:10:876:13 | call to CUrl | atl.cpp:879:3:879:3 | url2 | | +| atl.cpp:877:5:877:8 | ref arg url2 | atl.cpp:878:10:878:13 | url2 | | +| atl.cpp:877:5:877:8 | ref arg url2 | atl.cpp:879:3:879:3 | url2 | | +| atl.cpp:881:10:881:13 | call to CUrl | atl.cpp:882:5:882:8 | url2 | | +| atl.cpp:881:10:881:13 | call to CUrl | atl.cpp:883:10:883:13 | url2 | | +| atl.cpp:881:10:881:13 | call to CUrl | atl.cpp:884:3:884:3 | url2 | | +| atl.cpp:882:5:882:8 | ref arg url2 | atl.cpp:883:10:883:13 | url2 | | +| atl.cpp:882:5:882:8 | ref arg url2 | atl.cpp:884:3:884:3 | url2 | | +| atl.cpp:886:10:886:13 | call to CUrl | atl.cpp:887:5:887:8 | url2 | | +| atl.cpp:886:10:886:13 | call to CUrl | atl.cpp:888:10:888:13 | url2 | | +| atl.cpp:886:10:886:13 | call to CUrl | atl.cpp:889:3:889:3 | url2 | | +| atl.cpp:887:5:887:8 | ref arg url2 | atl.cpp:888:10:888:13 | url2 | | +| atl.cpp:887:5:887:8 | ref arg url2 | atl.cpp:889:3:889:3 | url2 | | +| atl.cpp:891:10:891:13 | call to CUrl | atl.cpp:892:5:892:8 | url2 | | +| atl.cpp:891:10:891:13 | call to CUrl | atl.cpp:893:10:893:13 | url2 | | +| atl.cpp:891:10:891:13 | call to CUrl | atl.cpp:894:3:894:3 | url2 | | +| atl.cpp:892:5:892:8 | ref arg url2 | atl.cpp:893:10:893:13 | url2 | | +| atl.cpp:892:5:892:8 | ref arg url2 | atl.cpp:894:3:894:3 | url2 | | +| atl.cpp:896:10:896:13 | call to CUrl | atl.cpp:897:5:897:8 | url2 | | +| atl.cpp:896:10:896:13 | call to CUrl | atl.cpp:898:10:898:13 | url2 | | +| atl.cpp:896:10:896:13 | call to CUrl | atl.cpp:899:3:899:3 | url2 | | +| atl.cpp:897:5:897:8 | ref arg url2 | atl.cpp:898:10:898:13 | url2 | | +| atl.cpp:897:5:897:8 | ref arg url2 | atl.cpp:899:3:899:3 | url2 | | | bsd.cpp:17:11:17:16 | call to source | bsd.cpp:20:18:20:18 | s | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:20:22:20:25 | addr | | | bsd.cpp:18:12:18:15 | addr | bsd.cpp:23:8:23:11 | addr | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 0d121219209a..7e8a52fdb35b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -1,78 +1,78 @@ signatureMatches -| atl.cpp:68:3:68:15 | _U_STRINGorID | (UINT) | CComBSTR | LoadString | 0 | -| atl.cpp:68:3:68:15 | _U_STRINGorID | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:69:3:69:15 | _U_STRINGorID | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:256:3:256:10 | CAtlList | (UINT) | CComBSTR | LoadString | 0 | -| atl.cpp:256:3:256:10 | CAtlList | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:410:3:410:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 0 | -| atl.cpp:410:3:410:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 1 | -| atl.cpp:411:3:411:10 | CComBSTR | (int,LPCSTR) | CComBSTR | CComBSTR | 0 | -| atl.cpp:411:3:411:10 | CComBSTR | (int,LPCSTR) | CComBSTR | CComBSTR | 1 | -| atl.cpp:412:3:412:10 | CComBSTR | (LPCOLESTR) | CComBSTR | Append | 0 | -| atl.cpp:412:3:412:10 | CComBSTR | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | -| atl.cpp:413:3:413:10 | CComBSTR | (LPCSTR) | CComBSTR | Append | 0 | -| atl.cpp:413:3:413:10 | CComBSTR | (LPCSTR) | CComBSTR | CComBSTR | 0 | -| atl.cpp:418:11:418:16 | Append | (wchar_t) | CComBSTR | Append | 0 | -| atl.cpp:419:11:419:16 | Append | (char) | CComBSTR | Append | 0 | -| atl.cpp:420:11:420:16 | Append | (LPCOLESTR) | CComBSTR | Append | 0 | -| atl.cpp:420:11:420:16 | Append | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | -| atl.cpp:421:11:421:16 | Append | (LPCSTR) | CComBSTR | Append | 0 | -| atl.cpp:421:11:421:16 | Append | (LPCSTR) | CComBSTR | CComBSTR | 0 | -| atl.cpp:422:11:422:16 | Append | (LPCOLESTR,int) | CComBSTR | Append | 0 | -| atl.cpp:422:11:422:16 | Append | (LPCOLESTR,int) | CComBSTR | Append | 1 | -| atl.cpp:424:11:424:21 | AppendBytes | (LPCOLESTR,int) | CComBSTR | Append | 1 | -| atl.cpp:425:11:425:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | Add | 0 | -| atl.cpp:425:11:425:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | -| atl.cpp:425:11:425:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | -| atl.cpp:437:8:437:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 0 | -| atl.cpp:437:8:437:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 1 | -| atl.cpp:437:8:437:17 | LoadString | (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 1 | -| atl.cpp:438:8:438:17 | LoadString | (UINT) | CComBSTR | LoadString | 0 | -| atl.cpp:438:8:438:17 | LoadString | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:447:13:447:22 | operator+= | (LPCOLESTR) | CComBSTR | Append | 0 | -| atl.cpp:447:13:447:22 | operator+= | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | -| atl.cpp:537:3:537:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | Add | 0 | -| atl.cpp:537:3:537:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | -| atl.cpp:537:3:537:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | -| atl.cpp:541:11:541:13 | Add | (const SAFEARRAY *) | CComSafeArray | Add | 0 | -| atl.cpp:541:11:541:13 | Add | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | -| atl.cpp:541:11:541:13 | Add | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | -| atl.cpp:543:11:543:13 | Add | (const T &,BOOL) | CComSafeArray | Add | 0 | -| atl.cpp:543:11:543:13 | Add | (const T &,BOOL) | CComSafeArray | Add | 1 | -| atl.cpp:762:8:762:10 | Add | (const deque &,const Allocator &) | deque | deque | 1 | -| atl.cpp:762:8:762:10 | Add | (const forward_list &,const Allocator &) | forward_list | forward_list | 1 | -| atl.cpp:762:8:762:10 | Add | (const list &,const Allocator &) | list | list | 1 | -| atl.cpp:762:8:762:10 | Add | (const vector &,const Allocator &) | vector | vector | 1 | -| atl.cpp:762:8:762:10 | Add | (deque &&,const Allocator &) | deque | deque | 1 | -| atl.cpp:762:8:762:10 | Add | (forward_list &&,const Allocator &) | forward_list | forward_list | 1 | -| atl.cpp:762:8:762:10 | Add | (list &&,const Allocator &) | list | list | 1 | -| atl.cpp:762:8:762:10 | Add | (vector &&,const Allocator &) | vector | vector | 1 | -| atl.cpp:773:8:773:12 | SetAt | (const deque &,const Allocator &) | deque | deque | 1 | -| atl.cpp:773:8:773:12 | SetAt | (const forward_list &,const Allocator &) | forward_list | forward_list | 1 | -| atl.cpp:773:8:773:12 | SetAt | (const list &,const Allocator &) | list | list | 1 | -| atl.cpp:773:8:773:12 | SetAt | (const vector &,const Allocator &) | vector | vector | 1 | -| atl.cpp:773:8:773:12 | SetAt | (deque &&,const Allocator &) | deque | deque | 1 | -| atl.cpp:773:8:773:12 | SetAt | (forward_list &&,const Allocator &) | forward_list | forward_list | 1 | -| atl.cpp:773:8:773:12 | SetAt | (list &&,const Allocator &) | list | list | 1 | -| atl.cpp:773:8:773:12 | SetAt | (vector &&,const Allocator &) | vector | vector | 1 | -| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | deque | deque | 2 | -| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | forward_list | forward_list | 2 | -| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | list | list | 2 | -| atl.cpp:774:8:774:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | vector | vector | 2 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | deque | deque | 1 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | deque | deque | 2 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | forward_list | forward_list | 1 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | forward_list | forward_list | 2 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | list | list | 1 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | list | list | 2 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | vector | vector | 1 | -| atl.cpp:774:8:774:17 | SetAtIndex | (size_type,const T &,const Allocator &) | vector | vector | 2 | -| atl.cpp:839:15:839:26 | SetExtraInfo | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:840:15:840:25 | SetHostName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:841:15:841:25 | SetPassword | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:844:15:844:27 | SetSchemeName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:845:15:845:24 | SetUrlPath | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | -| atl.cpp:846:15:846:25 | SetUserName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:69:3:69:15 | _U_STRINGorID | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:69:3:69:15 | _U_STRINGorID | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:70:3:70:15 | _U_STRINGorID | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:257:3:257:10 | CAtlList | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:257:3:257:10 | CAtlList | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:411:3:411:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:411:3:411:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 1 | +| atl.cpp:412:3:412:10 | CComBSTR | (int,LPCSTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:412:3:412:10 | CComBSTR | (int,LPCSTR) | CComBSTR | CComBSTR | 1 | +| atl.cpp:413:3:413:10 | CComBSTR | (LPCOLESTR) | CComBSTR | Append | 0 | +| atl.cpp:413:3:413:10 | CComBSTR | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:414:3:414:10 | CComBSTR | (LPCSTR) | CComBSTR | Append | 0 | +| atl.cpp:414:3:414:10 | CComBSTR | (LPCSTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:419:11:419:16 | Append | (wchar_t) | CComBSTR | Append | 0 | +| atl.cpp:420:11:420:16 | Append | (char) | CComBSTR | Append | 0 | +| atl.cpp:421:11:421:16 | Append | (LPCOLESTR) | CComBSTR | Append | 0 | +| atl.cpp:421:11:421:16 | Append | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:422:11:422:16 | Append | (LPCSTR) | CComBSTR | Append | 0 | +| atl.cpp:422:11:422:16 | Append | (LPCSTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:423:11:423:16 | Append | (LPCOLESTR,int) | CComBSTR | Append | 0 | +| atl.cpp:423:11:423:16 | Append | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| atl.cpp:425:11:425:21 | AppendBytes | (LPCOLESTR,int) | CComBSTR | Append | 1 | +| atl.cpp:426:11:426:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | Add | 0 | +| atl.cpp:426:11:426:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | +| atl.cpp:426:11:426:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | +| atl.cpp:438:8:438:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:438:8:438:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 1 | +| atl.cpp:438:8:438:17 | LoadString | (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 1 | +| atl.cpp:439:8:439:17 | LoadString | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:439:8:439:17 | LoadString | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:448:13:448:22 | operator+= | (LPCOLESTR) | CComBSTR | Append | 0 | +| atl.cpp:448:13:448:22 | operator+= | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:538:3:538:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | Add | 0 | +| atl.cpp:538:3:538:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | +| atl.cpp:538:3:538:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | +| atl.cpp:542:11:542:13 | Add | (const SAFEARRAY *) | CComSafeArray | Add | 0 | +| atl.cpp:542:11:542:13 | Add | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | +| atl.cpp:542:11:542:13 | Add | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | +| atl.cpp:544:11:544:13 | Add | (const T &,BOOL) | CComSafeArray | Add | 0 | +| atl.cpp:544:11:544:13 | Add | (const T &,BOOL) | CComSafeArray | Add | 1 | +| atl.cpp:763:8:763:10 | Add | (const deque &,const Allocator &) | deque | deque | 1 | +| atl.cpp:763:8:763:10 | Add | (const forward_list &,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:763:8:763:10 | Add | (const list &,const Allocator &) | list | list | 1 | +| atl.cpp:763:8:763:10 | Add | (const vector &,const Allocator &) | vector | vector | 1 | +| atl.cpp:763:8:763:10 | Add | (deque &&,const Allocator &) | deque | deque | 1 | +| atl.cpp:763:8:763:10 | Add | (forward_list &&,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:763:8:763:10 | Add | (list &&,const Allocator &) | list | list | 1 | +| atl.cpp:763:8:763:10 | Add | (vector &&,const Allocator &) | vector | vector | 1 | +| atl.cpp:774:8:774:12 | SetAt | (const deque &,const Allocator &) | deque | deque | 1 | +| atl.cpp:774:8:774:12 | SetAt | (const forward_list &,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:774:8:774:12 | SetAt | (const list &,const Allocator &) | list | list | 1 | +| atl.cpp:774:8:774:12 | SetAt | (const vector &,const Allocator &) | vector | vector | 1 | +| atl.cpp:774:8:774:12 | SetAt | (deque &&,const Allocator &) | deque | deque | 1 | +| atl.cpp:774:8:774:12 | SetAt | (forward_list &&,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:774:8:774:12 | SetAt | (list &&,const Allocator &) | list | list | 1 | +| atl.cpp:774:8:774:12 | SetAt | (vector &&,const Allocator &) | vector | vector | 1 | +| atl.cpp:775:8:775:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | deque | deque | 2 | +| atl.cpp:775:8:775:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | forward_list | forward_list | 2 | +| atl.cpp:775:8:775:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | list | list | 2 | +| atl.cpp:775:8:775:17 | SetAtIndex | (InputIterator,InputIterator,const Allocator &) | vector | vector | 2 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | deque | deque | 1 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | deque | deque | 2 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | forward_list | forward_list | 1 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | forward_list | forward_list | 2 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | list | list | 1 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | list | list | 2 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | vector | vector | 1 | +| atl.cpp:775:8:775:17 | SetAtIndex | (size_type,const T &,const Allocator &) | vector | vector | 2 | +| atl.cpp:840:15:840:26 | SetExtraInfo | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:841:15:841:25 | SetHostName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:842:15:842:25 | SetPassword | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:845:15:845:27 | SetSchemeName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:846:15:846:24 | SetUrlPath | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:847:15:847:25 | SetUserName | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | | constructor_delegation.cpp:10:2:10:8 | MyValue | (LPCOLESTR,int) | CComBSTR | Append | 1 | | constructor_delegation.cpp:19:2:19:15 | MyDerivedValue | (LPCOLESTR,int) | CComBSTR | Append | 1 | | standalone_iterators.cpp:103:27:103:36 | operator+= | (LPCOLESTR,int) | CComBSTR | Append | 1 | @@ -518,134 +518,134 @@ getParameterTypeName | arrayassignment.cpp:124:6:124:9 | sink | 0 | int * | | atl.cpp:28:8:28:8 | operator= | 0 | __POSITION && | | atl.cpp:28:8:28:8 | operator= | 0 | const __POSITION & | -| atl.cpp:49:16:49:16 | operator= | 0 | const tagSAFEARRAYBOUND & | -| atl.cpp:49:16:49:16 | operator= | 0 | tagSAFEARRAYBOUND && | -| atl.cpp:54:16:54:16 | operator= | 0 | const tagVARIANT & | -| atl.cpp:54:16:54:16 | operator= | 0 | tagVARIANT && | -| atl.cpp:58:16:58:16 | operator= | 0 | const tagSAFEARRAY & | -| atl.cpp:58:16:58:16 | operator= | 0 | tagSAFEARRAY && | -| atl.cpp:67:8:67:8 | _U_STRINGorID | 0 | _U_STRINGorID && | -| atl.cpp:67:8:67:8 | _U_STRINGorID | 0 | const _U_STRINGorID & | -| atl.cpp:67:8:67:8 | operator= | 0 | _U_STRINGorID && | -| atl.cpp:67:8:67:8 | operator= | 0 | const _U_STRINGorID & | -| atl.cpp:68:3:68:15 | _U_STRINGorID | 0 | UINT | -| atl.cpp:69:3:69:15 | _U_STRINGorID | 0 | LPCTSTR | -| atl.cpp:193:10:193:12 | Add | 0 | INARGTYPclass:0 | -| atl.cpp:195:10:195:15 | Append | 0 | const CAtlArray & | -| atl.cpp:196:8:196:11 | Copy | 0 | const CAtlArray & | -| atl.cpp:198:6:198:10 | GetAt | 0 | size_t | -| atl.cpp:202:8:202:20 | InsertArrayAt | 0 | size_t | -| atl.cpp:202:8:202:20 | InsertArrayAt | 1 | const CAtlArray * | -| atl.cpp:203:8:203:15 | InsertAt | 0 | size_t | -| atl.cpp:203:8:203:15 | InsertAt | 1 | INARGTYPclass:0 | -| atl.cpp:203:8:203:15 | InsertAt | 2 | size_t | -| atl.cpp:208:8:208:16 | SetAtGrow | 0 | size_t | -| atl.cpp:208:8:208:16 | SetAtGrow | 1 | INARGTYPclass:0 | -| atl.cpp:210:6:210:15 | operator[] | 0 | size_t | -| atl.cpp:256:3:256:10 | CAtlList | 0 | UINT | -| atl.cpp:259:12:259:18 | AddHead | 0 | INARGTYPclass:0 | -| atl.cpp:260:8:260:18 | AddHeadList | 0 | const CAtlList * | -| atl.cpp:262:12:262:18 | AddTail | 0 | INARGTYPclass:0 | -| atl.cpp:263:8:263:18 | AddTailList | 0 | const CAtlList * | -| atl.cpp:264:12:264:15 | Find | 0 | INARGTYPclass:0 | -| atl.cpp:264:12:264:15 | Find | 1 | POSITION | -| atl.cpp:265:12:265:20 | FindIndex | 0 | size_t | -| atl.cpp:266:6:266:10 | GetAt | 0 | POSITION | -| atl.cpp:279:12:279:22 | InsertAfter | 0 | POSITION | -| atl.cpp:279:12:279:22 | InsertAfter | 1 | INARGTYPclass:0 | -| atl.cpp:280:12:280:23 | InsertBefore | 0 | POSITION | -| atl.cpp:280:12:280:23 | InsertBefore | 1 | INARGTYPclass:0 | -| atl.cpp:290:8:290:12 | SetAt | 0 | POSITION | -| atl.cpp:290:8:290:12 | SetAt | 1 | INARGTYPclass:0 | -| atl.cpp:400:8:400:8 | operator= | 0 | IUnknown && | -| atl.cpp:400:8:400:8 | operator= | 0 | const IUnknown & | -| atl.cpp:402:8:402:8 | operator= | 0 | ISequentialStream && | -| atl.cpp:402:8:402:8 | operator= | 0 | const ISequentialStream & | -| atl.cpp:404:8:404:8 | operator= | 0 | IStream && | -| atl.cpp:404:8:404:8 | operator= | 0 | const IStream & | -| atl.cpp:406:8:406:8 | operator= | 0 | const CComBSTR & | -| atl.cpp:408:3:408:10 | CComBSTR | 0 | const CComBSTR & | -| atl.cpp:409:3:409:10 | CComBSTR | 0 | int | +| atl.cpp:50:16:50:16 | operator= | 0 | const tagSAFEARRAYBOUND & | +| atl.cpp:50:16:50:16 | operator= | 0 | tagSAFEARRAYBOUND && | +| atl.cpp:55:16:55:16 | operator= | 0 | const tagVARIANT & | +| atl.cpp:55:16:55:16 | operator= | 0 | tagVARIANT && | +| atl.cpp:59:16:59:16 | operator= | 0 | const tagSAFEARRAY & | +| atl.cpp:59:16:59:16 | operator= | 0 | tagSAFEARRAY && | +| atl.cpp:68:8:68:8 | _U_STRINGorID | 0 | _U_STRINGorID && | +| atl.cpp:68:8:68:8 | _U_STRINGorID | 0 | const _U_STRINGorID & | +| atl.cpp:68:8:68:8 | operator= | 0 | _U_STRINGorID && | +| atl.cpp:68:8:68:8 | operator= | 0 | const _U_STRINGorID & | +| atl.cpp:69:3:69:15 | _U_STRINGorID | 0 | UINT | +| atl.cpp:70:3:70:15 | _U_STRINGorID | 0 | LPCTSTR | +| atl.cpp:194:10:194:12 | Add | 0 | INARGTYPclass:0 | +| atl.cpp:196:10:196:15 | Append | 0 | const CAtlArray & | +| atl.cpp:197:8:197:11 | Copy | 0 | const CAtlArray & | +| atl.cpp:199:6:199:10 | GetAt | 0 | size_t | +| atl.cpp:203:8:203:20 | InsertArrayAt | 0 | size_t | +| atl.cpp:203:8:203:20 | InsertArrayAt | 1 | const CAtlArray * | +| atl.cpp:204:8:204:15 | InsertAt | 0 | size_t | +| atl.cpp:204:8:204:15 | InsertAt | 1 | INARGTYPclass:0 | +| atl.cpp:204:8:204:15 | InsertAt | 2 | size_t | +| atl.cpp:209:8:209:16 | SetAtGrow | 0 | size_t | +| atl.cpp:209:8:209:16 | SetAtGrow | 1 | INARGTYPclass:0 | +| atl.cpp:211:6:211:15 | operator[] | 0 | size_t | +| atl.cpp:257:3:257:10 | CAtlList | 0 | UINT | +| atl.cpp:260:12:260:18 | AddHead | 0 | INARGTYPclass:0 | +| atl.cpp:261:8:261:18 | AddHeadList | 0 | const CAtlList * | +| atl.cpp:263:12:263:18 | AddTail | 0 | INARGTYPclass:0 | +| atl.cpp:264:8:264:18 | AddTailList | 0 | const CAtlList * | +| atl.cpp:265:12:265:15 | Find | 0 | INARGTYPclass:0 | +| atl.cpp:265:12:265:15 | Find | 1 | POSITION | +| atl.cpp:266:12:266:20 | FindIndex | 0 | size_t | +| atl.cpp:267:6:267:10 | GetAt | 0 | POSITION | +| atl.cpp:280:12:280:22 | InsertAfter | 0 | POSITION | +| atl.cpp:280:12:280:22 | InsertAfter | 1 | INARGTYPclass:0 | +| atl.cpp:281:12:281:23 | InsertBefore | 0 | POSITION | +| atl.cpp:281:12:281:23 | InsertBefore | 1 | INARGTYPclass:0 | +| atl.cpp:291:8:291:12 | SetAt | 0 | POSITION | +| atl.cpp:291:8:291:12 | SetAt | 1 | INARGTYPclass:0 | +| atl.cpp:401:8:401:8 | operator= | 0 | IUnknown && | +| atl.cpp:401:8:401:8 | operator= | 0 | const IUnknown & | +| atl.cpp:403:8:403:8 | operator= | 0 | ISequentialStream && | +| atl.cpp:403:8:403:8 | operator= | 0 | const ISequentialStream & | +| atl.cpp:405:8:405:8 | operator= | 0 | IStream && | +| atl.cpp:405:8:405:8 | operator= | 0 | const IStream & | +| atl.cpp:407:8:407:8 | operator= | 0 | const CComBSTR & | +| atl.cpp:409:3:409:10 | CComBSTR | 0 | const CComBSTR & | | atl.cpp:410:3:410:10 | CComBSTR | 0 | int | -| atl.cpp:410:3:410:10 | CComBSTR | 1 | LPCOLESTR | | atl.cpp:411:3:411:10 | CComBSTR | 0 | int | -| atl.cpp:411:3:411:10 | CComBSTR | 1 | LPCSTR | -| atl.cpp:412:3:412:10 | CComBSTR | 0 | LPCOLESTR | -| atl.cpp:413:3:413:10 | CComBSTR | 0 | LPCSTR | -| atl.cpp:414:3:414:10 | CComBSTR | 0 | CComBSTR && | -| atl.cpp:417:11:417:16 | Append | 0 | const CComBSTR & | -| atl.cpp:418:11:418:16 | Append | 0 | wchar_t | -| atl.cpp:419:11:419:16 | Append | 0 | char | -| atl.cpp:420:11:420:16 | Append | 0 | LPCOLESTR | -| atl.cpp:421:11:421:16 | Append | 0 | LPCSTR | -| atl.cpp:422:11:422:16 | Append | 0 | LPCOLESTR | -| atl.cpp:422:11:422:16 | Append | 1 | int | -| atl.cpp:423:11:423:20 | AppendBSTR | 0 | BSTR | -| atl.cpp:424:11:424:21 | AppendBytes | 0 | const char * | -| atl.cpp:424:11:424:21 | AppendBytes | 1 | int | -| atl.cpp:425:11:425:21 | ArrayToBSTR | 0 | const SAFEARRAY * | -| atl.cpp:426:11:426:20 | AssignBSTR | 0 | const BSTR | -| atl.cpp:427:8:427:13 | Attach | 0 | BSTR | -| atl.cpp:428:11:428:21 | BSTRToArray | 0 | LPSAFEARRAY | -| atl.cpp:431:11:431:16 | CopyTo | 0 | BSTR * | -| atl.cpp:433:11:433:16 | CopyTo | 0 | VARIANT * | -| atl.cpp:437:8:437:17 | LoadString | 0 | HINSTANCE | -| atl.cpp:437:8:437:17 | LoadString | 1 | UINT | -| atl.cpp:438:8:438:17 | LoadString | 0 | UINT | -| atl.cpp:439:11:439:24 | ReadFromStream | 0 | IStream * | -| atl.cpp:441:11:441:23 | WriteToStream | 0 | IStream * | -| atl.cpp:446:13:446:22 | operator+= | 0 | const CComBSTR & | -| atl.cpp:447:13:447:22 | operator+= | 0 | LPCOLESTR | -| atl.cpp:537:3:537:15 | CComSafeArray | 0 | const SAFEARRAY * | -| atl.cpp:541:11:541:13 | Add | 0 | const SAFEARRAY * | -| atl.cpp:543:11:543:13 | Add | 0 | const class:0 & | -| atl.cpp:543:11:543:13 | Add | 1 | BOOL | -| atl.cpp:551:6:551:10 | GetAt | 0 | LONG | -| atl.cpp:562:11:562:15 | SetAt | 0 | LONG | -| atl.cpp:562:11:562:15 | SetAt | 1 | const class:0 & | -| atl.cpp:562:11:562:15 | SetAt | 2 | BOOL | -| atl.cpp:564:6:564:15 | operator[] | 0 | long | -| atl.cpp:565:6:565:15 | operator[] | 0 | int | -| atl.cpp:609:3:609:8 | CPathT | 0 | PCXSTR | -| atl.cpp:610:3:610:8 | CPathT | 0 | const CPathT & | -| atl.cpp:614:8:614:19 | AddExtension | 0 | PCXSTR | -| atl.cpp:615:8:615:13 | Append | 0 | PCXSTR | -| atl.cpp:618:8:618:14 | Combine | 0 | PCXSTR | -| atl.cpp:618:8:618:14 | Combine | 1 | PCXSTR | -| atl.cpp:619:22:619:33 | CommonPrefix | 0 | PCXSTR | -| atl.cpp:656:23:656:32 | operator+= | 0 | PCXSTR | -| atl.cpp:716:8:716:10 | Add | 0 | const class:0 & | -| atl.cpp:717:7:717:10 | Find | 0 | const class:0 & | -| atl.cpp:728:6:728:15 | operator[] | 0 | int | -| atl.cpp:729:21:729:29 | operator= | 0 | const CSimpleArray & | -| atl.cpp:762:8:762:10 | Add | 0 | const class:0 & | -| atl.cpp:762:8:762:10 | Add | 1 | const class:1 & | -| atl.cpp:763:7:763:13 | FindKey | 0 | const class:0 & | -| atl.cpp:764:7:764:13 | FindVal | 0 | const class:1 & | -| atl.cpp:767:9:767:18 | GetValueAt | 0 | int | -| atl.cpp:768:8:768:13 | Lookup | 0 | const class:0 & | -| atl.cpp:772:8:772:20 | ReverseLookup | 0 | const class:1 & | -| atl.cpp:773:8:773:12 | SetAt | 0 | const class:0 & | -| atl.cpp:773:8:773:12 | SetAt | 1 | const class:1 & | -| atl.cpp:774:8:774:17 | SetAtIndex | 0 | int | -| atl.cpp:774:8:774:17 | SetAtIndex | 1 | const class:0 & | -| atl.cpp:774:8:774:17 | SetAtIndex | 2 | const class:1 & | -| atl.cpp:813:9:813:17 | operator= | 0 | const CUrl & | -| atl.cpp:815:3:815:6 | CUrl | 0 | const CUrl & | -| atl.cpp:818:15:818:26 | Canonicalize | 0 | DWORD | -| atl.cpp:821:8:821:15 | CrackUrl | 0 | LPCTSTR | -| atl.cpp:821:8:821:15 | CrackUrl | 1 | DWORD | -| atl.cpp:822:15:822:23 | CreateUrl | 0 | LPTSTR | -| atl.cpp:822:15:822:23 | CreateUrl | 1 | DWORD * | -| atl.cpp:822:15:822:23 | CreateUrl | 2 | DWORD | -| atl.cpp:839:15:839:26 | SetExtraInfo | 0 | LPCTSTR | -| atl.cpp:840:15:840:25 | SetHostName | 0 | LPCTSTR | -| atl.cpp:841:15:841:25 | SetPassword | 0 | LPCTSTR | -| atl.cpp:842:15:842:27 | SetPortNumber | 0 | ATL_URL_PORT | -| atl.cpp:843:15:843:23 | SetScheme | 0 | ATL_URL_SCHEME | -| atl.cpp:844:15:844:27 | SetSchemeName | 0 | LPCTSTR | -| atl.cpp:845:15:845:24 | SetUrlPath | 0 | LPCTSTR | -| atl.cpp:846:15:846:25 | SetUserName | 0 | LPCTSTR | +| atl.cpp:411:3:411:10 | CComBSTR | 1 | LPCOLESTR | +| atl.cpp:412:3:412:10 | CComBSTR | 0 | int | +| atl.cpp:412:3:412:10 | CComBSTR | 1 | LPCSTR | +| atl.cpp:413:3:413:10 | CComBSTR | 0 | LPCOLESTR | +| atl.cpp:414:3:414:10 | CComBSTR | 0 | LPCSTR | +| atl.cpp:415:3:415:10 | CComBSTR | 0 | CComBSTR && | +| atl.cpp:418:11:418:16 | Append | 0 | const CComBSTR & | +| atl.cpp:419:11:419:16 | Append | 0 | wchar_t | +| atl.cpp:420:11:420:16 | Append | 0 | char | +| atl.cpp:421:11:421:16 | Append | 0 | LPCOLESTR | +| atl.cpp:422:11:422:16 | Append | 0 | LPCSTR | +| atl.cpp:423:11:423:16 | Append | 0 | LPCOLESTR | +| atl.cpp:423:11:423:16 | Append | 1 | int | +| atl.cpp:424:11:424:20 | AppendBSTR | 0 | BSTR | +| atl.cpp:425:11:425:21 | AppendBytes | 0 | const char * | +| atl.cpp:425:11:425:21 | AppendBytes | 1 | int | +| atl.cpp:426:11:426:21 | ArrayToBSTR | 0 | const SAFEARRAY * | +| atl.cpp:427:11:427:20 | AssignBSTR | 0 | const BSTR | +| atl.cpp:428:8:428:13 | Attach | 0 | BSTR | +| atl.cpp:429:11:429:21 | BSTRToArray | 0 | LPSAFEARRAY | +| atl.cpp:432:11:432:16 | CopyTo | 0 | BSTR * | +| atl.cpp:434:11:434:16 | CopyTo | 0 | VARIANT * | +| atl.cpp:438:8:438:17 | LoadString | 0 | HINSTANCE | +| atl.cpp:438:8:438:17 | LoadString | 1 | UINT | +| atl.cpp:439:8:439:17 | LoadString | 0 | UINT | +| atl.cpp:440:11:440:24 | ReadFromStream | 0 | IStream * | +| atl.cpp:442:11:442:23 | WriteToStream | 0 | IStream * | +| atl.cpp:447:13:447:22 | operator+= | 0 | const CComBSTR & | +| atl.cpp:448:13:448:22 | operator+= | 0 | LPCOLESTR | +| atl.cpp:538:3:538:15 | CComSafeArray | 0 | const SAFEARRAY * | +| atl.cpp:542:11:542:13 | Add | 0 | const SAFEARRAY * | +| atl.cpp:544:11:544:13 | Add | 0 | const class:0 & | +| atl.cpp:544:11:544:13 | Add | 1 | BOOL | +| atl.cpp:552:6:552:10 | GetAt | 0 | LONG | +| atl.cpp:563:11:563:15 | SetAt | 0 | LONG | +| atl.cpp:563:11:563:15 | SetAt | 1 | const class:0 & | +| atl.cpp:563:11:563:15 | SetAt | 2 | BOOL | +| atl.cpp:565:6:565:15 | operator[] | 0 | long | +| atl.cpp:566:6:566:15 | operator[] | 0 | int | +| atl.cpp:610:3:610:8 | CPathT | 0 | PCXSTR | +| atl.cpp:611:3:611:8 | CPathT | 0 | const CPathT & | +| atl.cpp:615:8:615:19 | AddExtension | 0 | PCXSTR | +| atl.cpp:616:8:616:13 | Append | 0 | PCXSTR | +| atl.cpp:619:8:619:14 | Combine | 0 | PCXSTR | +| atl.cpp:619:8:619:14 | Combine | 1 | PCXSTR | +| atl.cpp:620:22:620:33 | CommonPrefix | 0 | PCXSTR | +| atl.cpp:657:23:657:32 | operator+= | 0 | PCXSTR | +| atl.cpp:717:8:717:10 | Add | 0 | const class:0 & | +| atl.cpp:718:7:718:10 | Find | 0 | const class:0 & | +| atl.cpp:729:6:729:15 | operator[] | 0 | int | +| atl.cpp:730:21:730:29 | operator= | 0 | const CSimpleArray & | +| atl.cpp:763:8:763:10 | Add | 0 | const class:0 & | +| atl.cpp:763:8:763:10 | Add | 1 | const class:1 & | +| atl.cpp:764:7:764:13 | FindKey | 0 | const class:0 & | +| atl.cpp:765:7:765:13 | FindVal | 0 | const class:1 & | +| atl.cpp:768:9:768:18 | GetValueAt | 0 | int | +| atl.cpp:769:8:769:13 | Lookup | 0 | const class:0 & | +| atl.cpp:773:8:773:20 | ReverseLookup | 0 | const class:1 & | +| atl.cpp:774:8:774:12 | SetAt | 0 | const class:0 & | +| atl.cpp:774:8:774:12 | SetAt | 1 | const class:1 & | +| atl.cpp:775:8:775:17 | SetAtIndex | 0 | int | +| atl.cpp:775:8:775:17 | SetAtIndex | 1 | const class:0 & | +| atl.cpp:775:8:775:17 | SetAtIndex | 2 | const class:1 & | +| atl.cpp:814:9:814:17 | operator= | 0 | const CUrl & | +| atl.cpp:816:3:816:6 | CUrl | 0 | const CUrl & | +| atl.cpp:819:15:819:26 | Canonicalize | 0 | DWORD | +| atl.cpp:822:8:822:15 | CrackUrl | 0 | LPCTSTR | +| atl.cpp:822:8:822:15 | CrackUrl | 1 | DWORD | +| atl.cpp:823:15:823:23 | CreateUrl | 0 | LPTSTR | +| atl.cpp:823:15:823:23 | CreateUrl | 1 | DWORD * | +| atl.cpp:823:15:823:23 | CreateUrl | 2 | DWORD | +| atl.cpp:840:15:840:26 | SetExtraInfo | 0 | LPCTSTR | +| atl.cpp:841:15:841:25 | SetHostName | 0 | LPCTSTR | +| atl.cpp:842:15:842:25 | SetPassword | 0 | LPCTSTR | +| atl.cpp:843:15:843:27 | SetPortNumber | 0 | ATL_URL_PORT | +| atl.cpp:844:15:844:23 | SetScheme | 0 | ATL_URL_SCHEME | +| atl.cpp:845:15:845:27 | SetSchemeName | 0 | LPCTSTR | +| atl.cpp:846:15:846:24 | SetUrlPath | 0 | LPCTSTR | +| atl.cpp:847:15:847:25 | SetUserName | 0 | LPCTSTR | | bsd.cpp:6:8:6:8 | operator= | 0 | const sockaddr & | | bsd.cpp:6:8:6:8 | operator= | 0 | sockaddr && | | bsd.cpp:12:5:12:10 | accept | 0 | int | From 3abb9049bb1fb9d3aa8031b42c4621ad0de7224e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 3 Dec 2024 19:06:20 +0000 Subject: [PATCH 050/213] C++: Fix testcase to reveal problematic models. --- .../library-tests/dataflow/taint-tests/atl.cpp | 4 ++-- .../dataflow/taint-tests/localTaint.expected | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index d8f5da016330..0fb0456daa45 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -682,11 +682,11 @@ void test_CPathT() { CPath p2; p2 += p; - sink(p.m_strPath); // $ ir + sink(p2.m_strPath); // $ MISSING: ir CPath p3; p3 += x; - sink(p.m_strPath); // $ ir + sink(p3.m_strPath); // $ MISSING: ir } { diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index c8a2ee98665e..41c3822aed52 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -761,28 +761,20 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:680:5:680:5 | p | | | atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:681:10:681:10 | p | | | atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:684:11:684:11 | p | | -| atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:685:10:685:10 | p | | -| atl.cpp:679:11:679:11 | call to CPathT | atl.cpp:689:10:689:10 | p | | | atl.cpp:680:5:680:5 | ref arg p | atl.cpp:681:10:681:10 | p | | | atl.cpp:680:5:680:5 | ref arg p | atl.cpp:684:11:684:11 | p | | -| atl.cpp:680:5:680:5 | ref arg p | atl.cpp:685:10:685:10 | p | | -| atl.cpp:680:5:680:5 | ref arg p | atl.cpp:689:10:689:10 | p | | | atl.cpp:680:14:680:14 | ref arg x | atl.cpp:688:11:688:11 | x | | | atl.cpp:680:14:680:14 | ref arg x | atl.cpp:694:15:694:15 | x | | | atl.cpp:680:14:680:14 | ref arg x | atl.cpp:699:24:699:24 | x | | | atl.cpp:680:14:680:14 | ref arg x | atl.cpp:705:30:705:30 | x | | | atl.cpp:681:10:681:10 | p [post update] | atl.cpp:684:11:684:11 | p | | -| atl.cpp:681:10:681:10 | p [post update] | atl.cpp:685:10:685:10 | p | | -| atl.cpp:681:10:681:10 | p [post update] | atl.cpp:689:10:689:10 | p | | -| atl.cpp:681:12:681:20 | ref arg m_strPath | atl.cpp:685:12:685:20 | m_strPath | | -| atl.cpp:681:12:681:20 | ref arg m_strPath | atl.cpp:689:12:689:20 | m_strPath | | | atl.cpp:683:11:683:12 | call to CPathT | atl.cpp:684:5:684:6 | p2 | | +| atl.cpp:683:11:683:12 | call to CPathT | atl.cpp:685:10:685:11 | p2 | | +| atl.cpp:684:5:684:6 | ref arg p2 | atl.cpp:685:10:685:11 | p2 | | | atl.cpp:684:11:684:11 | call to operator char *& | atl.cpp:684:8:684:8 | call to operator+= | TAINT | -| atl.cpp:684:11:684:11 | ref arg p | atl.cpp:685:10:685:10 | p | | -| atl.cpp:684:11:684:11 | ref arg p | atl.cpp:689:10:689:10 | p | | -| atl.cpp:685:10:685:10 | p [post update] | atl.cpp:689:10:689:10 | p | | -| atl.cpp:685:12:685:20 | ref arg m_strPath | atl.cpp:689:12:689:20 | m_strPath | | | atl.cpp:687:11:687:12 | call to CPathT | atl.cpp:688:5:688:6 | p3 | | +| atl.cpp:687:11:687:12 | call to CPathT | atl.cpp:689:10:689:11 | p3 | | +| atl.cpp:688:5:688:6 | ref arg p3 | atl.cpp:689:10:689:11 | p3 | | | atl.cpp:688:11:688:11 | ref arg x | atl.cpp:694:15:694:15 | x | | | atl.cpp:688:11:688:11 | ref arg x | atl.cpp:699:24:699:24 | x | | | atl.cpp:688:11:688:11 | ref arg x | atl.cpp:705:30:705:30 | x | | From c3086d4ecda3b5c8ba986fb89c9c7ad408daad3b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 3 Dec 2024 19:13:00 +0000 Subject: [PATCH 051/213] C++: Fix models and accept test changes. --- cpp/ql/lib/ext/CPathT.model.yml | 7 ++++--- .../dataflow/external-models/flow.expected | 10 +++++----- .../dataflow/external-models/validatemodels.expected | 1 - cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cpp/ql/lib/ext/CPathT.model.yml b/cpp/ql/lib/ext/CPathT.model.yml index 2138dd6c9425..8211343d479e 100644 --- a/cpp/ql/lib/ext/CPathT.model.yml +++ b/cpp/ql/lib/ext/CPathT.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/cpp-all extensible: summaryModel data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance - - ["", "CPathT", True, "CPathT", "", "", "Argument[*1]", "Argument[-1]", "value", "manual"] + - ["", "CPathT", True, "CPathT", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CPathT", True, "AddExtension", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - ["", "CPathT", True, "Append", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - ["", "CPathT", True, "Combine", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] @@ -18,5 +18,6 @@ extensions: # - ["", "CPathT", True, "operator const T&", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] # - ["", "CPathT", True, "operator T&", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - ["", "CPathT", True, "operator PCXSTR", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - - ["", "CPathT", True, "operator +=", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - - ["", "CPathT", True, "operator +=", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["", "CPathT", True, "operator+=", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] + - ["", "CPathT", True, "operator+=", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"] + - ["", "CPathT", True, "operator+=", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] 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 3c5b69b09f4b..a8a3e5a209a5 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:809 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:807 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:808 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:810 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:808 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:809 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:808 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:809 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:809 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:810 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index 166d834ea768..39dade253254 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -1,4 +1,3 @@ -| Dubious member name "operator +=" in summary model. | | Dubious member name "operator BSTR" in summary model. | | Dubious member name "operator LPCSTR" in summary model. | | Dubious member name "operator LPSAFEARRAY" in summary model. | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 0fb0456daa45..a6638ad3f563 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -682,11 +682,11 @@ void test_CPathT() { CPath p2; p2 += p; - sink(p2.m_strPath); // $ MISSING: ir + sink(p2.m_strPath); // $ MISSING: ir // this requires flow through `operator StringType&()` which we can't yet model in MaD CPath p3; p3 += x; - sink(p3.m_strPath); // $ MISSING: ir + sink(p3.m_strPath); // $ ir } { From 19424020c372f284e7595e3ffbf93341533acf38 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Wed, 4 Dec 2024 10:57:15 +0000 Subject: [PATCH 052/213] C++: Test for erroneous string types --- .../Buildless/WrongTypeFormatArguments.expected | 1 + .../Format/WrongTypeFormatArguments/Buildless/tests.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected index 745f2f790f79..8ff4f02d4d67 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected @@ -1 +1,2 @@ | tests.c:7:18:7:18 | 1 | This format specifier for type 'char *' does not match the argument type 'int'. | +| tests.c:11:18:11:20 | str | This format specifier for type 'char *' does not match the argument type ' *'. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/tests.c b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/tests.c index 81698c497c57..175d2f23182d 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/tests.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/tests.c @@ -3,9 +3,10 @@ int printf(const char * format, ...); int fprintf(); -void f() { +void f(UNKNOWN_CHAR * str) { printf("%s", 1); // BAD printf("%s", implicit_function()); // GOOD - we should ignore the type sprintf(0, "%s", ""); // GOOD fprintf(0, "%s", ""); // GOOD + printf("%s", str); // GOOD - erroneous type is ignored } From 28c5187a3c6505593635b3262e69ca486d87a8d5 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Wed, 4 Dec 2024 11:02:19 +0000 Subject: [PATCH 053/213] C++: Remove FPs in cpp/wrong-type-format-argument when string type is an error --- cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql | 4 ++++ .../Buildless/WrongTypeFormatArguments.expected | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql index 027f4caa8ae4..905c4307ad16 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql @@ -171,6 +171,10 @@ where not arg.isAffectedByMacro() and not arg.isFromUninstantiatedTemplate(_) and not actual.getUnspecifiedType() instanceof ErroneousType and + not ( + expected instanceof PointerType and + actual.getUnspecifiedType().(PointerType).getBaseType() instanceof ErroneousType + ) and not arg.(Call).mayBeFromImplicitlyDeclaredFunction() select arg, "This format specifier for type '" + expected.getName() + "' does not match the argument type '" + diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected index 8ff4f02d4d67..745f2f790f79 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Buildless/WrongTypeFormatArguments.expected @@ -1,2 +1 @@ | tests.c:7:18:7:18 | 1 | This format specifier for type 'char *' does not match the argument type 'int'. | -| tests.c:11:18:11:20 | str | This format specifier for type 'char *' does not match the argument type ' *'. | From 8d035e61a3b744d9a878c18661e2f14e685b780f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 4 Dec 2024 12:33:02 +0000 Subject: [PATCH 054/213] C++: Fix test. --- .../dataflow/taint-tests/atl.cpp | 32 +++--- .../dataflow/taint-tests/localTaint.expected | 102 +++++++++--------- .../taint-tests/test_mad-signatures.expected | 17 +++ 3 files changed, 84 insertions(+), 67 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index a6638ad3f563..05d14c06c362 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -347,52 +347,52 @@ void test_CAtlList() { int* p = indirect_source(); { - CAtlList list(10); + CAtlList list(10); sink(list.GetHead()); - list.AddHead(x); + list.AddHead(p); sink(list.GetHead()); // $ ir - CAtlList list2(10); + CAtlList list2(10); list2.AddHeadList(&list); sink(list2.GetHead()); // $ ir - CAtlList list3(10); - list3.AddTail(x); + CAtlList list3(10); + list3.AddTail(p); sink(list3.GetHead()); // $ ir - CAtlList list4(10); + CAtlList list4(10); list4.AddTailList(&list3); sink(list4.GetHead()); // $ ir { - CAtlList list5(10); - auto pos = list5.Find(x, list5.GetHeadPosition()); + CAtlList list5(10); + auto pos = list5.Find(p, list5.GetHeadPosition()); sink(list5.GetAt(pos)); // $ MISSING: ir } { - CAtlList list6(10); - list6.AddHead(x); + CAtlList list6(10); + list6.AddHead(p); auto pos = list6.FindIndex(0); sink(list6.GetAt(pos)); // $ ir } { - CAtlList list7(10); + CAtlList list7(10); auto pos = list7.GetTailPosition(); - list7.InsertAfter(pos, x); + list7.InsertAfter(pos, p); sink(list7.GetHead()); // $ ir } { - CAtlList list8(10); + CAtlList list8(10); auto pos = list8.GetTailPosition(); - list8.InsertBefore(pos, x); + list8.InsertBefore(pos, p); sink(list8.GetHead()); // $ ir } { - CAtlList list9(10); - list9.SetAt(list9.GetHeadPosition(), x); + CAtlList list9(10); + list9.SetAt(list9.GetHeadPosition(), p); sink(list9.GetHead()); // $ ir } } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 41c3822aed52..a35e1c53d1c5 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -299,13 +299,6 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:296:11:296:21 | call to source | atl.cpp:331:30:331:30 | x | | | atl.cpp:296:11:296:21 | call to source | atl.cpp:338:31:338:31 | x | | | atl.cpp:296:11:296:21 | call to source | atl.cpp:343:44:343:44 | x | | -| atl.cpp:296:11:296:21 | call to source | atl.cpp:352:18:352:18 | x | | -| atl.cpp:296:11:296:21 | call to source | atl.cpp:360:19:360:19 | x | | -| atl.cpp:296:11:296:21 | call to source | atl.cpp:369:29:369:29 | x | | -| atl.cpp:296:11:296:21 | call to source | atl.cpp:375:21:375:21 | x | | -| atl.cpp:296:11:296:21 | call to source | atl.cpp:383:30:383:30 | x | | -| atl.cpp:296:11:296:21 | call to source | atl.cpp:390:31:390:31 | x | | -| atl.cpp:296:11:296:21 | call to source | atl.cpp:395:44:395:44 | x | | | atl.cpp:298:24:298:25 | 10 | atl.cpp:298:24:298:26 | call to CAtlList | TAINT | | atl.cpp:298:24:298:26 | call to CAtlList | atl.cpp:299:10:299:13 | list | | | atl.cpp:298:24:298:26 | call to CAtlList | atl.cpp:300:5:300:8 | list | | @@ -406,12 +399,19 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:343:19:343:23 | ref arg list9 | atl.cpp:344:12:344:16 | list9 | | | atl.cpp:343:19:343:23 | ref arg list9 | atl.cpp:345:5:345:5 | list9 | | | atl.cpp:344:12:344:16 | ref arg list9 | atl.cpp:345:5:345:5 | list9 | | -| atl.cpp:350:24:350:25 | 10 | atl.cpp:350:24:350:26 | call to CAtlList | TAINT | -| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:351:10:351:13 | list | | -| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:352:5:352:8 | list | | -| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:353:10:353:13 | list | | -| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:356:24:356:27 | list | | -| atl.cpp:350:24:350:26 | call to CAtlList | atl.cpp:398:3:398:3 | list | | +| atl.cpp:348:12:348:31 | call to indirect_source | atl.cpp:352:18:352:18 | p | | +| atl.cpp:348:12:348:31 | call to indirect_source | atl.cpp:360:19:360:19 | p | | +| atl.cpp:348:12:348:31 | call to indirect_source | atl.cpp:369:29:369:29 | p | | +| atl.cpp:348:12:348:31 | call to indirect_source | atl.cpp:375:21:375:21 | p | | +| atl.cpp:348:12:348:31 | call to indirect_source | atl.cpp:383:30:383:30 | p | | +| atl.cpp:348:12:348:31 | call to indirect_source | atl.cpp:390:31:390:31 | p | | +| atl.cpp:348:12:348:31 | call to indirect_source | atl.cpp:395:44:395:44 | p | | +| atl.cpp:350:25:350:26 | 10 | atl.cpp:350:25:350:27 | call to CAtlList | TAINT | +| atl.cpp:350:25:350:27 | call to CAtlList | atl.cpp:351:10:351:13 | list | | +| atl.cpp:350:25:350:27 | call to CAtlList | atl.cpp:352:5:352:8 | list | | +| atl.cpp:350:25:350:27 | call to CAtlList | atl.cpp:353:10:353:13 | list | | +| atl.cpp:350:25:350:27 | call to CAtlList | atl.cpp:356:24:356:27 | list | | +| atl.cpp:350:25:350:27 | call to CAtlList | atl.cpp:398:3:398:3 | list | | | atl.cpp:351:10:351:13 | ref arg list | atl.cpp:352:5:352:8 | list | | | atl.cpp:351:10:351:13 | ref arg list | atl.cpp:353:10:353:13 | list | | | atl.cpp:351:10:351:13 | ref arg list | atl.cpp:356:24:356:27 | list | | @@ -421,37 +421,37 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:352:5:352:8 | ref arg list | atl.cpp:398:3:398:3 | list | | | atl.cpp:353:10:353:13 | ref arg list | atl.cpp:356:24:356:27 | list | | | atl.cpp:353:10:353:13 | ref arg list | atl.cpp:398:3:398:3 | list | | -| atl.cpp:355:25:355:26 | 10 | atl.cpp:355:25:355:27 | call to CAtlList | TAINT | -| atl.cpp:355:25:355:27 | call to CAtlList | atl.cpp:356:5:356:9 | list2 | | -| atl.cpp:355:25:355:27 | call to CAtlList | atl.cpp:357:10:357:14 | list2 | | -| atl.cpp:355:25:355:27 | call to CAtlList | atl.cpp:398:3:398:3 | list2 | | +| atl.cpp:355:26:355:27 | 10 | atl.cpp:355:26:355:28 | call to CAtlList | TAINT | +| atl.cpp:355:26:355:28 | call to CAtlList | atl.cpp:356:5:356:9 | list2 | | +| atl.cpp:355:26:355:28 | call to CAtlList | atl.cpp:357:10:357:14 | list2 | | +| atl.cpp:355:26:355:28 | call to CAtlList | atl.cpp:398:3:398:3 | list2 | | | atl.cpp:356:5:356:9 | ref arg list2 | atl.cpp:357:10:357:14 | list2 | | | atl.cpp:356:5:356:9 | ref arg list2 | atl.cpp:398:3:398:3 | list2 | | | atl.cpp:356:24:356:27 | list | atl.cpp:356:23:356:27 | & ... | | | atl.cpp:357:10:357:14 | ref arg list2 | atl.cpp:398:3:398:3 | list2 | | -| atl.cpp:359:25:359:26 | 10 | atl.cpp:359:25:359:27 | call to CAtlList | TAINT | -| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:360:5:360:9 | list3 | | -| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:361:10:361:14 | list3 | | -| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:364:24:364:28 | list3 | | -| atl.cpp:359:25:359:27 | call to CAtlList | atl.cpp:398:3:398:3 | list3 | | +| atl.cpp:359:26:359:27 | 10 | atl.cpp:359:26:359:28 | call to CAtlList | TAINT | +| atl.cpp:359:26:359:28 | call to CAtlList | atl.cpp:360:5:360:9 | list3 | | +| atl.cpp:359:26:359:28 | call to CAtlList | atl.cpp:361:10:361:14 | list3 | | +| atl.cpp:359:26:359:28 | call to CAtlList | atl.cpp:364:24:364:28 | list3 | | +| atl.cpp:359:26:359:28 | call to CAtlList | atl.cpp:398:3:398:3 | list3 | | | atl.cpp:360:5:360:9 | ref arg list3 | atl.cpp:361:10:361:14 | list3 | | | atl.cpp:360:5:360:9 | ref arg list3 | atl.cpp:364:24:364:28 | list3 | | | atl.cpp:360:5:360:9 | ref arg list3 | atl.cpp:398:3:398:3 | list3 | | | atl.cpp:361:10:361:14 | ref arg list3 | atl.cpp:364:24:364:28 | list3 | | | atl.cpp:361:10:361:14 | ref arg list3 | atl.cpp:398:3:398:3 | list3 | | -| atl.cpp:363:25:363:26 | 10 | atl.cpp:363:25:363:27 | call to CAtlList | TAINT | -| atl.cpp:363:25:363:27 | call to CAtlList | atl.cpp:364:5:364:9 | list4 | | -| atl.cpp:363:25:363:27 | call to CAtlList | atl.cpp:365:10:365:14 | list4 | | -| atl.cpp:363:25:363:27 | call to CAtlList | atl.cpp:398:3:398:3 | list4 | | +| atl.cpp:363:26:363:27 | 10 | atl.cpp:363:26:363:28 | call to CAtlList | TAINT | +| atl.cpp:363:26:363:28 | call to CAtlList | atl.cpp:364:5:364:9 | list4 | | +| atl.cpp:363:26:363:28 | call to CAtlList | atl.cpp:365:10:365:14 | list4 | | +| atl.cpp:363:26:363:28 | call to CAtlList | atl.cpp:398:3:398:3 | list4 | | | atl.cpp:364:5:364:9 | ref arg list4 | atl.cpp:365:10:365:14 | list4 | | | atl.cpp:364:5:364:9 | ref arg list4 | atl.cpp:398:3:398:3 | list4 | | | atl.cpp:364:24:364:28 | list3 | atl.cpp:364:23:364:28 | & ... | | | atl.cpp:365:10:365:14 | ref arg list4 | atl.cpp:398:3:398:3 | list4 | | -| atl.cpp:368:27:368:28 | 10 | atl.cpp:368:27:368:29 | call to CAtlList | TAINT | -| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:369:18:369:22 | list5 | | -| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:369:32:369:36 | list5 | | -| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:370:12:370:16 | list5 | | -| atl.cpp:368:27:368:29 | call to CAtlList | atl.cpp:371:5:371:5 | list5 | | +| atl.cpp:368:28:368:29 | 10 | atl.cpp:368:28:368:30 | call to CAtlList | TAINT | +| atl.cpp:368:28:368:30 | call to CAtlList | atl.cpp:369:18:369:22 | list5 | | +| atl.cpp:368:28:368:30 | call to CAtlList | atl.cpp:369:32:369:36 | list5 | | +| atl.cpp:368:28:368:30 | call to CAtlList | atl.cpp:370:12:370:16 | list5 | | +| atl.cpp:368:28:368:30 | call to CAtlList | atl.cpp:371:5:371:5 | list5 | | | atl.cpp:369:18:369:22 | ref arg list5 | atl.cpp:370:12:370:16 | list5 | | | atl.cpp:369:18:369:22 | ref arg list5 | atl.cpp:371:5:371:5 | list5 | | | atl.cpp:369:24:369:27 | call to Find | atl.cpp:370:24:370:26 | pos | | @@ -459,11 +459,11 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:369:32:369:36 | ref arg list5 | atl.cpp:370:12:370:16 | list5 | | | atl.cpp:369:32:369:36 | ref arg list5 | atl.cpp:371:5:371:5 | list5 | | | atl.cpp:370:12:370:16 | ref arg list5 | atl.cpp:371:5:371:5 | list5 | | -| atl.cpp:374:27:374:28 | 10 | atl.cpp:374:27:374:29 | call to CAtlList | TAINT | -| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:375:7:375:11 | list6 | | -| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:376:18:376:22 | list6 | | -| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:377:12:377:16 | list6 | | -| atl.cpp:374:27:374:29 | call to CAtlList | atl.cpp:378:5:378:5 | list6 | | +| atl.cpp:374:28:374:29 | 10 | atl.cpp:374:28:374:30 | call to CAtlList | TAINT | +| atl.cpp:374:28:374:30 | call to CAtlList | atl.cpp:375:7:375:11 | list6 | | +| atl.cpp:374:28:374:30 | call to CAtlList | atl.cpp:376:18:376:22 | list6 | | +| atl.cpp:374:28:374:30 | call to CAtlList | atl.cpp:377:12:377:16 | list6 | | +| atl.cpp:374:28:374:30 | call to CAtlList | atl.cpp:378:5:378:5 | list6 | | | atl.cpp:375:7:375:11 | ref arg list6 | atl.cpp:376:18:376:22 | list6 | | | atl.cpp:375:7:375:11 | ref arg list6 | atl.cpp:377:12:377:16 | list6 | | | atl.cpp:375:7:375:11 | ref arg list6 | atl.cpp:378:5:378:5 | list6 | | @@ -471,11 +471,11 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:376:18:376:22 | ref arg list6 | atl.cpp:378:5:378:5 | list6 | | | atl.cpp:376:24:376:32 | call to FindIndex | atl.cpp:377:24:377:26 | pos | | | atl.cpp:377:12:377:16 | ref arg list6 | atl.cpp:378:5:378:5 | list6 | | -| atl.cpp:381:27:381:28 | 10 | atl.cpp:381:27:381:29 | call to CAtlList | TAINT | -| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:382:18:382:22 | list7 | | -| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:383:7:383:11 | list7 | | -| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:384:12:384:16 | list7 | | -| atl.cpp:381:27:381:29 | call to CAtlList | atl.cpp:385:5:385:5 | list7 | | +| atl.cpp:381:28:381:29 | 10 | atl.cpp:381:28:381:30 | call to CAtlList | TAINT | +| atl.cpp:381:28:381:30 | call to CAtlList | atl.cpp:382:18:382:22 | list7 | | +| atl.cpp:381:28:381:30 | call to CAtlList | atl.cpp:383:7:383:11 | list7 | | +| atl.cpp:381:28:381:30 | call to CAtlList | atl.cpp:384:12:384:16 | list7 | | +| atl.cpp:381:28:381:30 | call to CAtlList | atl.cpp:385:5:385:5 | list7 | | | atl.cpp:382:18:382:22 | ref arg list7 | atl.cpp:383:7:383:11 | list7 | | | atl.cpp:382:18:382:22 | ref arg list7 | atl.cpp:384:12:384:16 | list7 | | | atl.cpp:382:18:382:22 | ref arg list7 | atl.cpp:385:5:385:5 | list7 | | @@ -483,11 +483,11 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:383:7:383:11 | ref arg list7 | atl.cpp:384:12:384:16 | list7 | | | atl.cpp:383:7:383:11 | ref arg list7 | atl.cpp:385:5:385:5 | list7 | | | atl.cpp:384:12:384:16 | ref arg list7 | atl.cpp:385:5:385:5 | list7 | | -| atl.cpp:388:27:388:28 | 10 | atl.cpp:388:27:388:29 | call to CAtlList | TAINT | -| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:389:18:389:22 | list8 | | -| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:390:7:390:11 | list8 | | -| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:391:12:391:16 | list8 | | -| atl.cpp:388:27:388:29 | call to CAtlList | atl.cpp:392:5:392:5 | list8 | | +| atl.cpp:388:28:388:29 | 10 | atl.cpp:388:28:388:30 | call to CAtlList | TAINT | +| atl.cpp:388:28:388:30 | call to CAtlList | atl.cpp:389:18:389:22 | list8 | | +| atl.cpp:388:28:388:30 | call to CAtlList | atl.cpp:390:7:390:11 | list8 | | +| atl.cpp:388:28:388:30 | call to CAtlList | atl.cpp:391:12:391:16 | list8 | | +| atl.cpp:388:28:388:30 | call to CAtlList | atl.cpp:392:5:392:5 | list8 | | | atl.cpp:389:18:389:22 | ref arg list8 | atl.cpp:390:7:390:11 | list8 | | | atl.cpp:389:18:389:22 | ref arg list8 | atl.cpp:391:12:391:16 | list8 | | | atl.cpp:389:18:389:22 | ref arg list8 | atl.cpp:392:5:392:5 | list8 | | @@ -495,11 +495,11 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:390:7:390:11 | ref arg list8 | atl.cpp:391:12:391:16 | list8 | | | atl.cpp:390:7:390:11 | ref arg list8 | atl.cpp:392:5:392:5 | list8 | | | atl.cpp:391:12:391:16 | ref arg list8 | atl.cpp:392:5:392:5 | list8 | | -| atl.cpp:394:27:394:28 | 10 | atl.cpp:394:27:394:29 | call to CAtlList | TAINT | -| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:395:7:395:11 | list9 | | -| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:395:19:395:23 | list9 | | -| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:396:12:396:16 | list9 | | -| atl.cpp:394:27:394:29 | call to CAtlList | atl.cpp:397:5:397:5 | list9 | | +| atl.cpp:394:28:394:29 | 10 | atl.cpp:394:28:394:30 | call to CAtlList | TAINT | +| atl.cpp:394:28:394:30 | call to CAtlList | atl.cpp:395:7:395:11 | list9 | | +| atl.cpp:394:28:394:30 | call to CAtlList | atl.cpp:395:19:395:23 | list9 | | +| atl.cpp:394:28:394:30 | call to CAtlList | atl.cpp:396:12:396:16 | list9 | | +| atl.cpp:394:28:394:30 | call to CAtlList | atl.cpp:397:5:397:5 | list9 | | | atl.cpp:395:7:395:11 | ref arg list9 | atl.cpp:396:12:396:16 | list9 | | | atl.cpp:395:7:395:11 | ref arg list9 | atl.cpp:397:5:397:5 | list9 | | | atl.cpp:395:19:395:23 | ref arg list9 | atl.cpp:395:7:395:11 | list9 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 7e8a52fdb35b..9284dc759eb1 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -3,6 +3,8 @@ signatureMatches | atl.cpp:69:3:69:15 | _U_STRINGorID | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | | atl.cpp:70:3:70:15 | _U_STRINGorID | (LPCTSTR) | _U_STRINGorID | _U_STRINGorID | 0 | | atl.cpp:257:3:257:10 | CAtlList | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:257:3:257:10 | CAtlList | (UINT) | CComBSTR | LoadString | 0 | +| atl.cpp:257:3:257:10 | CAtlList | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | | atl.cpp:257:3:257:10 | CAtlList | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | | atl.cpp:411:3:411:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 0 | | atl.cpp:411:3:411:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 1 | @@ -543,19 +545,34 @@ getParameterTypeName | atl.cpp:209:8:209:16 | SetAtGrow | 1 | INARGTYPclass:0 | | atl.cpp:211:6:211:15 | operator[] | 0 | size_t | | atl.cpp:257:3:257:10 | CAtlList | 0 | UINT | +| atl.cpp:257:3:257:10 | CAtlList | 0 | UINT | | atl.cpp:260:12:260:18 | AddHead | 0 | INARGTYPclass:0 | +| atl.cpp:260:12:260:18 | AddHead | 0 | INARGTYPclass:0 | +| atl.cpp:261:8:261:18 | AddHeadList | 0 | const CAtlList * | | atl.cpp:261:8:261:18 | AddHeadList | 0 | const CAtlList * | | atl.cpp:263:12:263:18 | AddTail | 0 | INARGTYPclass:0 | +| atl.cpp:263:12:263:18 | AddTail | 0 | INARGTYPclass:0 | +| atl.cpp:264:8:264:18 | AddTailList | 0 | const CAtlList * | | atl.cpp:264:8:264:18 | AddTailList | 0 | const CAtlList * | | atl.cpp:265:12:265:15 | Find | 0 | INARGTYPclass:0 | +| atl.cpp:265:12:265:15 | Find | 0 | INARGTYPclass:0 | +| atl.cpp:265:12:265:15 | Find | 1 | POSITION | | atl.cpp:265:12:265:15 | Find | 1 | POSITION | | atl.cpp:266:12:266:20 | FindIndex | 0 | size_t | +| atl.cpp:266:12:266:20 | FindIndex | 0 | size_t | +| atl.cpp:267:6:267:10 | GetAt | 0 | POSITION | | atl.cpp:267:6:267:10 | GetAt | 0 | POSITION | | atl.cpp:280:12:280:22 | InsertAfter | 0 | POSITION | +| atl.cpp:280:12:280:22 | InsertAfter | 0 | POSITION | +| atl.cpp:280:12:280:22 | InsertAfter | 1 | INARGTYPclass:0 | | atl.cpp:280:12:280:22 | InsertAfter | 1 | INARGTYPclass:0 | | atl.cpp:281:12:281:23 | InsertBefore | 0 | POSITION | +| atl.cpp:281:12:281:23 | InsertBefore | 0 | POSITION | +| atl.cpp:281:12:281:23 | InsertBefore | 1 | INARGTYPclass:0 | | atl.cpp:281:12:281:23 | InsertBefore | 1 | INARGTYPclass:0 | | atl.cpp:291:8:291:12 | SetAt | 0 | POSITION | +| atl.cpp:291:8:291:12 | SetAt | 0 | POSITION | +| atl.cpp:291:8:291:12 | SetAt | 1 | INARGTYPclass:0 | | atl.cpp:291:8:291:12 | SetAt | 1 | INARGTYPclass:0 | | atl.cpp:401:8:401:8 | operator= | 0 | IUnknown && | | atl.cpp:401:8:401:8 | operator= | 0 | const IUnknown & | From de75e033beb7b871e23f7dc706fd904bcbf19529 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 4 Dec 2024 12:42:48 +0000 Subject: [PATCH 055/213] C++: Remove taint to POSITIONs. --- cpp/ql/lib/ext/CAtlList.model.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cpp/ql/lib/ext/CAtlList.model.yml b/cpp/ql/lib/ext/CAtlList.model.yml index eb59fb8417ed..411b9390a9c2 100644 --- a/cpp/ql/lib/ext/CAtlList.model.yml +++ b/cpp/ql/lib/ext/CAtlList.model.yml @@ -7,9 +7,7 @@ extensions: - ["", "CAtlList", True, "AddHeadList", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "AddTail", "", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "AddTailList", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] - - ["", "CAtlList", True, "FindIndex", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "GetAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - - ["", "CAtlList", True, "GetAt", "", "", "Argument[0]", "ReturnValue[*@]", "taint", "manual"] - ["", "CAtlList", True, "GetHead", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CAtlList", True, "GetHeadPosition", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "GetNext", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] @@ -17,9 +15,5 @@ extensions: - ["", "CAtlList", True, "GetTail", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CAtlList", True, "GetTailPosition", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "InsertAfter", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - - ["", "CAtlList", True, "InsertAfter", "", "", "Argument[*@1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "InsertBefore", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - - ["", "CAtlList", True, "InsertBefore", "", "", "Argument[*@1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "taint", "manual"] - - ["", "CAtlList", True, "SwapElements", "", "", "Argument[0]", "Argument[1]", "taint", "manual"] - - ["", "CAtlList", True, "SwapElements", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] From 9dc3aecf67e2a5fcf47b2b5c10ccd37b4d7ae152 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 4 Dec 2024 12:48:55 +0000 Subject: [PATCH 056/213] C++: Remove more taint to POSITIONs. --- cpp/ql/lib/ext/CAtlList.model.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/ql/lib/ext/CAtlList.model.yml b/cpp/ql/lib/ext/CAtlList.model.yml index 411b9390a9c2..4b724ce717cf 100644 --- a/cpp/ql/lib/ext/CAtlList.model.yml +++ b/cpp/ql/lib/ext/CAtlList.model.yml @@ -9,11 +9,9 @@ extensions: - ["", "CAtlList", True, "AddTailList", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "GetAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CAtlList", True, "GetHead", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - - ["", "CAtlList", True, "GetHeadPosition", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "GetNext", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "GetPrev", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "GetTail", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - - ["", "CAtlList", True, "GetTailPosition", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "InsertAfter", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "InsertBefore", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "taint", "manual"] From c7dee4b02050448973eeb14c979fe7b254321bb3 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 4 Dec 2024 12:52:13 +0000 Subject: [PATCH 057/213] C++: Remove more taint to POSITIONs. --- cpp/ql/lib/ext/CAtlList.model.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/ql/lib/ext/CAtlList.model.yml b/cpp/ql/lib/ext/CAtlList.model.yml index 4b724ce717cf..a2de8a645d00 100644 --- a/cpp/ql/lib/ext/CAtlList.model.yml +++ b/cpp/ql/lib/ext/CAtlList.model.yml @@ -9,8 +9,6 @@ extensions: - ["", "CAtlList", True, "AddTailList", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "GetAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CAtlList", True, "GetHead", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - - ["", "CAtlList", True, "GetNext", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["", "CAtlList", True, "GetPrev", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CAtlList", True, "GetTail", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CAtlList", True, "InsertAfter", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "InsertBefore", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] From 279a30c7e80300d7ae5ffc003c5e1bff0bf1c5bd Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 4 Dec 2024 12:52:41 +0000 Subject: [PATCH 058/213] C++: Make 'SetAt' a value-preserving step. --- cpp/ql/lib/ext/CAtlList.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/ext/CAtlList.model.yml b/cpp/ql/lib/ext/CAtlList.model.yml index a2de8a645d00..6d952f2ca133 100644 --- a/cpp/ql/lib/ext/CAtlList.model.yml +++ b/cpp/ql/lib/ext/CAtlList.model.yml @@ -12,4 +12,4 @@ extensions: - ["", "CAtlList", True, "GetTail", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CAtlList", True, "InsertAfter", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CAtlList", True, "InsertBefore", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - - ["", "CAtlList", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "taint", "manual"] + - ["", "CAtlList", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] From 4f00e229e0296e97560923442508a9ae30ad904f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 4 Dec 2024 13:49:07 +0000 Subject: [PATCH 059/213] C++: Accept more test changes. --- .../dataflow/external-models/flow.expected | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 a8a3e5a209a5..81a9c605f005 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:810 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:808 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:809 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:800 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:798 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:799 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:809 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:799 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:810 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:800 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | From 121780c55a5fb5f2da85ea4cccdfdd50f34b5284 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Wed, 4 Dec 2024 16:56:49 -0500 Subject: [PATCH 060/213] Java: add File.getName as a path injection sanitizer --- .../semmle/code/java/security/PathSanitizer.qll | 15 +++++++++++++++ .../CWE-022/semmle/tests/TaintedPath.java | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index 77803e3e27dc..0d2e5cdfa7fe 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -333,3 +333,18 @@ private Method getSourceMethod(Method m) { not exists(Method src | m = src.getKotlinParameterDefaultsProxy()) and result = m } + +/** + * A sanitizer that protects against path injection vulnerabilities + * by extracting the final component of the user provided path. + * + * TODO: convert this class to models-as-data if sanitizer support is added + */ +private class FileGetNameSanitizer extends PathInjectionSanitizer { + FileGetNameSanitizer() { + exists(MethodCall mc | + mc.getMethod().hasQualifiedName("java.io", "File", "getName") and + this.asExpr() = mc + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java index 8bfc35c1d969..00447364bb38 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java @@ -71,4 +71,19 @@ public void sendUserFileGood3(Socket sock, String user) throws Exception { fileLine = fileReader.readLine(); } } + + public void sendUserFileGood4(Socket sock, String user) throws IOException { + BufferedReader filenameReader = + new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8")); + String filename = filenameReader.readLine(); + File file = new File(filename); + String baseName = file.getName(); + // GOOD: only use the final component of the user provided path + BufferedReader fileReader = new BufferedReader(new FileReader(baseName)); + String fileLine = fileReader.readLine(); + while (fileLine != null) { + sock.getOutputStream().write(fileLine.getBytes()); + fileLine = fileReader.readLine(); + } + } } From b20b7c7572104495ec8fddf957beb085c2597554 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 5 Dec 2024 10:43:13 +0000 Subject: [PATCH 061/213] Remove escaped "{" and "}" before counting placeholders --- .../semmle/code/java/frameworks/spring/SpringWebClient.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll index 79f0cb9c8bb7..9e6ac2c86014 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll @@ -56,7 +56,10 @@ private class SpringWebClientRestTemplateGetForObject extends RequestForgerySink i <= max(int occurrenceIndex, int occurrenceOffset | exists( - hsp.getStringValue().regexpFind("\\{[^}]*\\}", occurrenceIndex, occurrenceOffset) + hsp.getStringValue() + .replaceAll("\\{", " ") + .replaceAll("\\}", " ") + .regexpFind("\\{[^}]*\\}", occurrenceIndex, occurrenceOffset) ) and occurrenceOffset < hsp.getOffset() | @@ -78,6 +81,8 @@ private class SpringWebClientRestTemplateGetForObject extends RequestForgerySink mc.getArgument(0) .(CompileTimeConstantExpr) .getStringValue() + .replaceAll("\\{", " ") + .replaceAll("\\}", " ") .regexpFind("\\{[^}]*\\}", occurrenceIndex, _) ) | From 347fd575a2c52e9d8ed7d227c7702c2541711ba3 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 5 Dec 2024 11:15:43 +0000 Subject: [PATCH 062/213] Refactor to avoid duplicated logic --- .../frameworks/spring/SpringWebClient.qll | 89 ++++++++++--------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll index 9e6ac2c86014..a9c3cd3cdd88 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWebClient.qll @@ -30,20 +30,50 @@ class SpringWebClient extends Interface { private import semmle.code.java.security.RequestForgery +/** The method `getForObject` on `org.springframework.web.reactive.function.client.RestTemplate`. */ +class SpringRestTemplateGetForObjectMethod extends Method { + SpringRestTemplateGetForObjectMethod() { + this.getDeclaringType() instanceof SpringRestTemplate and + this.hasName("getForObject") + } +} + +/** A call to the method `getForObject` on `org.springframework.web.reactive.function.client.RestTemplate`. */ +class SpringRestTemplateGetForObjectMethodCall extends MethodCall { + SpringRestTemplateGetForObjectMethodCall() { + this.getMethod() instanceof SpringRestTemplateGetForObjectMethod + } + + /** Gets the first argument, if it is a compile time constant. */ + CompileTimeConstantExpr getConstantUrl() { result = this.getArgument(0) } + + /** + * Holds if the first argument is a compile time constant and it has a + * placeholder at offset `offset`, and there are `idx` placeholders that + * appear before it. + */ + predicate urlHasPlaceholderAtOffset(int idx, int offset) { + exists( + this.getConstantUrl() + .getStringValue() + .replaceAll("\\{", " ") + .replaceAll("\\}", " ") + .regexpFind("\\{[^}]*\\}", idx, offset) + ) + } +} + private class SpringWebClientRestTemplateGetForObject extends RequestForgerySink { SpringWebClientRestTemplateGetForObject() { - exists(Method m, MethodCall mc, int i | - m.getDeclaringType() instanceof SpringRestTemplate and - m.hasName("getForObject") and - mc.getMethod() = m and - // Note that mc.getArgument(0) is modeled separately. This model is for - // arguments beyond the first two. There are two relevant overloads, one - // with third parameter type `Object...` and one with third parameter - // type `Map`. For the latter we cannot deal with mapvalue - // content easily but there is a default implicit taint read at sinks - // that will catch it. - this.asExpr() = mc.getArgument(i + 2) and - i >= 0 + exists(SpringRestTemplateGetForObjectMethodCall mc, int i | + // Note that the first argument is modeled as a request forgery sink + // separately. This model is for arguments beyond the first two. There + // are two relevant overloads, one with third parameter type `Object...` + // and one with third parameter type `Map`. For the latter we + // cannot deal with MapValue content easily but there is a default + // implicit taint read at sinks that will catch it. + i >= 0 and + this.asExpr() = mc.getArgument(i + 2) | // If we can determine that part of mc.getArgument(0) is a hostname // sanitizing prefix, then we count how many placeholders occur before it @@ -51,20 +81,9 @@ private class SpringWebClientRestTemplateGetForObject extends RequestForgerySink // For the `Map` overload this has the effect of only // considering the map values as sinks if there is at least one // placeholder in the URL before the hostname sanitizing prefix. - exists(HostnameSanitizingPrefix hsp | - hsp = mc.getArgument(0) and - i <= - max(int occurrenceIndex, int occurrenceOffset | - exists( - hsp.getStringValue() - .replaceAll("\\{", " ") - .replaceAll("\\}", " ") - .regexpFind("\\{[^}]*\\}", occurrenceIndex, occurrenceOffset) - ) and - occurrenceOffset < hsp.getOffset() - | - occurrenceIndex - ) + exists(int offset | + mc.urlHasPlaceholderAtOffset(i, offset) and + offset < mc.getConstantUrl().(HostnameSanitizingPrefix).getOffset() ) or // If we cannot determine that part of mc.getArgument(0) is a hostname @@ -74,24 +93,12 @@ private class SpringWebClientRestTemplateGetForObject extends RequestForgerySink // For the `Map` overload this has the effect of only // considering the map values as sinks if there is at least one // placeholder in the URL. - not mc.getArgument(0) instanceof HostnameSanitizingPrefix and - i <= - max(int occurrenceIndex | - exists( - mc.getArgument(0) - .(CompileTimeConstantExpr) - .getStringValue() - .replaceAll("\\{", " ") - .replaceAll("\\}", " ") - .regexpFind("\\{[^}]*\\}", occurrenceIndex, _) - ) - | - occurrenceIndex - ) + not mc.getConstantUrl() instanceof HostnameSanitizingPrefix and + mc.urlHasPlaceholderAtOffset(i, _) or // If we cannot determine the string value of mc.getArgument(0), then we // conservatively consider all arguments as sinks. - not exists(mc.getArgument(0).(CompileTimeConstantExpr).getStringValue()) + not exists(mc.getConstantUrl().getStringValue()) ) } } From 537601290b235c80021d986e4245cbb18fbebc3a Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 11 Nov 2024 10:44:23 +0000 Subject: [PATCH 063/213] C#: Add `CODEQL_PROXY_*` environment variable names --- .../EnvironmentVariableNames.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs index 345cb43453fc..d825e5daeb03 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs @@ -74,5 +74,20 @@ internal static class EnvironmentVariableNames /// Specifies the location of the diagnostic directory. /// public const string DiagnosticDir = "CODEQL_EXTRACTOR_CSHARP_DIAGNOSTIC_DIR"; + + /// + /// Specifies the hostname of the Dependabot proxy. + /// + public const string ProxyHost = "CODEQL_PROXY_HOST"; + + /// + /// Specifies the hostname of the Dependabot proxy. + /// + public const string ProxyPort = "CODEQL_PROXY_PORT"; + + /// + /// Contains the certificate used by the Dependabot proxy. + /// + public const string ProxyCertificate = "CODEQL_PROXY_CA_CERTIFICATE"; } } From 232caa7185880c150566dd42224162be58feef33 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 11 Nov 2024 11:25:13 +0000 Subject: [PATCH 064/213] C#: Add `DependabotProxy` class --- .../DependabotProxy.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs new file mode 100644 index 000000000000..5b47189c7454 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using Semmle.Util; + +namespace Semmle.Extraction.CSharp.DependencyFetching +{ + internal class DependabotProxy + { + private readonly string? host; + private readonly string? port; + private readonly FileInfo? certFile; + + /// + /// The full address of the Dependabot proxy, if available. + /// + internal readonly string? Address; + + /// + /// Gets a value indicating whether a Dependabot proxy is configured. + /// + internal bool IsConfigured => !string.IsNullOrEmpty(this.Address); + + internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) + { + // Obtain and store the address of the Dependabot proxy, if available. + this.host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); + this.port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); + + if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port)) + { + return; + } + + this.Address = $"http://{this.host}:{this.port}"; + + // Obtain and store the proxy's certificate, if available. + var cert = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyCertificate); + + if (string.IsNullOrWhiteSpace(cert)) + { + return; + } + + var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); + Directory.CreateDirectory(certDirPath.FullName); + + this.certFile = new FileInfo(Path.Join(certDirPath.FullName, "proxy.crt")); + + using var writer = this.certFile.CreateText(); + writer.Write(cert); + } + } +} From 8ca75602d8a5c25abdd770e0958981cfcb6ed218 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 19 Nov 2024 12:26:54 +0000 Subject: [PATCH 065/213] C#: Initialise `DependabotProxy` in `DotNetCliInvoker` --- .../DotNet.cs | 2 +- .../DotNetCliInvoker.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index edfea049a81b..439f00754dda 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -27,7 +27,7 @@ private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDire Info(); } - private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet")), logger, tempWorkingDirectory) { } + private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), tempWorkingDirectory), logger, tempWorkingDirectory) { } internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 4295cce67167..b81b393e42a0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -12,12 +12,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching internal sealed class DotNetCliInvoker : IDotNetCliInvoker { private readonly ILogger logger; + private readonly DependabotProxy proxy; public string Exec { get; } - public DotNetCliInvoker(ILogger logger, string exec) + public DotNetCliInvoker(ILogger logger, string exec, TemporaryDirectory tempWorkingDirectory) { this.logger = logger; + this.proxy = new DependabotProxy(tempWorkingDirectory); this.Exec = exec; logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } @@ -38,6 +40,14 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = "en"; startInfo.EnvironmentVariables["MSBUILDDISABLENODEREUSE"] = "1"; startInfo.EnvironmentVariables["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true"; + + // Configure the proxy settings, if applicable. + this.proxy.ApplyProxy(this.logger, startInfo); + + this.logger.LogInfo(startInfo.EnvironmentVariables["HTTP_PROXY"] ?? ""); + this.logger.LogInfo(startInfo.EnvironmentVariables["HTTPS_PROXY"] ?? ""); + this.logger.LogInfo(startInfo.EnvironmentVariables["SSL_CERT_FILE"] ?? ""); + return startInfo; } From 6cd5711313c9e47f39845b24051e6ecaee5df519 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 19 Nov 2024 13:23:05 +0000 Subject: [PATCH 066/213] C#: Set environment variables for proxy for calls to `dotnet` --- .../DependabotProxy.cs | 14 ++++++++++++++ .../DotNetCliInvoker.cs | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 5b47189c7454..96ba3452cefe 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics; using System.IO; using Semmle.Util; +using Semmle.Util.Logging; namespace Semmle.Extraction.CSharp.DependencyFetching { @@ -49,5 +51,17 @@ internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) using var writer = this.certFile.CreateText(); writer.Write(cert); } + + internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) + { + // If the proxy isn't configured, we have nothing to do. + if (!this.IsConfigured) return; + + logger.LogInfo($"Setting up Dependabot proxy at {this.Address}"); + + startInfo.EnvironmentVariables["HTTP_PROXY"] = this.Address; + startInfo.EnvironmentVariables["HTTPS_PROXY"] = this.Address; + startInfo.EnvironmentVariables["SSL_CERT_FILE"] = this.certFile?.FullName; + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index b81b393e42a0..522d3e9ffd45 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -44,10 +44,6 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto // Configure the proxy settings, if applicable. this.proxy.ApplyProxy(this.logger, startInfo); - this.logger.LogInfo(startInfo.EnvironmentVariables["HTTP_PROXY"] ?? ""); - this.logger.LogInfo(startInfo.EnvironmentVariables["HTTPS_PROXY"] ?? ""); - this.logger.LogInfo(startInfo.EnvironmentVariables["SSL_CERT_FILE"] ?? ""); - return startInfo; } From de415d68cfa0428c2b133c5311014aced6a8807a Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 29 Nov 2024 13:18:58 +0000 Subject: [PATCH 067/213] C#: Add more logging to `DependabotProxy` --- .../DependabotProxy.cs | 10 ++++++++-- .../DotNetCliInvoker.cs | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 96ba3452cefe..c1db0b99017a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -22,7 +22,7 @@ internal class DependabotProxy /// internal bool IsConfigured => !string.IsNullOrEmpty(this.Address); - internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) + internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) { // Obtain and store the address of the Dependabot proxy, if available. this.host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); @@ -30,26 +30,32 @@ internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port)) { + logger.LogInfo("No Dependabot proxy credentials are configured."); return; } this.Address = $"http://{this.host}:{this.port}"; + logger.LogInfo($"Dependabot proxy configured at {this.Address}"); // Obtain and store the proxy's certificate, if available. var cert = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyCertificate); if (string.IsNullOrWhiteSpace(cert)) { + logger.LogInfo("No certificate configured for Dependabot proxy."); return; } var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); Directory.CreateDirectory(certDirPath.FullName); - this.certFile = new FileInfo(Path.Join(certDirPath.FullName, "proxy.crt")); + var certFilePath = Path.Join(certDirPath.FullName, "proxy.crt"); + this.certFile = new FileInfo(certFilePath); using var writer = this.certFile.CreateText(); writer.Write(cert); + + logger.LogInfo($"Stored Dependabot proxy certificate at {certFilePath}"); } internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 522d3e9ffd45..597acc58259a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -19,7 +19,7 @@ internal sealed class DotNetCliInvoker : IDotNetCliInvoker public DotNetCliInvoker(ILogger logger, string exec, TemporaryDirectory tempWorkingDirectory) { this.logger = logger; - this.proxy = new DependabotProxy(tempWorkingDirectory); + this.proxy = new DependabotProxy(logger, tempWorkingDirectory); this.Exec = exec; logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } From 87bd21e12c311cf57965c33eb058add1aebf16ec Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 13:40:37 +0000 Subject: [PATCH 068/213] C#: Use `Add` for environment variables --- .../DependabotProxy.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index c1db0b99017a..462cde58c87b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -65,9 +65,9 @@ internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) logger.LogInfo($"Setting up Dependabot proxy at {this.Address}"); - startInfo.EnvironmentVariables["HTTP_PROXY"] = this.Address; - startInfo.EnvironmentVariables["HTTPS_PROXY"] = this.Address; - startInfo.EnvironmentVariables["SSL_CERT_FILE"] = this.certFile?.FullName; + startInfo.EnvironmentVariables.Add("HTTP_PROXY", this.Address); + startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.Address); + startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.certFile?.FullName); } } } From e999ec1ecf8736a5815522df5ffd97f8c6a1061b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 14:17:06 +0000 Subject: [PATCH 069/213] C# Expose `CertificatePath` from `DependabotProxy` --- .../DependabotProxy.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 462cde58c87b..56bf08de9cc8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -16,6 +16,10 @@ internal class DependabotProxy /// The full address of the Dependabot proxy, if available. /// internal readonly string? Address; + /// + /// The path to the temporary file where the certificate is stored. + /// + internal readonly string? CertificatePath; /// /// Gets a value indicating whether a Dependabot proxy is configured. @@ -49,13 +53,13 @@ internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); Directory.CreateDirectory(certDirPath.FullName); - var certFilePath = Path.Join(certDirPath.FullName, "proxy.crt"); - this.certFile = new FileInfo(certFilePath); + this.CertificatePath = Path.Join(certDirPath.FullName, "proxy.crt"); + this.certFile = new FileInfo(this.CertificatePath); using var writer = this.certFile.CreateText(); writer.Write(cert); - logger.LogInfo($"Stored Dependabot proxy certificate at {certFilePath}"); + logger.LogInfo($"Stored Dependabot proxy certificate at {this.CertificatePath}"); } internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) From 984091d4a4cf8fa4e44fed4f22a9cc9f1fa1191d Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 14:18:24 +0000 Subject: [PATCH 070/213] C#: Propagate `DependabotProxy` instance down from `DependencyManager` --- .../DependabotProxy.cs | 2 +- .../DependencyManager.cs | 7 +++++-- .../Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs | 4 ++-- .../DotNetCliInvoker.cs | 4 ++-- .../NugetPackageRestorer.cs | 3 +++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 56bf08de9cc8..207d19777cc8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -6,7 +6,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching { - internal class DependabotProxy + public class DependabotProxy { private readonly string? host; private readonly string? port; diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index 4866df1260e2..de9308675982 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -27,6 +27,7 @@ public sealed partial class DependencyManager : IDisposable, ICompilationInfoCon private readonly ILogger logger; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly NugetPackageRestorer nugetPackageRestorer; + private readonly DependabotProxy dependabotProxy; private readonly IDotNet dotnet; private readonly FileContent fileContent; private readonly FileProvider fileProvider; @@ -106,9 +107,11 @@ void exitCallback(int ret, string msg, bool silent) return BuildScript.Success; }).Run(SystemBuildActions.Instance, startCallback, exitCallback); + dependabotProxy = new DependabotProxy(logger, tempWorkingDirectory); + try { - this.dotnet = DotNet.Make(logger, dotnetPath, tempWorkingDirectory); + this.dotnet = DotNet.Make(logger, dotnetPath, tempWorkingDirectory, dependabotProxy); runtimeLazy = new Lazy(() => new Runtime(dotnet)); } catch @@ -117,7 +120,7 @@ void exitCallback(int ret, string msg, bool silent) throw; } - nugetPackageRestorer = new NugetPackageRestorer(fileProvider, fileContent, dotnet, diagnosticsWriter, logger, this); + nugetPackageRestorer = new NugetPackageRestorer(fileProvider, fileContent, dotnet, dependabotProxy, diagnosticsWriter, logger, this); var dllLocations = fileProvider.Dlls.Select(x => new AssemblyLookupLocation(x)).ToHashSet(); dllLocations.UnionWith(nugetPackageRestorer.Restore()); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index 439f00754dda..a82a0a47f415 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -27,11 +27,11 @@ private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDire Info(); } - private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), tempWorkingDirectory), logger, tempWorkingDirectory) { } + private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { } internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger); - public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) => new DotNet(logger, dotNetPath, tempWorkingDirectory); + public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); private void Info() { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 597acc58259a..cdadfe1f5b8e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -16,10 +16,10 @@ internal sealed class DotNetCliInvoker : IDotNetCliInvoker public string Exec { get; } - public DotNetCliInvoker(ILogger logger, string exec, TemporaryDirectory tempWorkingDirectory) + public DotNetCliInvoker(ILogger logger, string exec, DependabotProxy dependabotProxy) { this.logger = logger; - this.proxy = new DependabotProxy(logger, tempWorkingDirectory); + this.proxy = dependabotProxy; this.Exec = exec; logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index f30760981f3a..96ab9300bdf6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -20,6 +20,7 @@ internal sealed partial class NugetPackageRestorer : IDisposable private readonly FileProvider fileProvider; private readonly FileContent fileContent; private readonly IDotNet dotnet; + private readonly DependabotProxy dependabotProxy; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly TemporaryDirectory legacyPackageDirectory; private readonly TemporaryDirectory missingPackageDirectory; @@ -32,6 +33,7 @@ public NugetPackageRestorer( FileProvider fileProvider, FileContent fileContent, IDotNet dotnet, + DependabotProxy dependabotProxy, IDiagnosticsWriter diagnosticsWriter, ILogger logger, ICompilationInfoContainer compilationInfoContainer) @@ -39,6 +41,7 @@ public NugetPackageRestorer( this.fileProvider = fileProvider; this.fileContent = fileContent; this.dotnet = dotnet; + this.dependabotProxy = dependabotProxy; this.diagnosticsWriter = diagnosticsWriter; this.logger = logger; this.compilationInfoContainer = compilationInfoContainer; From ca251fb840ffdfcda228baa1dd90b7e678c02ee0 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 14:20:11 +0000 Subject: [PATCH 071/213] C#: Set up proxy for `IsFeedReachable`, if configured --- .../NugetPackageRestorer.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 96ab9300bdf6..dfa9349d4265 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Net.Http; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -591,7 +593,26 @@ private static async Task ExecuteGetRequest(string address, HttpClient httpClien private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, bool allowExceptions = true) { logger.LogInfo($"Checking if Nuget feed '{feed}' is reachable..."); - using HttpClient client = new(); + + // Configure the HttpClient to be aware of the Dependabot Proxy, if used. + HttpClientHandler httpClientHandler = new(); + if (this.dependabotProxy.IsConfigured) + { + httpClientHandler.Proxy = new WebProxy(this.dependabotProxy.Address); + + if (!String.IsNullOrEmpty(this.dependabotProxy.CertificatePath)) + { + X509Certificate2 proxyCert = new X509Certificate2(this.dependabotProxy.CertificatePath); + httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) => + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(proxyCert); + return chain.Build(cert); + }; + } + } + + using HttpClient client = new(httpClientHandler); for (var i = 0; i < tryCount; i++) { From ee7f0b0f2afb157a3ae2f52410ecd66e19cd414f Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 3 Dec 2024 18:47:47 +0000 Subject: [PATCH 072/213] C#: Load Dependabot Proxy certificate in `DependabotProxy`, and implement `IDisposable` --- .../DependabotProxy.cs | 17 ++++++++++++++++- .../DependencyManager.cs | 1 + .../NugetPackageRestorer.cs | 5 ++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 207d19777cc8..7d0f21d65b1a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -1,12 +1,13 @@ using System; using System.Diagnostics; using System.IO; +using System.Security.Cryptography.X509Certificates; using Semmle.Util; using Semmle.Util.Logging; namespace Semmle.Extraction.CSharp.DependencyFetching { - public class DependabotProxy + public class DependabotProxy : IDisposable { private readonly string? host; private readonly string? port; @@ -20,6 +21,10 @@ public class DependabotProxy /// The path to the temporary file where the certificate is stored. /// internal readonly string? CertificatePath; + /// + /// The certificate used for the Dependabot proxy. + /// + internal readonly X509Certificate2? Certificate; /// /// Gets a value indicating whether a Dependabot proxy is configured. @@ -60,6 +65,8 @@ internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory writer.Write(cert); logger.LogInfo($"Stored Dependabot proxy certificate at {this.CertificatePath}"); + + this.Certificate = new X509Certificate2(this.CertificatePath); } internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) @@ -73,5 +80,13 @@ internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.Address); startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.certFile?.FullName); } + + public void Dispose() + { + if (this.Certificate != null) + { + this.Certificate.Dispose(); + } + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index de9308675982..bbd5ecbd127a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -545,6 +545,7 @@ private void AnalyseProject(FileInfo project) public void Dispose() { nugetPackageRestorer?.Dispose(); + dependabotProxy.Dispose(); if (cleanupTempWorkingDirectory) { tempWorkingDirectory?.Dispose(); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index dfa9349d4265..a01b3ae96493 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -600,13 +600,12 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, { httpClientHandler.Proxy = new WebProxy(this.dependabotProxy.Address); - if (!String.IsNullOrEmpty(this.dependabotProxy.CertificatePath)) + if (this.dependabotProxy.Certificate != null) { - X509Certificate2 proxyCert = new X509Certificate2(this.dependabotProxy.CertificatePath); httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) => { chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; - chain.ChainPolicy.CustomTrustStore.Add(proxyCert); + chain.ChainPolicy.CustomTrustStore.Add(this.dependabotProxy.Certificate); return chain.Build(cert); }; } From 2e80e09f52e2e8c1d4b54507dfca05e4bfd9d94e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 5 Dec 2024 12:13:29 +0000 Subject: [PATCH 073/213] C#: Apply suggestions from code review for `DependabotProxy` --- .../DependabotProxy.cs | 69 ++++++++----------- .../DependencyManager.cs | 4 +- .../DotNet.cs | 4 +- .../DotNetCliInvoker.cs | 13 +++- .../NugetPackageRestorer.cs | 6 +- 5 files changed, 45 insertions(+), 51 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 7d0f21d65b1a..d1a5df4dbc5e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -9,84 +9,71 @@ namespace Semmle.Extraction.CSharp.DependencyFetching { public class DependabotProxy : IDisposable { - private readonly string? host; - private readonly string? port; - private readonly FileInfo? certFile; + private readonly string host; + private readonly string port; /// /// The full address of the Dependabot proxy, if available. /// - internal readonly string? Address; + internal string Address { get; } /// /// The path to the temporary file where the certificate is stored. /// - internal readonly string? CertificatePath; + internal string? CertificatePath { get; private set; } /// /// The certificate used for the Dependabot proxy. /// - internal readonly X509Certificate2? Certificate; + internal X509Certificate2? Certificate { get; private set; } - /// - /// Gets a value indicating whether a Dependabot proxy is configured. - /// - internal bool IsConfigured => !string.IsNullOrEmpty(this.Address); - - internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) + internal static DependabotProxy? GetDependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) { // Obtain and store the address of the Dependabot proxy, if available. - this.host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); - this.port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); + var host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); + var port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port)) { logger.LogInfo("No Dependabot proxy credentials are configured."); - return; + return null; } - this.Address = $"http://{this.host}:{this.port}"; - logger.LogInfo($"Dependabot proxy configured at {this.Address}"); + var result = new DependabotProxy(host, port); + logger.LogInfo($"Dependabot proxy configured at {result.Address}"); // Obtain and store the proxy's certificate, if available. var cert = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyCertificate); - if (string.IsNullOrWhiteSpace(cert)) + if (!string.IsNullOrWhiteSpace(cert)) { logger.LogInfo("No certificate configured for Dependabot proxy."); - return; - } - var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); - Directory.CreateDirectory(certDirPath.FullName); + var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); + Directory.CreateDirectory(certDirPath.FullName); + + result.CertificatePath = Path.Join(certDirPath.FullName, "proxy.crt"); + var certFile = new FileInfo(result.CertificatePath); - this.CertificatePath = Path.Join(certDirPath.FullName, "proxy.crt"); - this.certFile = new FileInfo(this.CertificatePath); + using var writer = certFile.CreateText(); + writer.Write(cert); - using var writer = this.certFile.CreateText(); - writer.Write(cert); + logger.LogInfo($"Stored Dependabot proxy certificate at {result.CertificatePath}"); - logger.LogInfo($"Stored Dependabot proxy certificate at {this.CertificatePath}"); + result.Certificate = new X509Certificate2(result.CertificatePath); + } - this.Certificate = new X509Certificate2(this.CertificatePath); + return result; } - internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) + private DependabotProxy(string host, string port) { - // If the proxy isn't configured, we have nothing to do. - if (!this.IsConfigured) return; - - logger.LogInfo($"Setting up Dependabot proxy at {this.Address}"); - - startInfo.EnvironmentVariables.Add("HTTP_PROXY", this.Address); - startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.Address); - startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.certFile?.FullName); + this.host = host; + this.port = port; + this.Address = $"http://{this.host}:{this.port}"; } public void Dispose() { - if (this.Certificate != null) - { - this.Certificate.Dispose(); - } + this.Certificate?.Dispose(); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index bbd5ecbd127a..cf4c6d73bd65 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -27,7 +27,7 @@ public sealed partial class DependencyManager : IDisposable, ICompilationInfoCon private readonly ILogger logger; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly NugetPackageRestorer nugetPackageRestorer; - private readonly DependabotProxy dependabotProxy; + private readonly DependabotProxy? dependabotProxy; private readonly IDotNet dotnet; private readonly FileContent fileContent; private readonly FileProvider fileProvider; @@ -107,7 +107,7 @@ void exitCallback(int ret, string msg, bool silent) return BuildScript.Success; }).Run(SystemBuildActions.Instance, startCallback, exitCallback); - dependabotProxy = new DependabotProxy(logger, tempWorkingDirectory); + dependabotProxy = DependabotProxy.GetDependabotProxy(logger, tempWorkingDirectory); try { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index a82a0a47f415..c1fdcc06e91b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -27,11 +27,11 @@ private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDire Info(); } - private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { } + private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { } internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger); - public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); + public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); private void Info() { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index cdadfe1f5b8e..19f0f3dbe0d9 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -12,11 +12,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching internal sealed class DotNetCliInvoker : IDotNetCliInvoker { private readonly ILogger logger; - private readonly DependabotProxy proxy; + private readonly DependabotProxy? proxy; public string Exec { get; } - public DotNetCliInvoker(ILogger logger, string exec, DependabotProxy dependabotProxy) + public DotNetCliInvoker(ILogger logger, string exec, DependabotProxy? dependabotProxy) { this.logger = logger; this.proxy = dependabotProxy; @@ -42,7 +42,14 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto startInfo.EnvironmentVariables["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true"; // Configure the proxy settings, if applicable. - this.proxy.ApplyProxy(this.logger, startInfo); + if (this.proxy != null) + { + logger.LogInfo($"Setting up Dependabot proxy at {this.proxy.Address}"); + + startInfo.EnvironmentVariables.Add("HTTP_PROXY", this.proxy.Address); + startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.proxy.Address); + startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.proxy.CertificatePath); + } return startInfo; } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index a01b3ae96493..d0c0af6b768b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -22,7 +22,7 @@ internal sealed partial class NugetPackageRestorer : IDisposable private readonly FileProvider fileProvider; private readonly FileContent fileContent; private readonly IDotNet dotnet; - private readonly DependabotProxy dependabotProxy; + private readonly DependabotProxy? dependabotProxy; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly TemporaryDirectory legacyPackageDirectory; private readonly TemporaryDirectory missingPackageDirectory; @@ -35,7 +35,7 @@ public NugetPackageRestorer( FileProvider fileProvider, FileContent fileContent, IDotNet dotnet, - DependabotProxy dependabotProxy, + DependabotProxy? dependabotProxy, IDiagnosticsWriter diagnosticsWriter, ILogger logger, ICompilationInfoContainer compilationInfoContainer) @@ -596,7 +596,7 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, // Configure the HttpClient to be aware of the Dependabot Proxy, if used. HttpClientHandler httpClientHandler = new(); - if (this.dependabotProxy.IsConfigured) + if (this.dependabotProxy != null) { httpClientHandler.Proxy = new WebProxy(this.dependabotProxy.Address); From 7369d043ed1e9438e69cf9c4c7b4bdcd988e6465 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 5 Dec 2024 12:25:45 +0000 Subject: [PATCH 074/213] C#: Don't initialise `DependabotProxy` on Windows or macOS --- .../DependabotProxy.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index d1a5df4dbc5e..09f5a15a21d6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -27,6 +27,13 @@ public class DependabotProxy : IDisposable internal static DependabotProxy? GetDependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) { + // Setting HTTP(S)_PROXY and SSL_CERT_FILE have no effect on Windows or macOS, + // but we would still end up using the Dependabot proxy to check for feed reachability. + // This would result in us discovering that the feeds are reachable, but `dotnet` would + // fail to connect to them. To prevent this from happening, we do not initialise an + // instance of `DependabotProxy` on those platforms. + if (SystemBuildActions.Instance.IsWindows() || SystemBuildActions.Instance.IsMacOs()) return null; + // Obtain and store the address of the Dependabot proxy, if available. var host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); var port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); From 952488c2d843d2a0196311f638051b4026b8a32c Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 5 Dec 2024 12:32:55 +0000 Subject: [PATCH 075/213] C#: Fix possible null dereference --- .../DependencyManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index cf4c6d73bd65..b8773f0ae4a6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -545,7 +545,7 @@ private void AnalyseProject(FileInfo project) public void Dispose() { nugetPackageRestorer?.Dispose(); - dependabotProxy.Dispose(); + dependabotProxy?.Dispose(); if (cleanupTempWorkingDirectory) { tempWorkingDirectory?.Dispose(); From fd7469848ea7b9f9b857e3e9ec6cca627bccc6fc Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Thu, 5 Dec 2024 13:16:59 +0000 Subject: [PATCH 076/213] C++: Test case for cpp/badly-bounded-write --- .../CWE-120/semmle/tests/BadlyBoundedWrite.expected | 1 + .../Security/CWE/CWE-120/semmle/tests/errors.c | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/errors.c diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected index 9abc89c68f17..0f9b0567c228 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected @@ -1,2 +1,3 @@ +| errors.c:10:5:10:12 | call to swprintf | This 'call to swprintf' operation is limited to 12 bytes but the destination is only 3 bytes. | | tests.c:43:3:43:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. | | tests.c:46:3:46:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/errors.c b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/errors.c new file mode 100644 index 000000000000..a8f509af154d --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/errors.c @@ -0,0 +1,11 @@ +// semmle-extractor-options: --expect_errors + +typedef unsigned long size_t; +typedef int wchar_t; + +int swprintf(wchar_t *s, size_t n, const wchar_t *format, ...); + +void test_extraction_errors() { + WCHAR buffer[3]; + swprintf(buffer, 3, L"abc"); +} From 5bebfdeb2ae3988a34f79159f2803f8ba1717ed0 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 5 Dec 2024 13:59:59 +0000 Subject: [PATCH 077/213] C#: Add a MaD model for the 'Microsoft.AspNetCore.Mvc.Controller.View' method. --- .../ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml diff --git a/csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml b/csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml new file mode 100644 index 000000000000..e980e51810b3 --- /dev/null +++ b/csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/csharp-all + extensible: summaryModel + data: + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "()", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String,System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "taint", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "()", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String,System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] From ed4819aeab6ecdf3c5fa924e0e777423e64b6cf7 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 5 Dec 2024 15:18:25 +0100 Subject: [PATCH 078/213] Rust: Cache `defaultAdditionalTaintStep` --- .../rust/dataflow/internal/DataFlowImpl.qll | 4 ++- .../dataflow/internal/TaintTrackingImpl.qll | 3 ++ .../rust/elements/internal/ArrayExprImpl.qll | 2 +- .../lib/codeql/rust/internal/CachedStages.qll | 34 ++++++++++++++++--- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index b22b27c4db65..80fb80e7dc6d 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -1101,9 +1101,11 @@ import MakeImpl /** A collection of cached types and predicates to be evaluated in the same stage. */ cached private module Cached { + private import codeql.rust.internal.CachedStages + cached newtype TNode = - TExprNode(ExprCfgNode n) or + TExprNode(ExprCfgNode n) { Stages::DataFlowStage::ref() } or TSourceParameterNode(ParamBaseCfgNode p) or TPatNode(PatCfgNode p) or TExprPostUpdateNode(ExprCfgNode e) { diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll index 13f0052a5ba3..25cc7e22fafc 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll @@ -4,6 +4,7 @@ private import codeql.rust.controlflow.CfgNodes private import codeql.rust.dataflow.FlowSummary private import DataFlowImpl private import FlowSummaryImpl as FlowSummaryImpl +private import codeql.rust.internal.CachedStages module RustTaintTracking implements InputSig { predicate defaultTaintSanitizer(Node::Node node) { none() } @@ -12,7 +13,9 @@ module RustTaintTracking implements InputSig { * Holds if the additional step from `pred` to `succ` should be included in all * global taint flow configurations. */ + cached predicate defaultAdditionalTaintStep(Node::Node pred, Node::Node succ, string model) { + Stages::DataFlowStage::ref() and model = "" and ( exists(BinaryExprCfgNode binary | diff --git a/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll index 13abb32bcce4..97f237e47723 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ArrayExprImpl.qll @@ -22,7 +22,7 @@ module Impl { * ``` */ class ArrayExpr extends Generated::ArrayExpr { - cached + pragma[nomagic] private Raw::ArrayExprInternal getUnderlyingEntity() { this = Synth::TArrayListExpr(result) or this = Synth::TArrayRepeatExpr(result) } diff --git a/rust/ql/lib/codeql/rust/internal/CachedStages.qll b/rust/ql/lib/codeql/rust/internal/CachedStages.qll index 1fdd3c2a9b85..0cf3c32921e8 100644 --- a/rust/ql/lib/codeql/rust/internal/CachedStages.qll +++ b/rust/ql/lib/codeql/rust/internal/CachedStages.qll @@ -35,10 +35,6 @@ module Stages { */ cached module AstStage { - private import codeql.rust.controlflow.internal.Splitting - private import codeql.rust.controlflow.internal.SuccessorType - private import codeql.rust.controlflow.internal.ControlFlowGraphImpl - /** * Always holds. * Ensures that a predicate is evaluated as part of the AST stage. @@ -98,4 +94,34 @@ module Stages { exists(CallExprCfgNode n | exists(n.getFunction())) } } + + /** + * The data flow stage. + */ + cached + module DataFlowStage { + private import codeql.rust.dataflow.internal.DataFlowImpl + private import codeql.rust.dataflow.internal.TaintTrackingImpl + + /** + * Always holds. + * Ensures that a predicate is evaluated as part of the data flow stage. + */ + cached + predicate ref() { 1 = 1 } + + /** + * DO NOT USE! + * + * Contains references to each predicate that use the above `ref` predicate. + */ + cached + predicate backref() { + 1 = 1 + or + exists(Node n) + or + RustTaintTracking::defaultAdditionalTaintStep(_, _, _) + } + } } From b7f47f752b0d80608fd803cce6a91afa3f662719 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Thu, 5 Dec 2024 14:37:19 +0000 Subject: [PATCH 079/213] C++: Remove FPs from cpp/badly-bounded-write --- cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql | 3 ++- .../CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql b/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql index e7dd6a5d8e39..e89ffac906e6 100644 --- a/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql @@ -25,7 +25,8 @@ from BufferWrite bw, int destSize where bw.hasExplicitLimit() and // has an explicit size limit destSize = max(getBufferSize(bw.getDest(), _)) and - bw.getExplicitLimit() > destSize // but it's larger than the destination + bw.getExplicitLimit() > destSize and // but it's larger than the destination + not bw.getDest().getUnderlyingType().stripType() instanceof ErroneousType // destSize may be incorrect select bw, "This '" + bw.getBWDesc() + "' operation is limited to " + bw.getExplicitLimit() + " bytes but the destination is only " + destSize + " bytes." diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected index 0f9b0567c228..9abc89c68f17 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/BadlyBoundedWrite.expected @@ -1,3 +1,2 @@ -| errors.c:10:5:10:12 | call to swprintf | This 'call to swprintf' operation is limited to 12 bytes but the destination is only 3 bytes. | | tests.c:43:3:43:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. | | tests.c:46:3:46:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. | From 4af18be70b8ef10519a22f604fcd1cd0cd027cfa Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 5 Dec 2024 14:42:59 +0000 Subject: [PATCH 080/213] C#: Add change note. --- csharp/ql/lib/change-notes/2024-12-05-aspnetcore-mvc-model.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2024-12-05-aspnetcore-mvc-model.md diff --git a/csharp/ql/lib/change-notes/2024-12-05-aspnetcore-mvc-model.md b/csharp/ql/lib/change-notes/2024-12-05-aspnetcore-mvc-model.md new file mode 100644 index 000000000000..04afe96522b0 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-12-05-aspnetcore-mvc-model.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added flow summaries for the `Microsoft.AspNetCore.Mvc.Controller::View` method. \ No newline at end of file From 41f08d9b84c74b5719ef37d7775581bcbf6b2a09 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 5 Dec 2024 14:59:37 +0000 Subject: [PATCH 081/213] C#: Accept test changes. --- .../library-tests/dataflow/library/FlowSummaries.expected | 8 ++++++++ .../dataflow/library/FlowSummariesFiltered.expected | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 033c83df3bdf..25e4a9317ebd 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -1506,6 +1506,14 @@ summary | Microsoft.AspNetCore.Mvc;ApiBehaviorOptions;GetEnumerator;();Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | Microsoft.AspNetCore.Mvc;ApiBehaviorOptions;set_InvalidModelStateResponseFactory;(System.Func);Argument[0];Argument[0].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;Controller;OnActionExecutionAsync;(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext,Microsoft.AspNetCore.Mvc.Filters.ActionExecutionDelegate);Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated | +| Microsoft.AspNetCore.Mvc;Controller;View;();Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;();Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];taint;manual | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(System.Object,System.Type,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[4];Argument[4].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,System.Func);Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 199ccee5a503..4d315854b67c 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -555,6 +555,14 @@ | Microsoft.AspNetCore.Mvc.ViewFeatures;TryGetValueDelegate;BeginInvoke;(System.Object,System.String,System.Object,System.AsyncCallback,System.Object);Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc.ViewFeatures;ViewDataInfo;ViewDataInfo;(System.Object,System.Reflection.PropertyInfo,System.Func);Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ApiBehaviorOptions;set_InvalidModelStateResponseFactory;(System.Func);Argument[0];Argument[0].Parameter[delegate-self];value;hq-generated | +| Microsoft.AspNetCore.Mvc;Controller;View;();Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;();Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];taint;manual | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(System.Object,System.Type,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[4];Argument[4].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,System.Func);Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | From 7aed4c3cbfedcf9add643c1a802282953bcca242 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Thu, 5 Dec 2024 15:13:38 +0000 Subject: [PATCH 082/213] C++: Change note --- cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md diff --git a/cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md b/cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md new file mode 100644 index 000000000000..2004cd08248e --- /dev/null +++ b/cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The "Badly bounded write" query (`cpp/badly-bounded-write`) query no longer produces results if there is an extraction error in the type of the output buffer. From 12b4c0a2dd26dfdf487026ca941b68b6005e4760 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Thu, 5 Dec 2024 15:40:50 +0000 Subject: [PATCH 083/213] C++: Change note --- cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md diff --git a/cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md b/cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md new file mode 100644 index 000000000000..df9e13c07046 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The "Wrong type of arguments to formatting function" query (`cpp/wrong-type-format-argument`) query no longer produces results when a string type has an extraction error. From 2cd4e1af9f387b6dbbe3b0a802104ae494aa70c6 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 6 Dec 2024 09:55:05 +0000 Subject: [PATCH 084/213] C++: Use Expr.stripType() --- cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql index 905c4307ad16..272ef8369d0e 100644 --- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql +++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql @@ -170,11 +170,7 @@ where ) and not arg.isAffectedByMacro() and not arg.isFromUninstantiatedTemplate(_) and - not actual.getUnspecifiedType() instanceof ErroneousType and - not ( - expected instanceof PointerType and - actual.getUnspecifiedType().(PointerType).getBaseType() instanceof ErroneousType - ) and + not actual.stripType() instanceof ErroneousType and not arg.(Call).mayBeFromImplicitlyDeclaredFunction() select arg, "This format specifier for type '" + expected.getName() + "' does not match the argument type '" + From 0d616ca7efde349758bee3e5de042eda82dc5e78 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 12:23:35 +0000 Subject: [PATCH 085/213] C#: Respond to PR comments. --- csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml b/csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml index e980e51810b3..4942fd4bc917 100644 --- a/csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml +++ b/csharp/ql/lib/ext/Microsoft.AspNetCore.Mvc.model.yml @@ -3,11 +3,5 @@ extensions: pack: codeql/csharp-all extensible: summaryModel data: - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "()", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String,System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "taint", "manual"] - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "()", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] - - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "(System.String,System.Object)", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] + - ["Microsoft.AspNetCore.Mvc", "Controller", True, "View", "", "", "Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag]", "ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"] From e52e1b0c1fe053bc096cd65fab956fea07181ce8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:24:11 +0000 Subject: [PATCH 086/213] Rust: Add test case for 'self' in unused entities. --- .../unusedentities/UnusedValue.expected | 14 +++---- .../unusedentities/UnusedVariable.expected | 41 ++++++++++--------- .../test/query-tests/unusedentities/main.rs | 4 ++ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/UnusedValue.expected b/rust/ql/test/query-tests/unusedentities/UnusedValue.expected index f8538e5b8bc8..d5b385407647 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedValue.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedValue.expected @@ -8,13 +8,13 @@ | main.rs:65:5:65:5 | f | Variable $@ is assigned a value that is never used. | main.rs:34:13:34:13 | f | f | | main.rs:67:5:67:5 | f | Variable $@ is assigned a value that is never used. | main.rs:34:13:34:13 | f | f | | main.rs:69:5:69:5 | g | Variable $@ is assigned a value that is never used. | main.rs:35:9:35:9 | g | g | -| main.rs:91:9:91:9 | a | Variable $@ is assigned a value that is never used. | main.rs:91:9:91:9 | a | a | -| main.rs:112:9:112:10 | is | Variable $@ is assigned a value that is never used. | main.rs:112:9:112:10 | is | is | -| main.rs:135:13:135:17 | total | Variable $@ is assigned a value that is never used. | main.rs:135:13:135:17 | total | total | -| main.rs:280:13:280:17 | total | Variable $@ is assigned a value that is never used. | main.rs:248:13:248:17 | total | total | -| main.rs:373:9:373:9 | x | Variable $@ is assigned a value that is never used. | main.rs:373:9:373:9 | x | x | -| main.rs:381:17:381:17 | x | Variable $@ is assigned a value that is never used. | main.rs:381:17:381:17 | x | x | -| main.rs:482:9:482:9 | c | Variable $@ is assigned a value that is never used. | main.rs:482:9:482:9 | c | c | +| main.rs:95:9:95:9 | a | Variable $@ is assigned a value that is never used. | main.rs:95:9:95:9 | a | a | +| main.rs:116:9:116:10 | is | Variable $@ is assigned a value that is never used. | main.rs:116:9:116:10 | is | is | +| main.rs:139:13:139:17 | total | Variable $@ is assigned a value that is never used. | main.rs:139:13:139:17 | total | total | +| main.rs:284:13:284:17 | total | Variable $@ is assigned a value that is never used. | main.rs:252:13:252:17 | total | total | +| main.rs:377:9:377:9 | x | Variable $@ is assigned a value that is never used. | main.rs:377:9:377:9 | x | x | +| main.rs:385:17:385:17 | x | Variable $@ is assigned a value that is never used. | main.rs:385:17:385:17 | x | x | +| main.rs:486:9:486:9 | c | Variable $@ is assigned a value that is never used. | main.rs:486:9:486:9 | c | c | | more.rs:44:9:44:14 | a_ptr4 | Variable $@ is assigned a value that is never used. | more.rs:44:9:44:14 | a_ptr4 | a_ptr4 | | more.rs:59:9:59:13 | d_ptr | Variable $@ is assigned a value that is never used. | more.rs:59:9:59:13 | d_ptr | d_ptr | | more.rs:65:9:65:17 | f_ptr | Variable $@ is assigned a value that is never used. | more.rs:65:13:65:17 | f_ptr | f_ptr | diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index dcfde3c46f54..302810e08e5f 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -1,22 +1,23 @@ | main.rs:29:9:29:9 | a | Variable 'a' is not used. | -| main.rs:94:13:94:13 | d | Variable 'd' is not used. | -| main.rs:143:5:143:5 | y | Variable 'y' is not used. | -| main.rs:170:9:170:9 | x | Variable 'x' is not used. | -| main.rs:250:17:250:17 | a | Variable 'a' is not used. | -| main.rs:258:20:258:22 | val | Variable 'val' is not used. | -| main.rs:272:14:272:16 | val | Variable 'val' is not used. | -| main.rs:287:22:287:24 | val | Variable 'val' is not used. | -| main.rs:294:24:294:26 | val | Variable 'val' is not used. | -| main.rs:302:13:302:15 | num | Variable 'num' is not used. | -| main.rs:317:12:317:12 | j | Variable 'j' is not used. | -| main.rs:337:25:337:25 | y | Variable 'y' is not used. | -| main.rs:340:28:340:28 | a | Variable 'a' is not used. | -| main.rs:343:9:343:9 | p | Variable 'p' is not used. | -| main.rs:361:9:361:13 | right | Variable 'right' is not used. | -| main.rs:367:9:367:14 | right2 | Variable 'right2' is not used. | -| main.rs:374:13:374:13 | y | Variable 'y' is not used. | -| main.rs:382:21:382:21 | y | Variable 'y' is not used. | -| main.rs:427:26:427:28 | val | Variable 'val' is not used. | -| main.rs:430:21:430:23 | acc | Variable 'acc' is not used. | -| main.rs:451:9:451:14 | unused | Variable 'unused' is not used. | +| main.rs:89:19:89:22 | self | Variable 'self' is not used. | +| main.rs:98:13:98:13 | d | Variable 'd' is not used. | +| main.rs:147:5:147:5 | y | Variable 'y' is not used. | +| main.rs:174:9:174:9 | x | Variable 'x' is not used. | +| main.rs:254:17:254:17 | a | Variable 'a' is not used. | +| main.rs:262:20:262:22 | val | Variable 'val' is not used. | +| main.rs:276:14:276:16 | val | Variable 'val' is not used. | +| main.rs:291:22:291:24 | val | Variable 'val' is not used. | +| main.rs:298:24:298:26 | val | Variable 'val' is not used. | +| main.rs:306:13:306:15 | num | Variable 'num' is not used. | +| main.rs:321:12:321:12 | j | Variable 'j' is not used. | +| main.rs:341:25:341:25 | y | Variable 'y' is not used. | +| main.rs:344:28:344:28 | a | Variable 'a' is not used. | +| main.rs:347:9:347:9 | p | Variable 'p' is not used. | +| main.rs:365:9:365:13 | right | Variable 'right' is not used. | +| main.rs:371:9:371:14 | right2 | Variable 'right2' is not used. | +| main.rs:378:13:378:13 | y | Variable 'y' is not used. | +| main.rs:386:21:386:21 | y | Variable 'y' is not used. | +| main.rs:431:26:431:28 | val | Variable 'val' is not used. | +| main.rs:434:21:434:23 | acc | Variable 'acc' is not used. | +| main.rs:455:9:455:14 | unused | Variable 'unused' is not used. | | more.rs:24:9:24:11 | val | Variable 'val' is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index bd4bc4d23e1f..cc64f47986b1 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -85,6 +85,10 @@ impl MyStruct { fn my_get(&mut self) -> i64 { return self.val; } + + fn get_flags(&self) -> i64 { // $ SPURIOUS: Alert[rust/unused-variable] + return 0; + } } fn structs() { From 281f8b1828eafc07a8014d2a307900d9599b853b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:29:07 +0000 Subject: [PATCH 087/213] Rust: Fix the unwanted results. --- rust/ql/src/queries/unusedentities/UnusedVariable.qll | 3 +++ .../ql/test/query-tests/unusedentities/UnusedVariable.expected | 1 - rust/ql/test/query-tests/unusedentities/main.rs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rust/ql/src/queries/unusedentities/UnusedVariable.qll b/rust/ql/src/queries/unusedentities/UnusedVariable.qll index d92f8787af12..38f09d0a500a 100644 --- a/rust/ql/src/queries/unusedentities/UnusedVariable.qll +++ b/rust/ql/src/queries/unusedentities/UnusedVariable.qll @@ -23,4 +23,7 @@ predicate isUnused(Variable v) { predicate isAllowableUnused(Variable v) { // in a macro expansion v.getPat().isInMacroExpansion() + or + // a 'self' variable + v.getName() = "self" } diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index 302810e08e5f..203824f4a4b6 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -1,5 +1,4 @@ | main.rs:29:9:29:9 | a | Variable 'a' is not used. | -| main.rs:89:19:89:22 | self | Variable 'self' is not used. | | main.rs:98:13:98:13 | d | Variable 'd' is not used. | | main.rs:147:5:147:5 | y | Variable 'y' is not used. | | main.rs:174:9:174:9 | x | Variable 'x' is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index cc64f47986b1..2f729690f92e 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -86,7 +86,7 @@ impl MyStruct { return self.val; } - fn get_flags(&self) -> i64 { // $ SPURIOUS: Alert[rust/unused-variable] + fn get_flags(&self) -> i64 { return 0; } } From 43dd3ebf14c187ad5aad5b6d9d1fe225eac896bf Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 6 Dec 2024 14:07:42 +0100 Subject: [PATCH 088/213] Rust: Add variables test with captured self parameter --- .../test/library-tests/variables/Cfg.expected | 480 +++++++++--------- .../test/library-tests/variables/Ssa.expected | 58 ++- .../variables/variables.expected | 76 +-- .../test/library-tests/variables/variables.rs | 9 + 4 files changed, 342 insertions(+), 281 deletions(-) diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 673f57d5e681..0763f7a4e4b8 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1084,235 +1084,261 @@ edges | variables.rs:486:11:486:14 | self | variables.rs:486:11:486:14 | SelfParam | | | variables.rs:486:25:488:5 | { ... } | variables.rs:486:5:488:5 | exit fn id (normal) | | | variables.rs:487:9:487:12 | self | variables.rs:486:25:488:5 | { ... } | | -| variables.rs:491:1:498:1 | enter fn structs | variables.rs:492:5:492:36 | let ... = ... | | -| variables.rs:491:1:498:1 | exit fn structs (normal) | variables.rs:491:1:498:1 | exit fn structs | | -| variables.rs:491:14:498:1 | { ... } | variables.rs:491:1:498:1 | exit fn structs (normal) | | -| variables.rs:492:5:492:36 | let ... = ... | variables.rs:492:33:492:33 | 1 | | -| variables.rs:492:9:492:13 | a | variables.rs:493:5:493:26 | ExprStmt | match | -| variables.rs:492:17:492:35 | MyStruct {...} | variables.rs:492:9:492:13 | a | | -| variables.rs:492:33:492:33 | 1 | variables.rs:492:17:492:35 | MyStruct {...} | | -| variables.rs:493:5:493:13 | print_i64 | variables.rs:493:15:493:15 | a | | -| variables.rs:493:5:493:25 | print_i64(...) | variables.rs:494:5:494:14 | ExprStmt | | -| variables.rs:493:5:493:26 | ExprStmt | variables.rs:493:5:493:13 | print_i64 | | -| variables.rs:493:15:493:15 | a | variables.rs:493:15:493:24 | a.my_get(...) | | -| variables.rs:493:15:493:24 | a.my_get(...) | variables.rs:493:5:493:25 | print_i64(...) | | -| variables.rs:494:5:494:5 | a | variables.rs:494:5:494:9 | a.val | | -| variables.rs:494:5:494:9 | a.val | variables.rs:494:13:494:13 | 5 | | -| variables.rs:494:5:494:13 | ... = ... | variables.rs:495:5:495:26 | ExprStmt | | -| variables.rs:494:5:494:14 | ExprStmt | variables.rs:494:5:494:5 | a | | -| variables.rs:494:13:494:13 | 5 | variables.rs:494:5:494:13 | ... = ... | | -| variables.rs:495:5:495:13 | print_i64 | variables.rs:495:15:495:15 | a | | -| variables.rs:495:5:495:25 | print_i64(...) | variables.rs:496:5:496:28 | ExprStmt | | -| variables.rs:495:5:495:26 | ExprStmt | variables.rs:495:5:495:13 | print_i64 | | -| variables.rs:495:15:495:15 | a | variables.rs:495:15:495:24 | a.my_get(...) | | -| variables.rs:495:15:495:24 | a.my_get(...) | variables.rs:495:5:495:25 | print_i64(...) | | -| variables.rs:496:5:496:5 | a | variables.rs:496:25:496:25 | 2 | | -| variables.rs:496:5:496:27 | ... = ... | variables.rs:497:5:497:26 | ExprStmt | | -| variables.rs:496:5:496:28 | ExprStmt | variables.rs:496:5:496:5 | a | | -| variables.rs:496:9:496:27 | MyStruct {...} | variables.rs:496:5:496:27 | ... = ... | | -| variables.rs:496:25:496:25 | 2 | variables.rs:496:9:496:27 | MyStruct {...} | | -| variables.rs:497:5:497:13 | print_i64 | variables.rs:497:15:497:15 | a | | -| variables.rs:497:5:497:25 | print_i64(...) | variables.rs:491:14:498:1 | { ... } | | -| variables.rs:497:5:497:26 | ExprStmt | variables.rs:497:5:497:13 | print_i64 | | -| variables.rs:497:15:497:15 | a | variables.rs:497:15:497:24 | a.my_get(...) | | -| variables.rs:497:15:497:24 | a.my_get(...) | variables.rs:497:5:497:25 | print_i64(...) | | -| variables.rs:500:1:507:1 | enter fn arrays | variables.rs:501:5:501:26 | let ... = ... | | -| variables.rs:500:1:507:1 | exit fn arrays (normal) | variables.rs:500:1:507:1 | exit fn arrays | | -| variables.rs:500:13:507:1 | { ... } | variables.rs:500:1:507:1 | exit fn arrays (normal) | | -| variables.rs:501:5:501:26 | let ... = ... | variables.rs:501:18:501:18 | 1 | | -| variables.rs:501:9:501:13 | a | variables.rs:502:5:502:20 | ExprStmt | match | -| variables.rs:501:17:501:25 | [...] | variables.rs:501:9:501:13 | a | | -| variables.rs:501:18:501:18 | 1 | variables.rs:501:21:501:21 | 2 | | -| variables.rs:501:21:501:21 | 2 | variables.rs:501:24:501:24 | 3 | | -| variables.rs:501:24:501:24 | 3 | variables.rs:501:17:501:25 | [...] | | +| variables.rs:490:5:497:5 | enter fn my_method | variables.rs:490:23:490:26 | self | | +| variables.rs:490:5:497:5 | exit fn my_method (normal) | variables.rs:490:5:497:5 | exit fn my_method | | +| variables.rs:490:18:490:26 | SelfParam | variables.rs:491:9:494:10 | let ... = ... | | +| variables.rs:490:23:490:26 | self | variables.rs:490:18:490:26 | SelfParam | | +| variables.rs:490:29:497:5 | { ... } | variables.rs:490:5:497:5 | exit fn my_method (normal) | | +| variables.rs:491:9:494:10 | let ... = ... | variables.rs:491:21:494:9 | \|...\| ... | | +| variables.rs:491:13:491:17 | f | variables.rs:495:9:495:13 | ExprStmt | match | +| variables.rs:491:21:494:9 | \|...\| ... | variables.rs:491:13:491:17 | f | | +| variables.rs:491:21:494:9 | enter \|...\| ... | variables.rs:491:22:491:22 | n | | +| variables.rs:491:21:494:9 | exit \|...\| ... (normal) | variables.rs:491:21:494:9 | exit \|...\| ... | | +| variables.rs:491:22:491:22 | ... | variables.rs:493:13:493:26 | ExprStmt | | +| variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | ... | match | +| variables.rs:491:25:494:9 | { ... } | variables.rs:491:21:494:9 | exit \|...\| ... (normal) | | +| variables.rs:493:13:493:16 | self | variables.rs:493:13:493:20 | self.val | | +| variables.rs:493:13:493:20 | self.val | variables.rs:493:25:493:25 | n | | +| variables.rs:493:13:493:25 | ... += ... | variables.rs:491:25:494:9 | { ... } | | +| variables.rs:493:13:493:26 | ExprStmt | variables.rs:493:13:493:16 | self | | +| variables.rs:493:25:493:25 | n | variables.rs:493:13:493:25 | ... += ... | | +| variables.rs:495:9:495:9 | f | variables.rs:495:11:495:11 | 3 | | +| variables.rs:495:9:495:12 | f(...) | variables.rs:496:9:496:13 | ExprStmt | | +| variables.rs:495:9:495:13 | ExprStmt | variables.rs:495:9:495:9 | f | | +| variables.rs:495:11:495:11 | 3 | variables.rs:495:9:495:12 | f(...) | | +| variables.rs:496:9:496:9 | f | variables.rs:496:11:496:11 | 4 | | +| variables.rs:496:9:496:12 | f(...) | variables.rs:490:29:497:5 | { ... } | | +| variables.rs:496:9:496:13 | ExprStmt | variables.rs:496:9:496:9 | f | | +| variables.rs:496:11:496:11 | 4 | variables.rs:496:9:496:12 | f(...) | | +| variables.rs:500:1:507:1 | enter fn structs | variables.rs:501:5:501:36 | let ... = ... | | +| variables.rs:500:1:507:1 | exit fn structs (normal) | variables.rs:500:1:507:1 | exit fn structs | | +| variables.rs:500:14:507:1 | { ... } | variables.rs:500:1:507:1 | exit fn structs (normal) | | +| variables.rs:501:5:501:36 | let ... = ... | variables.rs:501:33:501:33 | 1 | | +| variables.rs:501:9:501:13 | a | variables.rs:502:5:502:26 | ExprStmt | match | +| variables.rs:501:17:501:35 | MyStruct {...} | variables.rs:501:9:501:13 | a | | +| variables.rs:501:33:501:33 | 1 | variables.rs:501:17:501:35 | MyStruct {...} | | | variables.rs:502:5:502:13 | print_i64 | variables.rs:502:15:502:15 | a | | -| variables.rs:502:5:502:19 | print_i64(...) | variables.rs:503:5:503:13 | ExprStmt | | -| variables.rs:502:5:502:20 | ExprStmt | variables.rs:502:5:502:13 | print_i64 | | -| variables.rs:502:15:502:15 | a | variables.rs:502:17:502:17 | 0 | | -| variables.rs:502:15:502:18 | a[0] | variables.rs:502:5:502:19 | print_i64(...) | | -| variables.rs:502:17:502:17 | 0 | variables.rs:502:15:502:18 | a[0] | | -| variables.rs:503:5:503:5 | a | variables.rs:503:7:503:7 | 1 | | -| variables.rs:503:5:503:8 | a[1] | variables.rs:503:12:503:12 | 5 | | -| variables.rs:503:5:503:12 | ... = ... | variables.rs:504:5:504:20 | ExprStmt | | -| variables.rs:503:5:503:13 | ExprStmt | variables.rs:503:5:503:5 | a | | -| variables.rs:503:7:503:7 | 1 | variables.rs:503:5:503:8 | a[1] | | -| variables.rs:503:12:503:12 | 5 | variables.rs:503:5:503:12 | ... = ... | | +| variables.rs:502:5:502:25 | print_i64(...) | variables.rs:503:5:503:14 | ExprStmt | | +| variables.rs:502:5:502:26 | ExprStmt | variables.rs:502:5:502:13 | print_i64 | | +| variables.rs:502:15:502:15 | a | variables.rs:502:15:502:24 | a.my_get(...) | | +| variables.rs:502:15:502:24 | a.my_get(...) | variables.rs:502:5:502:25 | print_i64(...) | | +| variables.rs:503:5:503:5 | a | variables.rs:503:5:503:9 | a.val | | +| variables.rs:503:5:503:9 | a.val | variables.rs:503:13:503:13 | 5 | | +| variables.rs:503:5:503:13 | ... = ... | variables.rs:504:5:504:26 | ExprStmt | | +| variables.rs:503:5:503:14 | ExprStmt | variables.rs:503:5:503:5 | a | | +| variables.rs:503:13:503:13 | 5 | variables.rs:503:5:503:13 | ... = ... | | | variables.rs:504:5:504:13 | print_i64 | variables.rs:504:15:504:15 | a | | -| variables.rs:504:5:504:19 | print_i64(...) | variables.rs:505:5:505:18 | ExprStmt | | -| variables.rs:504:5:504:20 | ExprStmt | variables.rs:504:5:504:13 | print_i64 | | -| variables.rs:504:15:504:15 | a | variables.rs:504:17:504:17 | 1 | | -| variables.rs:504:15:504:18 | a[1] | variables.rs:504:5:504:19 | print_i64(...) | | -| variables.rs:504:17:504:17 | 1 | variables.rs:504:15:504:18 | a[1] | | -| variables.rs:505:5:505:5 | a | variables.rs:505:10:505:10 | 4 | | -| variables.rs:505:5:505:17 | ... = ... | variables.rs:506:5:506:20 | ExprStmt | | -| variables.rs:505:5:505:18 | ExprStmt | variables.rs:505:5:505:5 | a | | -| variables.rs:505:9:505:17 | [...] | variables.rs:505:5:505:17 | ... = ... | | -| variables.rs:505:10:505:10 | 4 | variables.rs:505:13:505:13 | 5 | | -| variables.rs:505:13:505:13 | 5 | variables.rs:505:16:505:16 | 6 | | -| variables.rs:505:16:505:16 | 6 | variables.rs:505:9:505:17 | [...] | | +| variables.rs:504:5:504:25 | print_i64(...) | variables.rs:505:5:505:28 | ExprStmt | | +| variables.rs:504:5:504:26 | ExprStmt | variables.rs:504:5:504:13 | print_i64 | | +| variables.rs:504:15:504:15 | a | variables.rs:504:15:504:24 | a.my_get(...) | | +| variables.rs:504:15:504:24 | a.my_get(...) | variables.rs:504:5:504:25 | print_i64(...) | | +| variables.rs:505:5:505:5 | a | variables.rs:505:25:505:25 | 2 | | +| variables.rs:505:5:505:27 | ... = ... | variables.rs:506:5:506:26 | ExprStmt | | +| variables.rs:505:5:505:28 | ExprStmt | variables.rs:505:5:505:5 | a | | +| variables.rs:505:9:505:27 | MyStruct {...} | variables.rs:505:5:505:27 | ... = ... | | +| variables.rs:505:25:505:25 | 2 | variables.rs:505:9:505:27 | MyStruct {...} | | | variables.rs:506:5:506:13 | print_i64 | variables.rs:506:15:506:15 | a | | -| variables.rs:506:5:506:19 | print_i64(...) | variables.rs:500:13:507:1 | { ... } | | -| variables.rs:506:5:506:20 | ExprStmt | variables.rs:506:5:506:13 | print_i64 | | -| variables.rs:506:15:506:15 | a | variables.rs:506:17:506:17 | 2 | | -| variables.rs:506:15:506:18 | a[2] | variables.rs:506:5:506:19 | print_i64(...) | | -| variables.rs:506:17:506:17 | 2 | variables.rs:506:15:506:18 | a[2] | | -| variables.rs:509:1:516:1 | enter fn ref_arg | variables.rs:510:5:510:15 | let ... = 16 | | -| variables.rs:509:1:516:1 | exit fn ref_arg (normal) | variables.rs:509:1:516:1 | exit fn ref_arg | | -| variables.rs:509:14:516:1 | { ... } | variables.rs:509:1:516:1 | exit fn ref_arg (normal) | | -| variables.rs:510:5:510:15 | let ... = 16 | variables.rs:510:13:510:14 | 16 | | -| variables.rs:510:9:510:9 | x | variables.rs:511:5:511:22 | ExprStmt | match | -| variables.rs:510:13:510:14 | 16 | variables.rs:510:9:510:9 | x | | -| variables.rs:511:5:511:17 | print_i64_ref | variables.rs:511:20:511:20 | x | | -| variables.rs:511:5:511:21 | print_i64_ref(...) | variables.rs:512:5:512:17 | ExprStmt | | -| variables.rs:511:5:511:22 | ExprStmt | variables.rs:511:5:511:17 | print_i64_ref | | -| variables.rs:511:19:511:20 | &x | variables.rs:511:5:511:21 | print_i64_ref(...) | | -| variables.rs:511:20:511:20 | x | variables.rs:511:19:511:20 | &x | | -| variables.rs:512:5:512:13 | print_i64 | variables.rs:512:15:512:15 | x | | -| variables.rs:512:5:512:16 | print_i64(...) | variables.rs:514:5:514:15 | let ... = 17 | | -| variables.rs:512:5:512:17 | ExprStmt | variables.rs:512:5:512:13 | print_i64 | | -| variables.rs:512:15:512:15 | x | variables.rs:512:5:512:16 | print_i64(...) | | -| variables.rs:514:5:514:15 | let ... = 17 | variables.rs:514:13:514:14 | 17 | | -| variables.rs:514:9:514:9 | z | variables.rs:515:5:515:22 | ExprStmt | match | -| variables.rs:514:13:514:14 | 17 | variables.rs:514:9:514:9 | z | | -| variables.rs:515:5:515:17 | print_i64_ref | variables.rs:515:20:515:20 | z | | -| variables.rs:515:5:515:21 | print_i64_ref(...) | variables.rs:509:14:516:1 | { ... } | | -| variables.rs:515:5:515:22 | ExprStmt | variables.rs:515:5:515:17 | print_i64_ref | | -| variables.rs:515:19:515:20 | &z | variables.rs:515:5:515:21 | print_i64_ref(...) | | -| variables.rs:515:20:515:20 | z | variables.rs:515:19:515:20 | &z | | -| variables.rs:523:3:525:3 | enter fn bar | variables.rs:523:15:523:18 | self | | -| variables.rs:523:3:525:3 | exit fn bar (normal) | variables.rs:523:3:525:3 | exit fn bar | | -| variables.rs:523:10:523:18 | SelfParam | variables.rs:524:5:524:32 | ExprStmt | | -| variables.rs:523:15:523:18 | self | variables.rs:523:10:523:18 | SelfParam | | -| variables.rs:523:21:525:3 | { ... } | variables.rs:523:3:525:3 | exit fn bar (normal) | | -| variables.rs:524:5:524:9 | * ... | variables.rs:524:29:524:29 | 3 | | -| variables.rs:524:5:524:31 | ... = ... | variables.rs:523:21:525:3 | { ... } | | -| variables.rs:524:5:524:32 | ExprStmt | variables.rs:524:6:524:9 | self | | -| variables.rs:524:6:524:9 | self | variables.rs:524:5:524:9 | * ... | | -| variables.rs:524:13:524:31 | MyStruct {...} | variables.rs:524:5:524:31 | ... = ... | | -| variables.rs:524:29:524:29 | 3 | variables.rs:524:13:524:31 | MyStruct {...} | | -| variables.rs:528:1:533:1 | enter fn ref_methodcall_receiver | variables.rs:529:3:529:34 | let ... = ... | | -| variables.rs:528:1:533:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:528:1:533:1 | exit fn ref_methodcall_receiver | | -| variables.rs:528:30:533:1 | { ... } | variables.rs:528:1:533:1 | exit fn ref_methodcall_receiver (normal) | | -| variables.rs:529:3:529:34 | let ... = ... | variables.rs:529:31:529:31 | 1 | | -| variables.rs:529:7:529:11 | a | variables.rs:530:3:530:10 | ExprStmt | match | -| variables.rs:529:15:529:33 | MyStruct {...} | variables.rs:529:7:529:11 | a | | -| variables.rs:529:31:529:31 | 1 | variables.rs:529:15:529:33 | MyStruct {...} | | -| variables.rs:530:3:530:3 | a | variables.rs:530:3:530:9 | a.bar(...) | | -| variables.rs:530:3:530:9 | a.bar(...) | variables.rs:532:3:532:19 | ExprStmt | | -| variables.rs:530:3:530:10 | ExprStmt | variables.rs:530:3:530:3 | a | | -| variables.rs:532:3:532:11 | print_i64 | variables.rs:532:13:532:13 | a | | -| variables.rs:532:3:532:18 | print_i64(...) | variables.rs:528:30:533:1 | { ... } | | -| variables.rs:532:3:532:19 | ExprStmt | variables.rs:532:3:532:11 | print_i64 | | -| variables.rs:532:13:532:13 | a | variables.rs:532:13:532:17 | a.val | | -| variables.rs:532:13:532:17 | a.val | variables.rs:532:3:532:18 | print_i64(...) | | -| variables.rs:535:1:569:1 | enter fn main | variables.rs:536:5:536:25 | ExprStmt | | -| variables.rs:535:1:569:1 | exit fn main (normal) | variables.rs:535:1:569:1 | exit fn main | | -| variables.rs:535:11:569:1 | { ... } | variables.rs:535:1:569:1 | exit fn main (normal) | | -| variables.rs:536:5:536:22 | immutable_variable | variables.rs:536:5:536:24 | immutable_variable(...) | | -| variables.rs:536:5:536:24 | immutable_variable(...) | variables.rs:537:5:537:23 | ExprStmt | | -| variables.rs:536:5:536:25 | ExprStmt | variables.rs:536:5:536:22 | immutable_variable | | -| variables.rs:537:5:537:20 | mutable_variable | variables.rs:537:5:537:22 | mutable_variable(...) | | -| variables.rs:537:5:537:22 | mutable_variable(...) | variables.rs:538:5:538:40 | ExprStmt | | -| variables.rs:537:5:537:23 | ExprStmt | variables.rs:537:5:537:20 | mutable_variable | | -| variables.rs:538:5:538:37 | mutable_variable_immutable_borrow | variables.rs:538:5:538:39 | mutable_variable_immutable_borrow(...) | | -| variables.rs:538:5:538:39 | mutable_variable_immutable_borrow(...) | variables.rs:539:5:539:23 | ExprStmt | | -| variables.rs:538:5:538:40 | ExprStmt | variables.rs:538:5:538:37 | mutable_variable_immutable_borrow | | -| variables.rs:539:5:539:20 | variable_shadow1 | variables.rs:539:5:539:22 | variable_shadow1(...) | | -| variables.rs:539:5:539:22 | variable_shadow1(...) | variables.rs:540:5:540:23 | ExprStmt | | -| variables.rs:539:5:539:23 | ExprStmt | variables.rs:539:5:539:20 | variable_shadow1 | | -| variables.rs:540:5:540:20 | variable_shadow2 | variables.rs:540:5:540:22 | variable_shadow2(...) | | -| variables.rs:540:5:540:22 | variable_shadow2(...) | variables.rs:541:5:541:19 | ExprStmt | | -| variables.rs:540:5:540:23 | ExprStmt | variables.rs:540:5:540:20 | variable_shadow2 | | -| variables.rs:541:5:541:16 | let_pattern1 | variables.rs:541:5:541:18 | let_pattern1(...) | | -| variables.rs:541:5:541:18 | let_pattern1(...) | variables.rs:542:5:542:19 | ExprStmt | | -| variables.rs:541:5:541:19 | ExprStmt | variables.rs:541:5:541:16 | let_pattern1 | | -| variables.rs:542:5:542:16 | let_pattern2 | variables.rs:542:5:542:18 | let_pattern2(...) | | -| variables.rs:542:5:542:18 | let_pattern2(...) | variables.rs:543:5:543:19 | ExprStmt | | -| variables.rs:542:5:542:19 | ExprStmt | variables.rs:542:5:542:16 | let_pattern2 | | -| variables.rs:543:5:543:16 | let_pattern3 | variables.rs:543:5:543:18 | let_pattern3(...) | | -| variables.rs:543:5:543:18 | let_pattern3(...) | variables.rs:544:5:544:19 | ExprStmt | | -| variables.rs:543:5:543:19 | ExprStmt | variables.rs:543:5:543:16 | let_pattern3 | | -| variables.rs:544:5:544:16 | let_pattern4 | variables.rs:544:5:544:18 | let_pattern4(...) | | -| variables.rs:544:5:544:18 | let_pattern4(...) | variables.rs:545:5:545:21 | ExprStmt | | -| variables.rs:544:5:544:19 | ExprStmt | variables.rs:544:5:544:16 | let_pattern4 | | -| variables.rs:545:5:545:18 | match_pattern1 | variables.rs:545:5:545:20 | match_pattern1(...) | | -| variables.rs:545:5:545:20 | match_pattern1(...) | variables.rs:546:5:546:21 | ExprStmt | | -| variables.rs:545:5:545:21 | ExprStmt | variables.rs:545:5:545:18 | match_pattern1 | | -| variables.rs:546:5:546:18 | match_pattern2 | variables.rs:546:5:546:20 | match_pattern2(...) | | -| variables.rs:546:5:546:20 | match_pattern2(...) | variables.rs:547:5:547:21 | ExprStmt | | -| variables.rs:546:5:546:21 | ExprStmt | variables.rs:546:5:546:18 | match_pattern2 | | -| variables.rs:547:5:547:18 | match_pattern3 | variables.rs:547:5:547:20 | match_pattern3(...) | | -| variables.rs:547:5:547:20 | match_pattern3(...) | variables.rs:548:5:548:21 | ExprStmt | | -| variables.rs:547:5:547:21 | ExprStmt | variables.rs:547:5:547:18 | match_pattern3 | | -| variables.rs:548:5:548:18 | match_pattern4 | variables.rs:548:5:548:20 | match_pattern4(...) | | -| variables.rs:548:5:548:20 | match_pattern4(...) | variables.rs:549:5:549:21 | ExprStmt | | -| variables.rs:548:5:548:21 | ExprStmt | variables.rs:548:5:548:18 | match_pattern4 | | -| variables.rs:549:5:549:18 | match_pattern5 | variables.rs:549:5:549:20 | match_pattern5(...) | | -| variables.rs:549:5:549:20 | match_pattern5(...) | variables.rs:550:5:550:21 | ExprStmt | | -| variables.rs:549:5:549:21 | ExprStmt | variables.rs:549:5:549:18 | match_pattern5 | | -| variables.rs:550:5:550:18 | match_pattern6 | variables.rs:550:5:550:20 | match_pattern6(...) | | -| variables.rs:550:5:550:20 | match_pattern6(...) | variables.rs:551:5:551:21 | ExprStmt | | -| variables.rs:550:5:550:21 | ExprStmt | variables.rs:550:5:550:18 | match_pattern6 | | -| variables.rs:551:5:551:18 | match_pattern7 | variables.rs:551:5:551:20 | match_pattern7(...) | | -| variables.rs:551:5:551:20 | match_pattern7(...) | variables.rs:552:5:552:21 | ExprStmt | | -| variables.rs:551:5:551:21 | ExprStmt | variables.rs:551:5:551:18 | match_pattern7 | | -| variables.rs:552:5:552:18 | match_pattern8 | variables.rs:552:5:552:20 | match_pattern8(...) | | -| variables.rs:552:5:552:20 | match_pattern8(...) | variables.rs:553:5:553:21 | ExprStmt | | -| variables.rs:552:5:552:21 | ExprStmt | variables.rs:552:5:552:18 | match_pattern8 | | -| variables.rs:553:5:553:18 | match_pattern9 | variables.rs:553:5:553:20 | match_pattern9(...) | | -| variables.rs:553:5:553:20 | match_pattern9(...) | variables.rs:554:5:554:36 | ExprStmt | | -| variables.rs:553:5:553:21 | ExprStmt | variables.rs:553:5:553:18 | match_pattern9 | | -| variables.rs:554:5:554:18 | param_pattern1 | variables.rs:554:20:554:22 | "a" | | -| variables.rs:554:5:554:35 | param_pattern1(...) | variables.rs:555:5:555:37 | ExprStmt | | -| variables.rs:554:5:554:36 | ExprStmt | variables.rs:554:5:554:18 | param_pattern1 | | -| variables.rs:554:20:554:22 | "a" | variables.rs:554:26:554:28 | "b" | | -| variables.rs:554:25:554:34 | TupleExpr | variables.rs:554:5:554:35 | param_pattern1(...) | | -| variables.rs:554:26:554:28 | "b" | variables.rs:554:31:554:33 | "c" | | -| variables.rs:554:31:554:33 | "c" | variables.rs:554:25:554:34 | TupleExpr | | -| variables.rs:555:5:555:18 | param_pattern2 | variables.rs:555:20:555:31 | ...::Left | | -| variables.rs:555:5:555:36 | param_pattern2(...) | variables.rs:556:5:556:26 | ExprStmt | | -| variables.rs:555:5:555:37 | ExprStmt | variables.rs:555:5:555:18 | param_pattern2 | | -| variables.rs:555:20:555:31 | ...::Left | variables.rs:555:33:555:34 | 45 | | -| variables.rs:555:20:555:35 | ...::Left(...) | variables.rs:555:5:555:36 | param_pattern2(...) | | -| variables.rs:555:33:555:34 | 45 | variables.rs:555:20:555:35 | ...::Left(...) | | -| variables.rs:556:5:556:23 | destruct_assignment | variables.rs:556:5:556:25 | destruct_assignment(...) | | -| variables.rs:556:5:556:25 | destruct_assignment(...) | variables.rs:557:5:557:23 | ExprStmt | | -| variables.rs:556:5:556:26 | ExprStmt | variables.rs:556:5:556:23 | destruct_assignment | | -| variables.rs:557:5:557:20 | closure_variable | variables.rs:557:5:557:22 | closure_variable(...) | | -| variables.rs:557:5:557:22 | closure_variable(...) | variables.rs:558:5:558:19 | ExprStmt | | -| variables.rs:557:5:557:23 | ExprStmt | variables.rs:557:5:557:20 | closure_variable | | -| variables.rs:558:5:558:16 | for_variable | variables.rs:558:5:558:18 | for_variable(...) | | -| variables.rs:558:5:558:18 | for_variable(...) | variables.rs:559:5:559:17 | ExprStmt | | -| variables.rs:558:5:558:19 | ExprStmt | variables.rs:558:5:558:16 | for_variable | | -| variables.rs:559:5:559:14 | add_assign | variables.rs:559:5:559:16 | add_assign(...) | | -| variables.rs:559:5:559:16 | add_assign(...) | variables.rs:560:5:560:13 | ExprStmt | | -| variables.rs:559:5:559:17 | ExprStmt | variables.rs:559:5:559:14 | add_assign | | -| variables.rs:560:5:560:10 | mutate | variables.rs:560:5:560:12 | mutate(...) | | -| variables.rs:560:5:560:12 | mutate(...) | variables.rs:561:5:561:17 | ExprStmt | | -| variables.rs:560:5:560:13 | ExprStmt | variables.rs:560:5:560:10 | mutate | | -| variables.rs:561:5:561:14 | mutate_arg | variables.rs:561:5:561:16 | mutate_arg(...) | | -| variables.rs:561:5:561:16 | mutate_arg(...) | variables.rs:562:5:562:12 | ExprStmt | | -| variables.rs:561:5:561:17 | ExprStmt | variables.rs:561:5:561:14 | mutate_arg | | -| variables.rs:562:5:562:9 | alias | variables.rs:562:5:562:11 | alias(...) | | -| variables.rs:562:5:562:11 | alias(...) | variables.rs:563:5:563:18 | ExprStmt | | -| variables.rs:562:5:562:12 | ExprStmt | variables.rs:562:5:562:9 | alias | | -| variables.rs:563:5:563:15 | capture_mut | variables.rs:563:5:563:17 | capture_mut(...) | | -| variables.rs:563:5:563:17 | capture_mut(...) | variables.rs:564:5:564:20 | ExprStmt | | -| variables.rs:563:5:563:18 | ExprStmt | variables.rs:563:5:563:15 | capture_mut | | -| variables.rs:564:5:564:17 | capture_immut | variables.rs:564:5:564:19 | capture_immut(...) | | -| variables.rs:564:5:564:19 | capture_immut(...) | variables.rs:565:5:565:26 | ExprStmt | | -| variables.rs:564:5:564:20 | ExprStmt | variables.rs:564:5:564:17 | capture_immut | | -| variables.rs:565:5:565:23 | async_block_capture | variables.rs:565:5:565:25 | async_block_capture(...) | | -| variables.rs:565:5:565:25 | async_block_capture(...) | variables.rs:566:5:566:14 | ExprStmt | | -| variables.rs:565:5:565:26 | ExprStmt | variables.rs:565:5:565:23 | async_block_capture | | -| variables.rs:566:5:566:11 | structs | variables.rs:566:5:566:13 | structs(...) | | -| variables.rs:566:5:566:13 | structs(...) | variables.rs:567:5:567:14 | ExprStmt | | -| variables.rs:566:5:566:14 | ExprStmt | variables.rs:566:5:566:11 | structs | | -| variables.rs:567:5:567:11 | ref_arg | variables.rs:567:5:567:13 | ref_arg(...) | | -| variables.rs:567:5:567:13 | ref_arg(...) | variables.rs:568:5:568:30 | ExprStmt | | -| variables.rs:567:5:567:14 | ExprStmt | variables.rs:567:5:567:11 | ref_arg | | -| variables.rs:568:5:568:27 | ref_methodcall_receiver | variables.rs:568:5:568:29 | ref_methodcall_receiver(...) | | -| variables.rs:568:5:568:29 | ref_methodcall_receiver(...) | variables.rs:535:11:569:1 | { ... } | | -| variables.rs:568:5:568:30 | ExprStmt | variables.rs:568:5:568:27 | ref_methodcall_receiver | | +| variables.rs:506:5:506:25 | print_i64(...) | variables.rs:500:14:507:1 | { ... } | | +| variables.rs:506:5:506:26 | ExprStmt | variables.rs:506:5:506:13 | print_i64 | | +| variables.rs:506:15:506:15 | a | variables.rs:506:15:506:24 | a.my_get(...) | | +| variables.rs:506:15:506:24 | a.my_get(...) | variables.rs:506:5:506:25 | print_i64(...) | | +| variables.rs:509:1:516:1 | enter fn arrays | variables.rs:510:5:510:26 | let ... = ... | | +| variables.rs:509:1:516:1 | exit fn arrays (normal) | variables.rs:509:1:516:1 | exit fn arrays | | +| variables.rs:509:13:516:1 | { ... } | variables.rs:509:1:516:1 | exit fn arrays (normal) | | +| variables.rs:510:5:510:26 | let ... = ... | variables.rs:510:18:510:18 | 1 | | +| variables.rs:510:9:510:13 | a | variables.rs:511:5:511:20 | ExprStmt | match | +| variables.rs:510:17:510:25 | [...] | variables.rs:510:9:510:13 | a | | +| variables.rs:510:18:510:18 | 1 | variables.rs:510:21:510:21 | 2 | | +| variables.rs:510:21:510:21 | 2 | variables.rs:510:24:510:24 | 3 | | +| variables.rs:510:24:510:24 | 3 | variables.rs:510:17:510:25 | [...] | | +| variables.rs:511:5:511:13 | print_i64 | variables.rs:511:15:511:15 | a | | +| variables.rs:511:5:511:19 | print_i64(...) | variables.rs:512:5:512:13 | ExprStmt | | +| variables.rs:511:5:511:20 | ExprStmt | variables.rs:511:5:511:13 | print_i64 | | +| variables.rs:511:15:511:15 | a | variables.rs:511:17:511:17 | 0 | | +| variables.rs:511:15:511:18 | a[0] | variables.rs:511:5:511:19 | print_i64(...) | | +| variables.rs:511:17:511:17 | 0 | variables.rs:511:15:511:18 | a[0] | | +| variables.rs:512:5:512:5 | a | variables.rs:512:7:512:7 | 1 | | +| variables.rs:512:5:512:8 | a[1] | variables.rs:512:12:512:12 | 5 | | +| variables.rs:512:5:512:12 | ... = ... | variables.rs:513:5:513:20 | ExprStmt | | +| variables.rs:512:5:512:13 | ExprStmt | variables.rs:512:5:512:5 | a | | +| variables.rs:512:7:512:7 | 1 | variables.rs:512:5:512:8 | a[1] | | +| variables.rs:512:12:512:12 | 5 | variables.rs:512:5:512:12 | ... = ... | | +| variables.rs:513:5:513:13 | print_i64 | variables.rs:513:15:513:15 | a | | +| variables.rs:513:5:513:19 | print_i64(...) | variables.rs:514:5:514:18 | ExprStmt | | +| variables.rs:513:5:513:20 | ExprStmt | variables.rs:513:5:513:13 | print_i64 | | +| variables.rs:513:15:513:15 | a | variables.rs:513:17:513:17 | 1 | | +| variables.rs:513:15:513:18 | a[1] | variables.rs:513:5:513:19 | print_i64(...) | | +| variables.rs:513:17:513:17 | 1 | variables.rs:513:15:513:18 | a[1] | | +| variables.rs:514:5:514:5 | a | variables.rs:514:10:514:10 | 4 | | +| variables.rs:514:5:514:17 | ... = ... | variables.rs:515:5:515:20 | ExprStmt | | +| variables.rs:514:5:514:18 | ExprStmt | variables.rs:514:5:514:5 | a | | +| variables.rs:514:9:514:17 | [...] | variables.rs:514:5:514:17 | ... = ... | | +| variables.rs:514:10:514:10 | 4 | variables.rs:514:13:514:13 | 5 | | +| variables.rs:514:13:514:13 | 5 | variables.rs:514:16:514:16 | 6 | | +| variables.rs:514:16:514:16 | 6 | variables.rs:514:9:514:17 | [...] | | +| variables.rs:515:5:515:13 | print_i64 | variables.rs:515:15:515:15 | a | | +| variables.rs:515:5:515:19 | print_i64(...) | variables.rs:509:13:516:1 | { ... } | | +| variables.rs:515:5:515:20 | ExprStmt | variables.rs:515:5:515:13 | print_i64 | | +| variables.rs:515:15:515:15 | a | variables.rs:515:17:515:17 | 2 | | +| variables.rs:515:15:515:18 | a[2] | variables.rs:515:5:515:19 | print_i64(...) | | +| variables.rs:515:17:515:17 | 2 | variables.rs:515:15:515:18 | a[2] | | +| variables.rs:518:1:525:1 | enter fn ref_arg | variables.rs:519:5:519:15 | let ... = 16 | | +| variables.rs:518:1:525:1 | exit fn ref_arg (normal) | variables.rs:518:1:525:1 | exit fn ref_arg | | +| variables.rs:518:14:525:1 | { ... } | variables.rs:518:1:525:1 | exit fn ref_arg (normal) | | +| variables.rs:519:5:519:15 | let ... = 16 | variables.rs:519:13:519:14 | 16 | | +| variables.rs:519:9:519:9 | x | variables.rs:520:5:520:22 | ExprStmt | match | +| variables.rs:519:13:519:14 | 16 | variables.rs:519:9:519:9 | x | | +| variables.rs:520:5:520:17 | print_i64_ref | variables.rs:520:20:520:20 | x | | +| variables.rs:520:5:520:21 | print_i64_ref(...) | variables.rs:521:5:521:17 | ExprStmt | | +| variables.rs:520:5:520:22 | ExprStmt | variables.rs:520:5:520:17 | print_i64_ref | | +| variables.rs:520:19:520:20 | &x | variables.rs:520:5:520:21 | print_i64_ref(...) | | +| variables.rs:520:20:520:20 | x | variables.rs:520:19:520:20 | &x | | +| variables.rs:521:5:521:13 | print_i64 | variables.rs:521:15:521:15 | x | | +| variables.rs:521:5:521:16 | print_i64(...) | variables.rs:523:5:523:15 | let ... = 17 | | +| variables.rs:521:5:521:17 | ExprStmt | variables.rs:521:5:521:13 | print_i64 | | +| variables.rs:521:15:521:15 | x | variables.rs:521:5:521:16 | print_i64(...) | | +| variables.rs:523:5:523:15 | let ... = 17 | variables.rs:523:13:523:14 | 17 | | +| variables.rs:523:9:523:9 | z | variables.rs:524:5:524:22 | ExprStmt | match | +| variables.rs:523:13:523:14 | 17 | variables.rs:523:9:523:9 | z | | +| variables.rs:524:5:524:17 | print_i64_ref | variables.rs:524:20:524:20 | z | | +| variables.rs:524:5:524:21 | print_i64_ref(...) | variables.rs:518:14:525:1 | { ... } | | +| variables.rs:524:5:524:22 | ExprStmt | variables.rs:524:5:524:17 | print_i64_ref | | +| variables.rs:524:19:524:20 | &z | variables.rs:524:5:524:21 | print_i64_ref(...) | | +| variables.rs:524:20:524:20 | z | variables.rs:524:19:524:20 | &z | | +| variables.rs:532:3:534:3 | enter fn bar | variables.rs:532:15:532:18 | self | | +| variables.rs:532:3:534:3 | exit fn bar (normal) | variables.rs:532:3:534:3 | exit fn bar | | +| variables.rs:532:10:532:18 | SelfParam | variables.rs:533:5:533:32 | ExprStmt | | +| variables.rs:532:15:532:18 | self | variables.rs:532:10:532:18 | SelfParam | | +| variables.rs:532:21:534:3 | { ... } | variables.rs:532:3:534:3 | exit fn bar (normal) | | +| variables.rs:533:5:533:9 | * ... | variables.rs:533:29:533:29 | 3 | | +| variables.rs:533:5:533:31 | ... = ... | variables.rs:532:21:534:3 | { ... } | | +| variables.rs:533:5:533:32 | ExprStmt | variables.rs:533:6:533:9 | self | | +| variables.rs:533:6:533:9 | self | variables.rs:533:5:533:9 | * ... | | +| variables.rs:533:13:533:31 | MyStruct {...} | variables.rs:533:5:533:31 | ... = ... | | +| variables.rs:533:29:533:29 | 3 | variables.rs:533:13:533:31 | MyStruct {...} | | +| variables.rs:537:1:542:1 | enter fn ref_methodcall_receiver | variables.rs:538:3:538:34 | let ... = ... | | +| variables.rs:537:1:542:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:537:1:542:1 | exit fn ref_methodcall_receiver | | +| variables.rs:537:30:542:1 | { ... } | variables.rs:537:1:542:1 | exit fn ref_methodcall_receiver (normal) | | +| variables.rs:538:3:538:34 | let ... = ... | variables.rs:538:31:538:31 | 1 | | +| variables.rs:538:7:538:11 | a | variables.rs:539:3:539:10 | ExprStmt | match | +| variables.rs:538:15:538:33 | MyStruct {...} | variables.rs:538:7:538:11 | a | | +| variables.rs:538:31:538:31 | 1 | variables.rs:538:15:538:33 | MyStruct {...} | | +| variables.rs:539:3:539:3 | a | variables.rs:539:3:539:9 | a.bar(...) | | +| variables.rs:539:3:539:9 | a.bar(...) | variables.rs:541:3:541:19 | ExprStmt | | +| variables.rs:539:3:539:10 | ExprStmt | variables.rs:539:3:539:3 | a | | +| variables.rs:541:3:541:11 | print_i64 | variables.rs:541:13:541:13 | a | | +| variables.rs:541:3:541:18 | print_i64(...) | variables.rs:537:30:542:1 | { ... } | | +| variables.rs:541:3:541:19 | ExprStmt | variables.rs:541:3:541:11 | print_i64 | | +| variables.rs:541:13:541:13 | a | variables.rs:541:13:541:17 | a.val | | +| variables.rs:541:13:541:17 | a.val | variables.rs:541:3:541:18 | print_i64(...) | | +| variables.rs:544:1:578:1 | enter fn main | variables.rs:545:5:545:25 | ExprStmt | | +| variables.rs:544:1:578:1 | exit fn main (normal) | variables.rs:544:1:578:1 | exit fn main | | +| variables.rs:544:11:578:1 | { ... } | variables.rs:544:1:578:1 | exit fn main (normal) | | +| variables.rs:545:5:545:22 | immutable_variable | variables.rs:545:5:545:24 | immutable_variable(...) | | +| variables.rs:545:5:545:24 | immutable_variable(...) | variables.rs:546:5:546:23 | ExprStmt | | +| variables.rs:545:5:545:25 | ExprStmt | variables.rs:545:5:545:22 | immutable_variable | | +| variables.rs:546:5:546:20 | mutable_variable | variables.rs:546:5:546:22 | mutable_variable(...) | | +| variables.rs:546:5:546:22 | mutable_variable(...) | variables.rs:547:5:547:40 | ExprStmt | | +| variables.rs:546:5:546:23 | ExprStmt | variables.rs:546:5:546:20 | mutable_variable | | +| variables.rs:547:5:547:37 | mutable_variable_immutable_borrow | variables.rs:547:5:547:39 | mutable_variable_immutable_borrow(...) | | +| variables.rs:547:5:547:39 | mutable_variable_immutable_borrow(...) | variables.rs:548:5:548:23 | ExprStmt | | +| variables.rs:547:5:547:40 | ExprStmt | variables.rs:547:5:547:37 | mutable_variable_immutable_borrow | | +| variables.rs:548:5:548:20 | variable_shadow1 | variables.rs:548:5:548:22 | variable_shadow1(...) | | +| variables.rs:548:5:548:22 | variable_shadow1(...) | variables.rs:549:5:549:23 | ExprStmt | | +| variables.rs:548:5:548:23 | ExprStmt | variables.rs:548:5:548:20 | variable_shadow1 | | +| variables.rs:549:5:549:20 | variable_shadow2 | variables.rs:549:5:549:22 | variable_shadow2(...) | | +| variables.rs:549:5:549:22 | variable_shadow2(...) | variables.rs:550:5:550:19 | ExprStmt | | +| variables.rs:549:5:549:23 | ExprStmt | variables.rs:549:5:549:20 | variable_shadow2 | | +| variables.rs:550:5:550:16 | let_pattern1 | variables.rs:550:5:550:18 | let_pattern1(...) | | +| variables.rs:550:5:550:18 | let_pattern1(...) | variables.rs:551:5:551:19 | ExprStmt | | +| variables.rs:550:5:550:19 | ExprStmt | variables.rs:550:5:550:16 | let_pattern1 | | +| variables.rs:551:5:551:16 | let_pattern2 | variables.rs:551:5:551:18 | let_pattern2(...) | | +| variables.rs:551:5:551:18 | let_pattern2(...) | variables.rs:552:5:552:19 | ExprStmt | | +| variables.rs:551:5:551:19 | ExprStmt | variables.rs:551:5:551:16 | let_pattern2 | | +| variables.rs:552:5:552:16 | let_pattern3 | variables.rs:552:5:552:18 | let_pattern3(...) | | +| variables.rs:552:5:552:18 | let_pattern3(...) | variables.rs:553:5:553:19 | ExprStmt | | +| variables.rs:552:5:552:19 | ExprStmt | variables.rs:552:5:552:16 | let_pattern3 | | +| variables.rs:553:5:553:16 | let_pattern4 | variables.rs:553:5:553:18 | let_pattern4(...) | | +| variables.rs:553:5:553:18 | let_pattern4(...) | variables.rs:554:5:554:21 | ExprStmt | | +| variables.rs:553:5:553:19 | ExprStmt | variables.rs:553:5:553:16 | let_pattern4 | | +| variables.rs:554:5:554:18 | match_pattern1 | variables.rs:554:5:554:20 | match_pattern1(...) | | +| variables.rs:554:5:554:20 | match_pattern1(...) | variables.rs:555:5:555:21 | ExprStmt | | +| variables.rs:554:5:554:21 | ExprStmt | variables.rs:554:5:554:18 | match_pattern1 | | +| variables.rs:555:5:555:18 | match_pattern2 | variables.rs:555:5:555:20 | match_pattern2(...) | | +| variables.rs:555:5:555:20 | match_pattern2(...) | variables.rs:556:5:556:21 | ExprStmt | | +| variables.rs:555:5:555:21 | ExprStmt | variables.rs:555:5:555:18 | match_pattern2 | | +| variables.rs:556:5:556:18 | match_pattern3 | variables.rs:556:5:556:20 | match_pattern3(...) | | +| variables.rs:556:5:556:20 | match_pattern3(...) | variables.rs:557:5:557:21 | ExprStmt | | +| variables.rs:556:5:556:21 | ExprStmt | variables.rs:556:5:556:18 | match_pattern3 | | +| variables.rs:557:5:557:18 | match_pattern4 | variables.rs:557:5:557:20 | match_pattern4(...) | | +| variables.rs:557:5:557:20 | match_pattern4(...) | variables.rs:558:5:558:21 | ExprStmt | | +| variables.rs:557:5:557:21 | ExprStmt | variables.rs:557:5:557:18 | match_pattern4 | | +| variables.rs:558:5:558:18 | match_pattern5 | variables.rs:558:5:558:20 | match_pattern5(...) | | +| variables.rs:558:5:558:20 | match_pattern5(...) | variables.rs:559:5:559:21 | ExprStmt | | +| variables.rs:558:5:558:21 | ExprStmt | variables.rs:558:5:558:18 | match_pattern5 | | +| variables.rs:559:5:559:18 | match_pattern6 | variables.rs:559:5:559:20 | match_pattern6(...) | | +| variables.rs:559:5:559:20 | match_pattern6(...) | variables.rs:560:5:560:21 | ExprStmt | | +| variables.rs:559:5:559:21 | ExprStmt | variables.rs:559:5:559:18 | match_pattern6 | | +| variables.rs:560:5:560:18 | match_pattern7 | variables.rs:560:5:560:20 | match_pattern7(...) | | +| variables.rs:560:5:560:20 | match_pattern7(...) | variables.rs:561:5:561:21 | ExprStmt | | +| variables.rs:560:5:560:21 | ExprStmt | variables.rs:560:5:560:18 | match_pattern7 | | +| variables.rs:561:5:561:18 | match_pattern8 | variables.rs:561:5:561:20 | match_pattern8(...) | | +| variables.rs:561:5:561:20 | match_pattern8(...) | variables.rs:562:5:562:21 | ExprStmt | | +| variables.rs:561:5:561:21 | ExprStmt | variables.rs:561:5:561:18 | match_pattern8 | | +| variables.rs:562:5:562:18 | match_pattern9 | variables.rs:562:5:562:20 | match_pattern9(...) | | +| variables.rs:562:5:562:20 | match_pattern9(...) | variables.rs:563:5:563:36 | ExprStmt | | +| variables.rs:562:5:562:21 | ExprStmt | variables.rs:562:5:562:18 | match_pattern9 | | +| variables.rs:563:5:563:18 | param_pattern1 | variables.rs:563:20:563:22 | "a" | | +| variables.rs:563:5:563:35 | param_pattern1(...) | variables.rs:564:5:564:37 | ExprStmt | | +| variables.rs:563:5:563:36 | ExprStmt | variables.rs:563:5:563:18 | param_pattern1 | | +| variables.rs:563:20:563:22 | "a" | variables.rs:563:26:563:28 | "b" | | +| variables.rs:563:25:563:34 | TupleExpr | variables.rs:563:5:563:35 | param_pattern1(...) | | +| variables.rs:563:26:563:28 | "b" | variables.rs:563:31:563:33 | "c" | | +| variables.rs:563:31:563:33 | "c" | variables.rs:563:25:563:34 | TupleExpr | | +| variables.rs:564:5:564:18 | param_pattern2 | variables.rs:564:20:564:31 | ...::Left | | +| variables.rs:564:5:564:36 | param_pattern2(...) | variables.rs:565:5:565:26 | ExprStmt | | +| variables.rs:564:5:564:37 | ExprStmt | variables.rs:564:5:564:18 | param_pattern2 | | +| variables.rs:564:20:564:31 | ...::Left | variables.rs:564:33:564:34 | 45 | | +| variables.rs:564:20:564:35 | ...::Left(...) | variables.rs:564:5:564:36 | param_pattern2(...) | | +| variables.rs:564:33:564:34 | 45 | variables.rs:564:20:564:35 | ...::Left(...) | | +| variables.rs:565:5:565:23 | destruct_assignment | variables.rs:565:5:565:25 | destruct_assignment(...) | | +| variables.rs:565:5:565:25 | destruct_assignment(...) | variables.rs:566:5:566:23 | ExprStmt | | +| variables.rs:565:5:565:26 | ExprStmt | variables.rs:565:5:565:23 | destruct_assignment | | +| variables.rs:566:5:566:20 | closure_variable | variables.rs:566:5:566:22 | closure_variable(...) | | +| variables.rs:566:5:566:22 | closure_variable(...) | variables.rs:567:5:567:19 | ExprStmt | | +| variables.rs:566:5:566:23 | ExprStmt | variables.rs:566:5:566:20 | closure_variable | | +| variables.rs:567:5:567:16 | for_variable | variables.rs:567:5:567:18 | for_variable(...) | | +| variables.rs:567:5:567:18 | for_variable(...) | variables.rs:568:5:568:17 | ExprStmt | | +| variables.rs:567:5:567:19 | ExprStmt | variables.rs:567:5:567:16 | for_variable | | +| variables.rs:568:5:568:14 | add_assign | variables.rs:568:5:568:16 | add_assign(...) | | +| variables.rs:568:5:568:16 | add_assign(...) | variables.rs:569:5:569:13 | ExprStmt | | +| variables.rs:568:5:568:17 | ExprStmt | variables.rs:568:5:568:14 | add_assign | | +| variables.rs:569:5:569:10 | mutate | variables.rs:569:5:569:12 | mutate(...) | | +| variables.rs:569:5:569:12 | mutate(...) | variables.rs:570:5:570:17 | ExprStmt | | +| variables.rs:569:5:569:13 | ExprStmt | variables.rs:569:5:569:10 | mutate | | +| variables.rs:570:5:570:14 | mutate_arg | variables.rs:570:5:570:16 | mutate_arg(...) | | +| variables.rs:570:5:570:16 | mutate_arg(...) | variables.rs:571:5:571:12 | ExprStmt | | +| variables.rs:570:5:570:17 | ExprStmt | variables.rs:570:5:570:14 | mutate_arg | | +| variables.rs:571:5:571:9 | alias | variables.rs:571:5:571:11 | alias(...) | | +| variables.rs:571:5:571:11 | alias(...) | variables.rs:572:5:572:18 | ExprStmt | | +| variables.rs:571:5:571:12 | ExprStmt | variables.rs:571:5:571:9 | alias | | +| variables.rs:572:5:572:15 | capture_mut | variables.rs:572:5:572:17 | capture_mut(...) | | +| variables.rs:572:5:572:17 | capture_mut(...) | variables.rs:573:5:573:20 | ExprStmt | | +| variables.rs:572:5:572:18 | ExprStmt | variables.rs:572:5:572:15 | capture_mut | | +| variables.rs:573:5:573:17 | capture_immut | variables.rs:573:5:573:19 | capture_immut(...) | | +| variables.rs:573:5:573:19 | capture_immut(...) | variables.rs:574:5:574:26 | ExprStmt | | +| variables.rs:573:5:573:20 | ExprStmt | variables.rs:573:5:573:17 | capture_immut | | +| variables.rs:574:5:574:23 | async_block_capture | variables.rs:574:5:574:25 | async_block_capture(...) | | +| variables.rs:574:5:574:25 | async_block_capture(...) | variables.rs:575:5:575:14 | ExprStmt | | +| variables.rs:574:5:574:26 | ExprStmt | variables.rs:574:5:574:23 | async_block_capture | | +| variables.rs:575:5:575:11 | structs | variables.rs:575:5:575:13 | structs(...) | | +| variables.rs:575:5:575:13 | structs(...) | variables.rs:576:5:576:14 | ExprStmt | | +| variables.rs:575:5:575:14 | ExprStmt | variables.rs:575:5:575:11 | structs | | +| variables.rs:576:5:576:11 | ref_arg | variables.rs:576:5:576:13 | ref_arg(...) | | +| variables.rs:576:5:576:13 | ref_arg(...) | variables.rs:577:5:577:30 | ExprStmt | | +| variables.rs:576:5:576:14 | ExprStmt | variables.rs:576:5:576:11 | ref_arg | | +| variables.rs:577:5:577:27 | ref_methodcall_receiver | variables.rs:577:5:577:29 | ref_methodcall_receiver(...) | | +| variables.rs:577:5:577:29 | ref_methodcall_receiver(...) | variables.rs:544:11:578:1 | { ... } | | +| variables.rs:577:5:577:30 | ExprStmt | variables.rs:577:5:577:27 | ref_methodcall_receiver | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 18fc0cffc353..714c5e34a4e7 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -5,8 +5,8 @@ nonSsaVariable | variables.rs:379:13:379:13 | z | | variables.rs:392:13:392:13 | x | | variables.rs:426:13:426:13 | z | -| variables.rs:492:13:492:13 | a | -| variables.rs:529:11:529:11 | a | +| variables.rs:501:13:501:13 | a | +| variables.rs:538:11:538:11 | a | definition | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | @@ -136,11 +136,13 @@ definition | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | | variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | -| variables.rs:505:5:505:5 | a | variables.rs:501:13:501:13 | a | -| variables.rs:510:9:510:9 | x | variables.rs:510:9:510:9 | x | -| variables.rs:514:9:514:9 | z | variables.rs:514:9:514:9 | z | -| variables.rs:523:10:523:18 | SelfParam | variables.rs:523:15:523:18 | self | +| variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | +| variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | +| variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | +| variables.rs:519:9:519:9 | x | variables.rs:519:9:519:9 | x | +| variables.rs:523:9:523:9 | z | variables.rs:523:9:523:9 | z | +| variables.rs:532:10:532:18 | SelfParam | variables.rs:532:15:532:18 | self | read | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -264,12 +266,15 @@ read | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | | variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | variables.rs:502:15:502:15 | a | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | variables.rs:503:5:503:5 | a | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | variables.rs:504:15:504:15 | a | -| variables.rs:505:5:505:5 | a | variables.rs:501:13:501:13 | a | variables.rs:506:15:506:15 | a | -| variables.rs:510:9:510:9 | x | variables.rs:510:9:510:9 | x | variables.rs:512:15:512:15 | x | -| variables.rs:523:10:523:18 | SelfParam | variables.rs:523:15:523:18 | self | variables.rs:524:6:524:9 | self | +| variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:495:9:495:9 | f | +| variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:496:9:496:9 | f | +| variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | variables.rs:493:25:493:25 | n | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:511:15:511:15 | a | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:512:5:512:5 | a | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:513:15:513:15 | a | +| variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | variables.rs:515:15:515:15 | a | +| variables.rs:519:9:519:9 | x | variables.rs:519:9:519:9 | x | variables.rs:521:15:521:15 | x | +| variables.rs:532:10:532:18 | SelfParam | variables.rs:532:15:532:18 | self | variables.rs:533:6:533:9 | self | firstRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -370,10 +375,12 @@ firstRead | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | | variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | variables.rs:502:15:502:15 | a | -| variables.rs:505:5:505:5 | a | variables.rs:501:13:501:13 | a | variables.rs:506:15:506:15 | a | -| variables.rs:510:9:510:9 | x | variables.rs:510:9:510:9 | x | variables.rs:512:15:512:15 | x | -| variables.rs:523:10:523:18 | SelfParam | variables.rs:523:15:523:18 | self | variables.rs:524:6:524:9 | self | +| variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:495:9:495:9 | f | +| variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | variables.rs:493:25:493:25 | n | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:511:15:511:15 | a | +| variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | variables.rs:515:15:515:15 | a | +| variables.rs:519:9:519:9 | x | variables.rs:519:9:519:9 | x | variables.rs:521:15:521:15 | x | +| variables.rs:532:10:532:18 | SelfParam | variables.rs:532:15:532:18 | self | variables.rs:533:6:533:9 | self | lastRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -475,10 +482,12 @@ lastRead | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | | variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | variables.rs:504:15:504:15 | a | -| variables.rs:505:5:505:5 | a | variables.rs:501:13:501:13 | a | variables.rs:506:15:506:15 | a | -| variables.rs:510:9:510:9 | x | variables.rs:510:9:510:9 | x | variables.rs:512:15:512:15 | x | -| variables.rs:523:10:523:18 | SelfParam | variables.rs:523:15:523:18 | self | variables.rs:524:6:524:9 | self | +| variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:496:9:496:9 | f | +| variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | variables.rs:493:25:493:25 | n | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:513:15:513:15 | a | +| variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | variables.rs:515:15:515:15 | a | +| variables.rs:519:9:519:9 | x | variables.rs:519:9:519:9 | x | variables.rs:521:15:521:15 | x | +| variables.rs:532:10:532:18 | SelfParam | variables.rs:532:15:532:18 | self | variables.rs:533:6:533:9 | self | adjacentReads | variables.rs:35:9:35:10 | x3 | variables.rs:35:9:35:10 | x3 | variables.rs:36:15:36:16 | x3 | variables.rs:38:9:38:10 | x3 | | variables.rs:43:9:43:10 | x4 | variables.rs:43:9:43:10 | x4 | variables.rs:44:15:44:16 | x4 | variables.rs:49:15:49:16 | x4 | @@ -506,8 +515,9 @@ adjacentReads | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x | variables.rs:472:19:472:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | variables.rs:470:19:470:19 | x | | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | variables.rs:472:19:472:19 | x | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | variables.rs:502:15:502:15 | a | variables.rs:503:5:503:5 | a | -| variables.rs:501:9:501:13 | a | variables.rs:501:13:501:13 | a | variables.rs:503:5:503:5 | a | variables.rs:504:15:504:15 | a | +| variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:495:9:495:9 | f | variables.rs:496:9:496:9 | f | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:511:15:511:15 | a | variables.rs:512:5:512:5 | a | +| variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:512:5:512:5 | a | variables.rs:513:15:513:15 | a | phi | variables.rs:191:9:191:44 | [match(true)] phi | variables.rs:191:9:191:44 | a3 | variables.rs:191:22:191:23 | a3 | | variables.rs:191:9:191:44 | [match(true)] phi | variables.rs:191:9:191:44 | a3 | variables.rs:191:42:191:43 | a3 | @@ -583,4 +593,4 @@ assigns | variables.rs:438:9:438:9 | i | variables.rs:438:13:438:13 | 1 | | variables.rs:450:9:450:9 | x | variables.rs:450:13:450:13 | 2 | | variables.rs:454:9:454:9 | x | variables.rs:454:13:454:13 | 3 | -| variables.rs:505:5:505:5 | a | variables.rs:505:9:505:17 | [...] | +| variables.rs:514:5:514:5 | a | variables.rs:514:9:514:17 | [...] | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 0ccdbfb55be0..63abece5a72b 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,4 +1,8 @@ testFailures +| variables.rs:493:13:493:16 | self | Unexpected result: read_access=self | +| variables.rs:493:25:493:25 | n | Unexpected result: read_access=n | +| variables.rs:495:9:495:9 | f | Unexpected result: read_access=f | +| variables.rs:496:9:496:9 | f | Unexpected result: read_access=f | variable | variables.rs:3:14:3:14 | s | | variables.rs:7:14:7:14 | i | @@ -96,12 +100,15 @@ variable | variables.rs:462:9:462:9 | x | | variables.rs:482:20:482:23 | self | | variables.rs:486:11:486:14 | self | -| variables.rs:492:13:492:13 | a | +| variables.rs:490:23:490:26 | self | +| variables.rs:491:17:491:17 | f | +| variables.rs:491:22:491:22 | n | | variables.rs:501:13:501:13 | a | -| variables.rs:510:9:510:9 | x | -| variables.rs:514:9:514:9 | z | -| variables.rs:523:15:523:18 | self | -| variables.rs:529:11:529:11 | a | +| variables.rs:510:13:510:13 | a | +| variables.rs:519:9:519:9 | x | +| variables.rs:523:9:523:9 | z | +| variables.rs:532:15:532:18 | self | +| variables.rs:538:11:538:11 | a | variableAccess | variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | | variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | @@ -251,22 +258,26 @@ variableAccess | variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | | variables.rs:483:16:483:19 | self | variables.rs:482:20:482:23 | self | | variables.rs:487:9:487:12 | self | variables.rs:486:11:486:14 | self | -| variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a | -| variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a | -| variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a | -| variables.rs:496:5:496:5 | a | variables.rs:492:13:492:13 | a | -| variables.rs:497:15:497:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:493:13:493:16 | self | variables.rs:490:23:490:26 | self | +| variables.rs:493:25:493:25 | n | variables.rs:491:22:491:22 | n | +| variables.rs:495:9:495:9 | f | variables.rs:491:17:491:17 | f | +| variables.rs:496:9:496:9 | f | variables.rs:491:17:491:17 | f | | variables.rs:502:15:502:15 | a | variables.rs:501:13:501:13 | a | | variables.rs:503:5:503:5 | a | variables.rs:501:13:501:13 | a | | variables.rs:504:15:504:15 | a | variables.rs:501:13:501:13 | a | | variables.rs:505:5:505:5 | a | variables.rs:501:13:501:13 | a | | variables.rs:506:15:506:15 | a | variables.rs:501:13:501:13 | a | -| variables.rs:511:20:511:20 | x | variables.rs:510:9:510:9 | x | -| variables.rs:512:15:512:15 | x | variables.rs:510:9:510:9 | x | -| variables.rs:515:20:515:20 | z | variables.rs:514:9:514:9 | z | -| variables.rs:524:6:524:9 | self | variables.rs:523:15:523:18 | self | -| variables.rs:530:3:530:3 | a | variables.rs:529:11:529:11 | a | -| variables.rs:532:13:532:13 | a | variables.rs:529:11:529:11 | a | +| variables.rs:511:15:511:15 | a | variables.rs:510:13:510:13 | a | +| variables.rs:512:5:512:5 | a | variables.rs:510:13:510:13 | a | +| variables.rs:513:15:513:15 | a | variables.rs:510:13:510:13 | a | +| variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | +| variables.rs:515:15:515:15 | a | variables.rs:510:13:510:13 | a | +| variables.rs:520:20:520:20 | x | variables.rs:519:9:519:9 | x | +| variables.rs:521:15:521:15 | x | variables.rs:519:9:519:9 | x | +| variables.rs:524:20:524:20 | z | variables.rs:523:9:523:9 | z | +| variables.rs:533:6:533:9 | self | variables.rs:532:15:532:18 | self | +| variables.rs:539:3:539:3 | a | variables.rs:538:11:538:11 | a | +| variables.rs:541:13:541:13 | a | variables.rs:538:11:538:11 | a | variableWriteAccess | variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 | | variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x | @@ -277,8 +288,8 @@ variableWriteAccess | variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | | variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | | variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | -| variables.rs:496:5:496:5 | a | variables.rs:492:13:492:13 | a | | variables.rs:505:5:505:5 | a | variables.rs:501:13:501:13 | a | +| variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | variableReadAccess | variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | | variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | @@ -410,18 +421,22 @@ variableReadAccess | variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | | variables.rs:483:16:483:19 | self | variables.rs:482:20:482:23 | self | | variables.rs:487:9:487:12 | self | variables.rs:486:11:486:14 | self | -| variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a | -| variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a | -| variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a | -| variables.rs:497:15:497:15 | a | variables.rs:492:13:492:13 | a | +| variables.rs:493:13:493:16 | self | variables.rs:490:23:490:26 | self | +| variables.rs:493:25:493:25 | n | variables.rs:491:22:491:22 | n | +| variables.rs:495:9:495:9 | f | variables.rs:491:17:491:17 | f | +| variables.rs:496:9:496:9 | f | variables.rs:491:17:491:17 | f | | variables.rs:502:15:502:15 | a | variables.rs:501:13:501:13 | a | | variables.rs:503:5:503:5 | a | variables.rs:501:13:501:13 | a | | variables.rs:504:15:504:15 | a | variables.rs:501:13:501:13 | a | | variables.rs:506:15:506:15 | a | variables.rs:501:13:501:13 | a | -| variables.rs:512:15:512:15 | x | variables.rs:510:9:510:9 | x | -| variables.rs:524:6:524:9 | self | variables.rs:523:15:523:18 | self | -| variables.rs:530:3:530:3 | a | variables.rs:529:11:529:11 | a | -| variables.rs:532:13:532:13 | a | variables.rs:529:11:529:11 | a | +| variables.rs:511:15:511:15 | a | variables.rs:510:13:510:13 | a | +| variables.rs:512:5:512:5 | a | variables.rs:510:13:510:13 | a | +| variables.rs:513:15:513:15 | a | variables.rs:510:13:510:13 | a | +| variables.rs:515:15:515:15 | a | variables.rs:510:13:510:13 | a | +| variables.rs:521:15:521:15 | x | variables.rs:519:9:519:9 | x | +| variables.rs:533:6:533:9 | self | variables.rs:532:15:532:18 | self | +| variables.rs:539:3:539:3 | a | variables.rs:538:11:538:11 | a | +| variables.rs:541:13:541:13 | a | variables.rs:538:11:538:11 | a | variableInitializer | variables.rs:16:9:16:10 | x1 | variables.rs:16:14:16:16 | "a" | | variables.rs:21:13:21:14 | x2 | variables.rs:21:18:21:18 | 4 | @@ -469,11 +484,12 @@ variableInitializer | variables.rs:437:9:437:13 | block | variables.rs:437:17:439:5 | { ... } | | variables.rs:446:13:446:13 | x | variables.rs:446:17:446:17 | 1 | | variables.rs:462:9:462:9 | x | variables.rs:462:13:462:13 | 1 | -| variables.rs:492:13:492:13 | a | variables.rs:492:17:492:35 | MyStruct {...} | -| variables.rs:501:13:501:13 | a | variables.rs:501:17:501:25 | [...] | -| variables.rs:510:9:510:9 | x | variables.rs:510:13:510:14 | 16 | -| variables.rs:514:9:514:9 | z | variables.rs:514:13:514:14 | 17 | -| variables.rs:529:11:529:11 | a | variables.rs:529:15:529:33 | MyStruct {...} | +| variables.rs:491:17:491:17 | f | variables.rs:491:21:494:9 | \|...\| ... | +| variables.rs:501:13:501:13 | a | variables.rs:501:17:501:35 | MyStruct {...} | +| variables.rs:510:13:510:13 | a | variables.rs:510:17:510:25 | [...] | +| variables.rs:519:9:519:9 | x | variables.rs:519:13:519:14 | 16 | +| variables.rs:523:9:523:9 | z | variables.rs:523:13:523:14 | 17 | +| variables.rs:538:11:538:11 | a | variables.rs:538:15:538:33 | MyStruct {...} | capturedVariable | variables.rs:400:9:400:9 | x | | variables.rs:410:13:410:13 | x | diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index 61bd3d72002d..73d350f24966 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -486,6 +486,15 @@ impl MyStruct { fn id(self) -> Self { self // $ read_access=self } + + fn my_method(&mut self) { + let mut f = |n| { + // Capture of `self` + self.val += n; + }; + f(3); + f(4); + } } fn structs() { From d38975bb99b746bd6fd27e947279ad003d75d147 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Fri, 6 Dec 2024 13:07:58 +0000 Subject: [PATCH 089/213] C++: Use getType() instead of getUnderlyingType() --- cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql b/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql index e89ffac906e6..69e6e675aa0d 100644 --- a/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql @@ -26,7 +26,7 @@ where bw.hasExplicitLimit() and // has an explicit size limit destSize = max(getBufferSize(bw.getDest(), _)) and bw.getExplicitLimit() > destSize and // but it's larger than the destination - not bw.getDest().getUnderlyingType().stripType() instanceof ErroneousType // destSize may be incorrect + not bw.getDest().getType().stripType() instanceof ErroneousType // destSize may be incorrect select bw, "This '" + bw.getBWDesc() + "' operation is limited to " + bw.getExplicitLimit() + " bytes but the destination is only " + destSize + " bytes." From ed68423d6eed6aa114240d2d51ee361e48a69b16 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 6 Dec 2024 14:12:27 +0100 Subject: [PATCH 090/213] Rust: Handle captured `self` parameter in variable implementation --- rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll | 5 ++++- rust/ql/test/library-tests/variables/Ssa.expected | 5 +++++ rust/ql/test/library-tests/variables/variables.expected | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index c93fb2d832c5..b21cf924204e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -139,6 +139,9 @@ module Impl { */ IdentPat getPat() { variableDecl(definingNode, result, name) } + /** Gets the enclosing CFG scope for this variable declaration. */ + CfgScope getEnclosingCfgScope() { result = definingNode.getEnclosingCfgScope() } + /** Gets the `let` statement that introduces this variable, if any. */ LetStmt getLetStmt() { this.getPat() = result.getPat() } @@ -452,7 +455,7 @@ module Impl { Variable getVariable() { result = v } /** Holds if this access is a capture. */ - predicate isCapture() { this.getEnclosingCfgScope() != v.getPat().getEnclosingCfgScope() } + predicate isCapture() { this.getEnclosingCfgScope() != v.getEnclosingCfgScope() } override string toString() { result = name } diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 714c5e34a4e7..e126ca45c3a2 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -136,7 +136,9 @@ definition | variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | | variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | +| variables.rs:490:18:490:26 | SelfParam | variables.rs:490:23:490:26 | self | | variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | +| variables.rs:491:21:494:9 | self | variables.rs:490:23:490:26 | self | | variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | | variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | | variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | @@ -268,6 +270,7 @@ read | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | | variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:495:9:495:9 | f | | variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:496:9:496:9 | f | +| variables.rs:491:21:494:9 | self | variables.rs:490:23:490:26 | self | variables.rs:493:13:493:16 | self | | variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | variables.rs:493:25:493:25 | n | | variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:511:15:511:15 | a | | variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:512:5:512:5 | a | @@ -376,6 +379,7 @@ firstRead | variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | | variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:495:9:495:9 | f | +| variables.rs:491:21:494:9 | self | variables.rs:490:23:490:26 | self | variables.rs:493:13:493:16 | self | | variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | variables.rs:493:25:493:25 | n | | variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:511:15:511:15 | a | | variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | variables.rs:515:15:515:15 | a | @@ -483,6 +487,7 @@ lastRead | variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self | | variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self | | variables.rs:491:13:491:17 | f | variables.rs:491:17:491:17 | f | variables.rs:496:9:496:9 | f | +| variables.rs:491:21:494:9 | self | variables.rs:490:23:490:26 | self | variables.rs:493:13:493:16 | self | | variables.rs:491:22:491:22 | n | variables.rs:491:22:491:22 | n | variables.rs:493:25:493:25 | n | | variables.rs:510:9:510:13 | a | variables.rs:510:13:510:13 | a | variables.rs:513:15:513:15 | a | | variables.rs:514:5:514:5 | a | variables.rs:510:13:510:13 | a | variables.rs:515:15:515:15 | a | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 63abece5a72b..d0141b2e1e80 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -496,9 +496,11 @@ capturedVariable | variables.rs:418:13:418:13 | y | | variables.rs:426:13:426:13 | z | | variables.rs:436:13:436:13 | i | +| variables.rs:490:23:490:26 | self | capturedAccess | variables.rs:403:19:403:19 | x | | variables.rs:413:19:413:19 | x | | variables.rs:421:9:421:9 | y | | variables.rs:429:9:429:9 | z | | variables.rs:438:9:438:9 | i | +| variables.rs:493:13:493:16 | self | From 653d68ea9472b93be390545b27381c98ed7756da Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 6 Dec 2024 13:13:15 +0000 Subject: [PATCH 091/213] C#: Explicitly close writer in `DependabotProxy` --- .../DependabotProxy.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 09f5a15a21d6..f3d92b38f0c8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -62,6 +62,7 @@ public class DependabotProxy : IDisposable using var writer = certFile.CreateText(); writer.Write(cert); + writer.Close(); logger.LogInfo($"Stored Dependabot proxy certificate at {result.CertificatePath}"); From c8ccfe40a550026411ecde0a8bc78b7486a4407e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 6 Dec 2024 13:13:41 +0000 Subject: [PATCH 092/213] C#: Create certificate from string, rather than file --- .../DependabotProxy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index f3d92b38f0c8..895bd313ac30 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -66,7 +66,7 @@ public class DependabotProxy : IDisposable logger.LogInfo($"Stored Dependabot proxy certificate at {result.CertificatePath}"); - result.Certificate = new X509Certificate2(result.CertificatePath); + result.Certificate = X509Certificate2.CreateFromPem(cert); } return result; From 2816234359a47ae1142c190d3a847bb98217d216 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 10:47:41 +0100 Subject: [PATCH 093/213] C#: Update Roslyn. --- csharp/paket.dependencies | 7 +- csharp/paket.lock | 154 +++++++++++++++++++++++--------------- csharp/paket.main.bzl | 60 +++++++-------- 3 files changed, 125 insertions(+), 96 deletions(-) diff --git a/csharp/paket.dependencies b/csharp/paket.dependencies index d3e2988bba6f..824e2d73a832 100644 --- a/csharp/paket.dependencies +++ b/csharp/paket.dependencies @@ -4,7 +4,6 @@ source https://api.nuget.org/v3/index.json # behave like nuget in choosing transitive dependency versions strategy: min -nuget MessagePack >= 2.5.187 nuget Basic.CompilerLog.Util nuget Mono.Posix.NETStandard nuget Newtonsoft.Json @@ -12,9 +11,9 @@ nuget xunit nuget xunit.runner.visualstudio nuget xunit.runner.utility nuget Microsoft.NET.Test.Sdk -nuget Microsoft.CodeAnalysis.CSharp 4.9.2 -nuget Microsoft.CodeAnalysis 4.9.2 -nuget Microsoft.Build 17.8.3 +nuget Microsoft.CodeAnalysis.CSharp 4.12.0 +nuget Microsoft.CodeAnalysis 4.12.0 +nuget Microsoft.Build 17.12.6 nuget Microsoft.Win32.Primitives nuget System.Net.Primitives nuget System.Security.Principal diff --git a/csharp/paket.lock b/csharp/paket.lock index 1bfc7465d122..b80defd8c436 100644 --- a/csharp/paket.lock +++ b/csharp/paket.lock @@ -3,64 +3,99 @@ STRATEGY: MIN RESTRICTION: == net9.0 NUGET remote: https://api.nuget.org/v3/index.json - Basic.CompilerLog.Util (0.7.9) - MessagePack (>= 2.5.129) - Microsoft.CodeAnalysis (>= 4.9.2) - Microsoft.CodeAnalysis.CSharp (>= 4.9.2) - Microsoft.CodeAnalysis.VisualBasic (>= 4.9.2) - Microsoft.Extensions.ObjectPool (>= 7.0.13) - MSBuild.StructuredLogger (>= 2.2.235) + Basic.CompilerLog.Util (0.9.3) + MessagePack (>= 2.5.187) + Microsoft.CodeAnalysis (>= 4.11) + Microsoft.CodeAnalysis.CSharp (>= 4.11) + Microsoft.CodeAnalysis.VisualBasic (>= 4.11) + Microsoft.Extensions.ObjectPool (>= 9.0) + MSBuild.StructuredLogger (>= 2.2.243) + System.Buffers (>= 4.6) Humanizer.Core (2.14.1) - MessagePack (2.5.192) - MessagePack.Annotations (>= 2.5.192) + MessagePack (2.5.187) + MessagePack.Annotations (>= 2.5.187) Microsoft.NET.StringTools (>= 17.6.3) - MessagePack.Annotations (2.5.192) - Microsoft.Build (17.8.3) - Microsoft.Build.Framework (>= 17.8.3) - Microsoft.NET.StringTools (>= 17.8.3) - System.Collections.Immutable (>= 7.0) - System.Configuration.ConfigurationManager (>= 7.0) - System.Reflection.Metadata (>= 7.0) - System.Reflection.MetadataLoadContext (>= 7.0) - System.Security.Principal.Windows (>= 5.0) - System.Threading.Tasks.Dataflow (>= 7.0) - Microsoft.Build.Framework (17.8.3) + MessagePack.Annotations (2.5.187) + Microsoft.Bcl.AsyncInterfaces (8.0) + Microsoft.Build (17.12.6) + Microsoft.Build.Framework (>= 17.12.6) + Microsoft.NET.StringTools (>= 17.12.6) + System.Collections.Immutable (>= 8.0) + System.Configuration.ConfigurationManager (>= 8.0) + System.Reflection.Metadata (>= 8.0) + System.Reflection.MetadataLoadContext (>= 8.0) + Microsoft.Build.Framework (17.12.6) Microsoft.Build.Utilities.Core (17.5) Microsoft.Build.Framework (>= 17.5) Microsoft.NET.StringTools (>= 17.5) System.Collections.Immutable (>= 6.0) System.Configuration.ConfigurationManager (>= 6.0) - Microsoft.CodeAnalysis (4.9.2) - Microsoft.CodeAnalysis.CSharp.Workspaces (4.9.2) - Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.9.2) - Microsoft.CodeAnalysis.Analyzers (3.3.4) - Microsoft.CodeAnalysis.Common (4.9.2) + Microsoft.CodeAnalysis (4.12) + Humanizer.Core (>= 2.14.1) + Microsoft.Bcl.AsyncInterfaces (>= 8.0) Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) + Microsoft.CodeAnalysis.CSharp.Workspaces (4.12) + Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.12) + System.Buffers (>= 4.5.1) System.Collections.Immutable (>= 8.0) + System.Composition (>= 8.0) + System.IO.Pipelines (>= 8.0) + System.Memory (>= 4.5.5) + System.Numerics.Vectors (>= 4.5) System.Reflection.Metadata (>= 8.0) System.Runtime.CompilerServices.Unsafe (>= 6.0) - Microsoft.CodeAnalysis.CSharp (4.9.2) - Microsoft.CodeAnalysis.Common (4.9.2) - Microsoft.CodeAnalysis.CSharp.Workspaces (4.9.2) + System.Text.Encoding.CodePages (>= 7.0) + System.Threading.Channels (>= 7.0) + System.Threading.Tasks.Extensions (>= 4.5.4) + Microsoft.CodeAnalysis.Analyzers (3.3.4) + Microsoft.CodeAnalysis.Common (4.12) + Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) + System.Collections.Immutable (>= 8.0) + System.Reflection.Metadata (>= 8.0) + Microsoft.CodeAnalysis.CSharp (4.12) + Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) + Microsoft.CodeAnalysis.Common (4.12) + System.Collections.Immutable (>= 8.0) + System.Reflection.Metadata (>= 8.0) + Microsoft.CodeAnalysis.CSharp.Workspaces (4.12) + Humanizer.Core (>= 2.14.1) + Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) + Microsoft.CodeAnalysis.Common (4.12) + Microsoft.CodeAnalysis.CSharp (4.12) + Microsoft.CodeAnalysis.Workspaces.Common (4.12) + System.Collections.Immutable (>= 8.0) + System.Composition (>= 8.0) + System.IO.Pipelines (>= 8.0) + System.Reflection.Metadata (>= 8.0) + System.Threading.Channels (>= 7.0) + Microsoft.CodeAnalysis.VisualBasic (4.12) + Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) + Microsoft.CodeAnalysis.Common (4.12) + System.Collections.Immutable (>= 8.0) + System.Reflection.Metadata (>= 8.0) + Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.12) Humanizer.Core (>= 2.14.1) - Microsoft.CodeAnalysis.Common (4.9.2) - Microsoft.CodeAnalysis.CSharp (4.9.2) - Microsoft.CodeAnalysis.Workspaces.Common (4.9.2) - Microsoft.CodeAnalysis.VisualBasic (4.9.2) - Microsoft.CodeAnalysis.Common (4.9.2) - Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.9.2) - Microsoft.CodeAnalysis.Common (4.9.2) - Microsoft.CodeAnalysis.VisualBasic (4.9.2) - Microsoft.CodeAnalysis.Workspaces.Common (4.9.2) - Microsoft.CodeAnalysis.Workspaces.Common (4.9.2) + Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) + Microsoft.CodeAnalysis.Common (4.12) + Microsoft.CodeAnalysis.VisualBasic (4.12) + Microsoft.CodeAnalysis.Workspaces.Common (4.12) + System.Collections.Immutable (>= 8.0) + System.Composition (>= 8.0) + System.IO.Pipelines (>= 8.0) + System.Reflection.Metadata (>= 8.0) + System.Threading.Channels (>= 7.0) + Microsoft.CodeAnalysis.Workspaces.Common (4.12) Humanizer.Core (>= 2.14.1) - Microsoft.CodeAnalysis.Common (4.9.2) + Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) + Microsoft.CodeAnalysis.Common (4.12) + System.Collections.Immutable (>= 8.0) System.Composition (>= 8.0) System.IO.Pipelines (>= 8.0) - System.Threading.Channels (>= 8.0) + System.Reflection.Metadata (>= 8.0) + System.Threading.Channels (>= 7.0) Microsoft.CodeCoverage (17.12) - Microsoft.Extensions.ObjectPool (7.0.13) - Microsoft.NET.StringTools (17.8.3) + Microsoft.Extensions.ObjectPool (9.0) + Microsoft.NET.StringTools (17.12.6) Microsoft.NET.Test.Sdk (17.12) Microsoft.CodeCoverage (>= 17.12) Microsoft.TestPlatform.TestHost (>= 17.12) @@ -75,12 +110,12 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - Microsoft.Win32.SystemEvents (7.0) Mono.Posix.NETStandard (1.0) - MSBuild.StructuredLogger (2.2.235) + MSBuild.StructuredLogger (2.2.243) Microsoft.Build.Framework (>= 17.5) Microsoft.Build.Utilities.Core (>= 17.5) Newtonsoft.Json (13.0.3) + System.Buffers (4.6) System.Collections.Immutable (8.0) System.Composition (8.0) System.Composition.AttributedModel (>= 8.0) @@ -98,13 +133,10 @@ NUGET System.Composition.AttributedModel (>= 8.0) System.Composition.Hosting (>= 8.0) System.Composition.Runtime (>= 8.0) - System.Configuration.ConfigurationManager (7.0) - System.Diagnostics.EventLog (>= 7.0) - System.Security.Cryptography.ProtectedData (>= 7.0) - System.Security.Permissions (>= 7.0) - System.Diagnostics.EventLog (7.0) - System.Drawing.Common (7.0) - Microsoft.Win32.SystemEvents (>= 7.0) + System.Configuration.ConfigurationManager (8.0) + System.Diagnostics.EventLog (>= 8.0) + System.Security.Cryptography.ProtectedData (>= 8.0) + System.Diagnostics.EventLog (8.0) System.IO (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -123,16 +155,18 @@ NUGET System.IO.FileSystem.Primitives (4.3) System.Runtime (>= 4.3) System.IO.Pipelines (8.0) + System.Memory (4.5.5) System.Net.Primitives (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) System.Runtime (>= 4.3.1) System.Runtime.Handles (>= 4.3) + System.Numerics.Vectors (4.5) System.Reflection.Metadata (8.0) System.Collections.Immutable (>= 8.0) - System.Reflection.MetadataLoadContext (7.0) - System.Collections.Immutable (>= 7.0) - System.Reflection.Metadata (>= 7.0) + System.Reflection.MetadataLoadContext (8.0) + System.Collections.Immutable (>= 8.0) + System.Reflection.Metadata (>= 8.0) System.Runtime (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) @@ -141,27 +175,23 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Security.Cryptography.ProtectedData (7.0) - System.Security.Permissions (7.0) - System.Windows.Extensions (>= 7.0) + System.Security.Cryptography.ProtectedData (8.0) System.Security.Principal (4.3) System.Runtime (>= 4.3) - System.Security.Principal.Windows (5.0) System.Text.Encoding (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Threading.Channels (8.0) + System.Text.Encoding.CodePages (7.0) + System.Threading.Channels (7.0) System.Threading.Tasks (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Threading.Tasks.Dataflow (7.0) + System.Threading.Tasks.Extensions (4.5.4) System.Threading.ThreadPool (4.3) System.Runtime (>= 4.3) System.Runtime.Handles (>= 4.3) - System.Windows.Extensions (7.0) - System.Drawing.Common (>= 7.0) xunit (2.9.2) xunit.analyzers (>= 1.16) xunit.assert (>= 2.9.2) diff --git a/csharp/paket.main.bzl b/csharp/paket.main.bzl index 2ec4e25c5f92..413bf68ddf3f 100644 --- a/csharp/paket.main.bzl +++ b/csharp/paket.main.bzl @@ -7,64 +7,64 @@ def main(): nuget_repo( name = "paket.main", packages = [ - {"name": "Basic.CompilerLog.Util", "id": "Basic.CompilerLog.Util", "version": "0.7.9", "sha512": "sha512-Z50VRWQIXO0E8GM3ZFdL+Mq+YdmPh+OEJ7bDXPIsp1TQJB07i09WdlEb4MucSz9wG4exeLC3HGt23O3NOFL30g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net462": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net47": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net471": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net472": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net48": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net5.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net6.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net7.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net8.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net9.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netcoreapp2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netcoreapp2.2": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netcoreapp3.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netcoreapp3.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netstandard2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Basic.CompilerLog.Util", "id": "Basic.CompilerLog.Util", "version": "0.9.3", "sha512": "sha512-hgu/4KttHz9bXOISmomz1uO4WidkXqBbSu4MjVgj3SeJ/bH4t+nkZ5qybpqpZJHf04hdXlyt/ux0OWv5/xEKRQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net462": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net47": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net471": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net472": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net48": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net5.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net6.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net7.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net8.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net9.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.2": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Humanizer.Core", "id": "Humanizer.Core", "version": "2.14.1", "sha512": "sha512-yzqGU/HKNLZ9Uvr6kvSc3wYV/S5O/IvklIUW5WF7MuivGLY8wS5IZnLPkt7D1KW8Et2Enl0I3Lzg2vGWM24Xsw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MessagePack", "id": "MessagePack", "version": "2.5.192", "sha512": "sha512-SnrwSQIKWfxcQvzE1TCUPvJ7A/44KFBDcmCc+YUDIq8QalCf0bGAjiBoAFewhJ81QuS5FsCNCOcKn+IURYlbAQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "net48": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net7.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net8.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "2.5.192", "sha512": "sha512-pE/SD2N0+nDAU8BtTHqjyIhLM2L5Mb0NiO4hW0ybiv2I+BbK0JEaGtbKpeEmOvKT+5s2hds0gvk/GrAHhgcpdw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.Build", "id": "Microsoft.Build", "version": "17.8.3", "sha512": "sha512-jRz++ltVTU9xGAYSnI7fGwLIsg/AwINaxlXaJrcMszO+fyh1xJ8gKZkDz10foT/5y26jZC6G93wyp85NVHc+lA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Security.Principal.Windows", "System.Threading.Tasks.Dataflow", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Security.Principal.Windows", "System.Threading.Tasks.Dataflow", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Security.Principal.Windows", "System.Threading.Tasks.Dataflow", "System.Reflection.Metadata"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Security.Principal.Windows", "System.Threading.Tasks.Dataflow", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.Build.Framework", "id": "Microsoft.Build.Framework", "version": "17.8.3", "sha512": "sha512-xDOoj8lpNohM0Sieo4sJ47m/3SAquclF8wFZeAYYuDRHc8hII4XWPhSafFmw5A4TMGOyV08Z1TrrqES9HxMB3Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "net462": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "net47": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "net471": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "net6.0": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "net7.0": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "netcoreapp2.1": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "netcoreapp2.2": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "netcoreapp3.0": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "netcoreapp3.1": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"], "netstandard2.1": ["System.Runtime.CompilerServices.Unsafe", "System.Security.Principal.Windows"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.Build.Utilities.Core", "id": "Microsoft.Build.Utilities.Core", "version": "17.5.0", "sha512": "sha512-La1NFQ7SVz1pVGEUnG15BQG26jJkRMCiitySBXLhuTYf9IG6eZ5j5UFjnM4EFKSVKbictRv+D/F0dQtsCiK9ag==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "net462": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "net47": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "net471": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Security.Permissions"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis", "id": "Microsoft.CodeAnalysis", "version": "4.9.2", "sha512": "sha512-CJh/yj/ZWnDn0qRDovqeb7qhXl4MDFR5CELAQ2B5K9dcEC6JPg7Fkm2ADRiBM4UF7ub+n6fkiE5+/+GPD5WbFg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net462": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net47": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net471": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net472": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net48": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net5.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net6.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net7.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net8.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "net9.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"], "netstandard2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MessagePack", "id": "MessagePack", "version": "2.5.187", "sha512": "sha512-gZ6QLyipngHr+n/XWWm7TM26j9vkM6+B6RXBuv+ia/DjJsG6pJaQbVuz/+RBFJrSd98eTk+CqHwrE1DtFyR1bw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net7.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net8.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "2.5.187", "sha512": "sha512-1IThHnbMw6Ah9Mb/bZfWEwZDo3ZbsU9usGAOeCs/oPWsklrdxVDNZHjIg6myvjlQvL7oMhagEeb+07kjL410aQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.Bcl.AsyncInterfaces", "id": "Microsoft.Bcl.AsyncInterfaces", "version": "8.0.0", "sha512": "sha512-ecsHc9lEZZJM7k5HHZA1PV2N+ELEarLFcssV2bn7XQIJoaiNZDkplTNcX+VKANfDGURAuEyVFCcRu7aFy16VUg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Threading.Tasks.Extensions"], "net462": ["System.Threading.Tasks.Extensions"], "net47": ["System.Threading.Tasks.Extensions"], "net471": ["System.Threading.Tasks.Extensions"], "net472": ["System.Threading.Tasks.Extensions"], "net48": ["System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.Build", "id": "Microsoft.Build", "version": "17.12.6", "sha512": "sha512-YEiL5xKowbwnr52YroALNHg8YurjLyFTlhv3USrswhubuxN2ldY1TmQpBKQ4K28UgWJV9BxTVXY9/CecMNDeOA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.Build.Framework", "id": "Microsoft.Build.Framework", "version": "17.12.6", "sha512": "sha512-UjfxnrQN9BPVtO0Kvv2FB5dpN2CX5snc7coq5vVQdbCV6kdSpI/r+GZTLvU/5BTT8y8bvIUqoocxRR674N6bWg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.Build.Utilities.Core", "id": "Microsoft.Build.Utilities.Core", "version": "17.5.0", "sha512": "sha512-La1NFQ7SVz1pVGEUnG15BQG26jJkRMCiitySBXLhuTYf9IG6eZ5j5UFjnM4EFKSVKbictRv+D/F0dQtsCiK9ag==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net462": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net47": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net471": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis", "id": "Microsoft.CodeAnalysis", "version": "4.12.0", "sha512": "sha512-saGSG86irNb5MX0/7j0Lx2T0jSGQuqa6QlohBHBcTzObPyMunQZIuIWVXlEiKwcrcEQm4rtUg/5FW43s0dqH7Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net9.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.CodeAnalysis.Analyzers", "id": "Microsoft.CodeAnalysis.Analyzers", "version": "3.3.4", "sha512": "sha512-I+Riw6/6WjNICydoiNpDjN/GGP7u4XsL6VsI9lG/OjFufH3flvSEy/fxNhGDVGwZWwq/5BlnqX+LH2dmheaPfg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis.Common", "id": "Microsoft.CodeAnalysis.Common", "version": "4.9.2", "sha512": "sha512-XCtqPQdnoqfrBSidFWIESm8exXVHF4yPY94e84St2PVZPc2bGeQNXdFNwadu1Bd2sr/bAgM5B0UHbCqBz+/SeQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net462": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net47": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net471": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net472": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net9.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis.CSharp", "id": "Microsoft.CodeAnalysis.CSharp", "version": "4.9.2", "sha512": "sha512-oy5nUdJOaOQEjUZimhYH4xU6nVxt8ctkdP7HT2fc32ecvH50QeIwJXgjNt7MGUyhJO+Wd3SipQWQ5QyDw7VuLg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common"], "net462": ["Microsoft.CodeAnalysis.Common"], "net47": ["Microsoft.CodeAnalysis.Common"], "net471": ["Microsoft.CodeAnalysis.Common"], "net472": ["Microsoft.CodeAnalysis.Common"], "net48": ["Microsoft.CodeAnalysis.Common"], "net5.0": ["Microsoft.CodeAnalysis.Common"], "net6.0": ["Microsoft.CodeAnalysis.Common"], "net7.0": ["Microsoft.CodeAnalysis.Common"], "net8.0": ["Microsoft.CodeAnalysis.Common"], "net9.0": ["Microsoft.CodeAnalysis.Common"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis.CSharp.Workspaces", "id": "Microsoft.CodeAnalysis.CSharp.Workspaces", "version": "4.9.2", "sha512": "sha512-NfP1c+OjN0KbFxhSN2DXilIjZzH6p/DzkF+yemB0v/7nhQkvRq7cDle6TpWgpw12JKOSa6lSirfECbRSyLFGhA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis.VisualBasic", "id": "Microsoft.CodeAnalysis.VisualBasic", "version": "4.9.2", "sha512": "sha512-Jx3d7jpZ2bdCb/FzVBPD2a4P8jFDhdoEugGoxLxVKtBDzHA5+RdQL0BWvzwrP1Tdw3YPshrUelNlZXmcNXqZyA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common"], "net462": ["Microsoft.CodeAnalysis.Common"], "net47": ["Microsoft.CodeAnalysis.Common"], "net471": ["Microsoft.CodeAnalysis.Common"], "net472": ["Microsoft.CodeAnalysis.Common"], "net48": ["Microsoft.CodeAnalysis.Common"], "net5.0": ["Microsoft.CodeAnalysis.Common"], "net6.0": ["Microsoft.CodeAnalysis.Common"], "net7.0": ["Microsoft.CodeAnalysis.Common"], "net8.0": ["Microsoft.CodeAnalysis.Common"], "net9.0": ["Microsoft.CodeAnalysis.Common"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "id": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "version": "4.9.2", "sha512": "sha512-v07rvZvckHiPLDzKXFs9AXfEGsDeTvR+N9YHO9wQqboXgms4HCv0fTrZOOgqM/aVS7racJKRo1tf62UfjqMeEw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis.Workspaces.Common", "id": "Microsoft.CodeAnalysis.Workspaces.Common", "version": "4.9.2", "sha512": "sha512-DieswZYcYVGDPeT6m7M4i+0aKkjSgyjmI9z9HJEDSRZdvXfKYLEKwmlFGUTyzFS4brnyMCwLSiw2KWVAydpzVA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net462": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net47": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net471": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net472": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net48": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis.Common", "id": "Microsoft.CodeAnalysis.Common", "version": "4.12.0", "sha512": "sha512-83sYPF0SekVhecApCFXsLCsQL9qFzAl5ieCEqVb8Uo08nV34YD3cfq7FLv6EkhnAwPbP7ky19sAEEqYLDUrxWA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net462": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net47": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net471": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net472": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net48": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net5.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net6.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net7.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis.CSharp", "id": "Microsoft.CodeAnalysis.CSharp", "version": "4.12.0", "sha512": "sha512-Dbb/taxFill9/+2HRJufXW3udAtJaQw3+LzbWTDyYx7Z02HVdU5ydMXXTqg5lFgSmLDNBe+B8jRuI2eYw8OBOA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis.CSharp.Workspaces", "id": "Microsoft.CodeAnalysis.CSharp.Workspaces", "version": "4.12.0", "sha512": "sha512-YwFqDAYHJrf02FyGU8nQnaWNryZXuDV0r8pVgWjRtxAFDWfaU5CZxvU/4NsS6GSnEsWp6W/e49QMHsDXTJW/KA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis.VisualBasic", "id": "Microsoft.CodeAnalysis.VisualBasic", "version": "4.12.0", "sha512": "sha512-le1vRWFDjf9mYrVwhxw+rNZpRg/AvBi9aK+4zfn47qN2S7XPXtDwdz/dvxVg8bKJMfkwK1WPi2Bvlc7naPdaYg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "id": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "version": "4.12.0", "sha512": "sha512-j/XDFfNu38FSTJOIhkB8pvLWNVNqNhaZTRtLuH/WsHUsnYfIztaDW9seR7OsUBF5LuZIKQ9uaCrj7p+0/BgPkw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis.Workspaces.Common", "id": "Microsoft.CodeAnalysis.Workspaces.Common", "version": "4.12.0", "sha512": "sha512-bzZOMF3kAtQhc5kcUILy0GyhgePksk/j9DJtlvFex1UYNgXJUoEkA6IUGootH1Z6GH4Z5BuLNXiFzsz9oJwbcQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.CodeCoverage", "id": "Microsoft.CodeCoverage", "version": "17.12.0", "sha512": "sha512-POBqg788rrLApvncy8rvtyJ3ynsBdU0/SGUXD+vPqyRDM/aUJbPZWx01qalGJRK1GcArSku8QDd9AVMa0TkCkA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.Extensions.ObjectPool", "id": "Microsoft.Extensions.ObjectPool", "version": "7.0.13", "sha512": "sha512-N66kAzKBfcs4zIX/iVMUOhfn8Xv3Ye1QpLGS8IUSpCHa+Vxh2ZsdDiqd0Y2m7ryPU6FU2LOTnZ+0ymmm83vC6w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.NET.StringTools", "id": "Microsoft.NET.StringTools", "version": "17.8.3", "sha512": "sha512-3N/Ika66JZeORrIZ68fap6M0LSQ9+SQz277NxjA/dxETnR3dZwJXj67jAAc4FkijG6w//QzrC5NEregtIVjz1w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Runtime.CompilerServices.Unsafe"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.Extensions.ObjectPool", "id": "Microsoft.Extensions.ObjectPool", "version": "9.0.0", "sha512": "sha512-dY64S9XmssfAjwvuGMHleFj2cKIhIFUU2D+Kr1D1Y+92mAPN/39HQMJay2FHxSRcDEI9hATivRV/I1N7QxVJcQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.NET.StringTools", "id": "Microsoft.NET.StringTools", "version": "17.12.6", "sha512": "sha512-uCT/G0W1wUteqfrriWHfLfFmArka8ISo6nUkC5gQzYZYm2PSTuqfS14DEsY0gqDuQpcLLLaYTDcEM0SA2Za5vA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.NET.Test.Sdk", "id": "Microsoft.NET.Test.Sdk", "version": "17.12.0", "sha512": "sha512-hGf8I8+yo15etavoMd+7OXcOG6/G7HYPDEJg5aQnhMzsxaUpq+udNZzSxmEN9rGTWMZOAVFcyNXNL7YBsN6chw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": ["Microsoft.CodeCoverage"], "net47": ["Microsoft.CodeCoverage"], "net471": ["Microsoft.CodeCoverage"], "net472": ["Microsoft.CodeCoverage"], "net48": ["Microsoft.CodeCoverage"], "net5.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net6.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net7.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net8.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net9.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.NETCore.Platforms", "id": "Microsoft.NETCore.Platforms", "version": "1.1.1", "sha512": "sha512-mDUJD1eLXIzmUnWCzWlmNQZGDp/cVGT8KyhzMcJNk2nlfdFUOoZai9idT8/FacJr8Nv8zhAmdf39FHm5qWUoGQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.NETCore.Targets", "id": "Microsoft.NETCore.Targets", "version": "1.1.3", "sha512": "sha512-pxwq8g2PYRiEF5KXVjmZFMNTqsg2Gr1puv/pR1sqAduAKHAGbaCuJ6+yc3pAJseClQUD29S2Ubrm7n/ZD78dUg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.TestPlatform.ObjectModel", "id": "Microsoft.TestPlatform.ObjectModel", "version": "17.12.0", "sha512": "sha512-klsXMgAPNWYo3ceakLkod4wYrk4lAV2Ehi676zUKgiVpQ5Yj6q3vsMhk/3pm97Ltk/hdcSW0rJKJvcQvTzPgYA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Reflection.Metadata"], "net462": ["System.Reflection.Metadata"], "net47": ["System.Reflection.Metadata"], "net471": ["System.Reflection.Metadata"], "net472": ["System.Reflection.Metadata"], "net48": ["System.Reflection.Metadata"], "net5.0": ["System.Reflection.Metadata"], "net6.0": ["System.Reflection.Metadata"], "net7.0": ["System.Reflection.Metadata"], "net8.0": ["System.Reflection.Metadata"], "net9.0": ["System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Reflection.Metadata"], "netcoreapp2.1": ["System.Reflection.Metadata"], "netcoreapp2.2": ["System.Reflection.Metadata"], "netcoreapp3.0": ["System.Reflection.Metadata"], "netcoreapp3.1": ["System.Reflection.Metadata"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Reflection.Metadata"], "netstandard2.1": ["System.Reflection.Metadata"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.TestPlatform.TestHost", "id": "Microsoft.TestPlatform.TestHost", "version": "17.12.0", "sha512": "sha512-gYM2BOGQvFEP2fZt61f3f5Gu+imL1G1bvGUrbJjpYcl66R6uzs5yESg0XMn8IgUgldz8RldOOaYmjk2KcSeG1Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net6.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net7.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net8.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net9.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.Win32.Primitives", "id": "Microsoft.Win32.Primitives", "version": "4.3.0", "sha512": "sha512-Nm8Hp51y9tYcK3xD6qk43Wjftrg1mdH24CCJsTb6gr7HS21U1uA+CKPGEtUcVZbjU1y8Kynzm5eoJ7Pnx5gm8A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.Win32.SystemEvents", "id": "Microsoft.Win32.SystemEvents", "version": "7.0.0", "sha512": "sha512-GO6SWx/wSZIFvxOn67Y6OiIGdz9JGCg5CRDDbSAAvBDQeZFbybu9sEOUb9w/vUlQv+A2XakTFZg9Ug1w+tgbWQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Mono.Posix.NETStandard", "id": "Mono.Posix.NETStandard", "version": "1.0.0", "sha512": "sha512-RtGiutQZJAmajvQ0QvBvh73VJye85iW9f9tjZlzF88idLxNMo4lAktP/4Y9ilCpais0LDO0tpoICt9Hdv6wooA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MSBuild.StructuredLogger", "id": "MSBuild.StructuredLogger", "version": "2.2.235", "sha512": "sha512-9ige0SOByBirmeIYZ3fwlwbnXrYZA2trdZV7Mad8z7FiuGbVNOVkGYrzln/+G1eIvmRh9J0pt6xBLwqIYaMxyQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net462": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net47": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net471": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net472": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net48": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MSBuild.StructuredLogger", "id": "MSBuild.StructuredLogger", "version": "2.2.243", "sha512": "sha512-Egw6dLclkDtfoVK+ncghRfYDEWiHjjmhbJFdqeZfqL/Ddtg+JoHzSMblBBTrn317coXZ7WMDELW3C9ZCpn0ByQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net462": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net47": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net471": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net472": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net48": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Newtonsoft.Json", "id": "Newtonsoft.Json", "version": "13.0.3", "sha512": "sha512-mbJSvHfRxfX3tR/U6n1WU+mWHXswYc+SB/hkOpx8yZZe68hNZGfymJu0cjsaJEkVzCMqePiU6LdIyogqfIn7kg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Collections.Immutable", "id": "System.Collections.Immutable", "version": "8.0.0", "sha512": "sha512-BXqVkcIrhimvvem6q2ChWkuW6XYYirvb6FlhvuwaMoBqBdpcr4nehJBKP65Tw40UqcUM6oDoODsecM0yjZ6AUw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Runtime.CompilerServices.Unsafe"], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Buffers", "id": "System.Buffers", "version": "4.6.0", "sha512": "sha512-iRbJyTSX9bJVpURLGLiW8Fgk5Vfm5iGCztw4IG4IJYcxJy+BXTCEgEWFeJtO6c+kPnUmQu87KK5m188+qbErcQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Collections.Immutable", "id": "System.Collections.Immutable", "version": "8.0.0", "sha512": "sha512-BXqVkcIrhimvvem6q2ChWkuW6XYYirvb6FlhvuwaMoBqBdpcr4nehJBKP65Tw40UqcUM6oDoODsecM0yjZ6AUw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Runtime.CompilerServices.Unsafe"], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Composition", "id": "System.Composition", "version": "8.0.0", "sha512": "sha512-/AZ/S+sX6awiSeSvOv7997aiwbU6HCcOBJDLecdYQJjDo+4nYCrWwWKQQIZ38VZ6BLh1pDmcYFPZockIuoRIYw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net462": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net47": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net471": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net472": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net48": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net5.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net6.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net7.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net8.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net9.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp2.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp2.2": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp3.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp3.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netstandard2.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Composition.AttributedModel", "id": "System.Composition.AttributedModel", "version": "8.0.0", "sha512": "sha512-gmEwpwXz+COPtuAASK+ichAg8+0oQAaPOV59g6fDdnt1KWbrymdixAn06bNbkdCUGcBXb8RX5k79cqg0Hqlv1g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Composition.Convention", "id": "System.Composition.Convention", "version": "8.0.0", "sha512": "sha512-MP7qMadQGUcMOEyGON5dmy9T+OXubvIx04kFHvTVPfZ/9+ns8dqmFToxoF7IDzJVSWmtOQHDUP2fL1x8F6slTA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel"], "net462": ["System.Composition.AttributedModel"], "net47": ["System.Composition.AttributedModel"], "net471": ["System.Composition.AttributedModel"], "net472": ["System.Composition.AttributedModel"], "net48": ["System.Composition.AttributedModel"], "net5.0": ["System.Composition.AttributedModel"], "net6.0": ["System.Composition.AttributedModel"], "net7.0": ["System.Composition.AttributedModel"], "net8.0": ["System.Composition.AttributedModel"], "net9.0": ["System.Composition.AttributedModel"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel"], "netcoreapp2.1": ["System.Composition.AttributedModel"], "netcoreapp2.2": ["System.Composition.AttributedModel"], "netcoreapp3.0": ["System.Composition.AttributedModel"], "netcoreapp3.1": ["System.Composition.AttributedModel"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel"], "netstandard2.1": ["System.Composition.AttributedModel"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Composition.Hosting", "id": "System.Composition.Hosting", "version": "8.0.0", "sha512": "sha512-HK6mWN38TLXo0jQOzR6so8cH1J8/6MzCfSsQS15bWbFEYKeonKRAZKyTC2E92o+wB1KCkocNpOy01ix61JnWjQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.Runtime"], "net462": ["System.Composition.Runtime"], "net47": ["System.Composition.Runtime"], "net471": ["System.Composition.Runtime"], "net472": ["System.Composition.Runtime"], "net48": ["System.Composition.Runtime"], "net5.0": ["System.Composition.Runtime"], "net6.0": ["System.Composition.Runtime"], "net7.0": ["System.Composition.Runtime"], "net8.0": ["System.Composition.Runtime"], "net9.0": ["System.Composition.Runtime"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.Runtime"], "netcoreapp2.1": ["System.Composition.Runtime"], "netcoreapp2.2": ["System.Composition.Runtime"], "netcoreapp3.0": ["System.Composition.Runtime"], "netcoreapp3.1": ["System.Composition.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.Runtime"], "netstandard2.1": ["System.Composition.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Composition.Runtime", "id": "System.Composition.Runtime", "version": "8.0.0", "sha512": "sha512-hgGA3KDIx9FN3WYkpMvy0pUqWAul9BTehmqq49dqPxu5E+MbUKqgksU5XRP8M9LoBPZFa8FqBbKeFgCZ3rja2w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Composition.TypedParts", "id": "System.Composition.TypedParts", "version": "8.0.0", "sha512": "sha512-rKu0GdZ4JYOWUF7br1W7UQFI/UgzWTU03CHY6tnTLZXCMth6YSADGJRRQYrLzpwh2+NuNcBIuv7a7x8J1xsfdw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net462": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net47": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net471": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net472": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net48": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net5.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net6.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net7.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net8.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net9.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp2.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp2.2": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp3.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp3.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netstandard2.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Configuration.ConfigurationManager", "id": "System.Configuration.ConfigurationManager", "version": "7.0.0", "sha512": "sha512-g3iVgTpIcjMYpH+sMq5VKjytevOJv+ABsYLKOLj0UZrXp3diFFdnPPqL+orxMD5ktyaTagg2S7ONJInu8itIaQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "net462": ["System.Security.Permissions"], "net47": ["System.Security.Permissions"], "net471": ["System.Security.Permissions"], "net472": ["System.Security.Permissions"], "net48": ["System.Security.Permissions"], "net5.0": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "net6.0": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "net7.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "net8.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "net9.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "netcoreapp2.1": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "netcoreapp2.2": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "netcoreapp3.0": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "netcoreapp3.1": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"], "netstandard2.1": ["System.Security.Cryptography.ProtectedData", "System.Security.Permissions"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Diagnostics.EventLog", "id": "System.Diagnostics.EventLog", "version": "7.0.0", "sha512": "sha512-m/H4Rg7KukGEmfRpl+rXU1UbMN3GYbv42cbMHRgMwHIiUL3svKoFFR76Fk/mHN5TgrwGx64fS0Fp+p3qICKg/Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Security.Principal.Windows"], "net462": ["System.Security.Principal.Windows"], "net47": ["System.Security.Principal.Windows"], "net471": ["System.Security.Principal.Windows"], "net472": ["System.Security.Principal.Windows"], "net48": ["System.Security.Principal.Windows"], "net5.0": ["System.Security.Principal.Windows"], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Security.Principal.Windows"], "netcoreapp2.1": ["System.Security.Principal.Windows"], "netcoreapp2.2": ["System.Security.Principal.Windows"], "netcoreapp3.0": ["System.Security.Principal.Windows"], "netcoreapp3.1": ["System.Security.Principal.Windows"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Security.Principal.Windows"], "netstandard2.1": ["System.Security.Principal.Windows"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Drawing.Common", "id": "System.Drawing.Common", "version": "7.0.0", "sha512": "sha512-0TJd5U26gRDgGa/rqABgHC5OBAiyl7Mm3pIzPgKfpmPXFQ8CFVWyGi+4mkEaCK715ViOBDkU2pC2nAiPunLw7Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": ["Microsoft.Win32.SystemEvents"], "net7.0": ["Microsoft.Win32.SystemEvents"], "net8.0": ["Microsoft.Win32.SystemEvents"], "net9.0": ["Microsoft.Win32.SystemEvents"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Configuration.ConfigurationManager", "id": "System.Configuration.ConfigurationManager", "version": "8.0.0", "sha512": "sha512-WLn7WxNMGs8+pboojHpid8CJiNhcr2j7kA0gmI8fgU5LF0JGKGqHhSSHc8WW0h77svQSS29KO+hr+xKeuS2J9A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Security.Cryptography.ProtectedData"], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Security.Cryptography.ProtectedData"], "net6.0": ["System.Security.Cryptography.ProtectedData"], "net7.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net8.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net9.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Security.Cryptography.ProtectedData"], "netcoreapp2.1": ["System.Security.Cryptography.ProtectedData"], "netcoreapp2.2": ["System.Security.Cryptography.ProtectedData"], "netcoreapp3.0": ["System.Security.Cryptography.ProtectedData"], "netcoreapp3.1": ["System.Security.Cryptography.ProtectedData"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Security.Cryptography.ProtectedData"], "netstandard2.1": ["System.Security.Cryptography.ProtectedData"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Diagnostics.EventLog", "id": "System.Diagnostics.EventLog", "version": "8.0.0", "sha512": "sha512-um5/JzI6kqUKdoRX4qtIrMql36C6GQgspx2ntHO3HNO23QNuRC4Qn8Fe+7TCZ4gamEQJeuTt3Dy4hxUsjJURpQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.IO", "id": "System.IO", "version": "4.3.0", "sha512": "sha512-v8paIePhmGuXZbE9xvvNb4uJ5ME4OFXR1+8la/G/L1GIl2nbU2WFnddgb79kVK3U2us7q1aZT/uY/R0D/ovB5g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.IO.FileSystem", "id": "System.IO.FileSystem", "version": "4.3.0", "sha512": "sha512-T7WB1vhblSmgkaDpdGM3Uqo55Qsr5sip5eyowrwiXOoHBkzOx3ePd9+Zh97r9NzOwFCxqX7awO6RBxQuao7n7g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": ["System.IO.FileSystem.Primitives"], "net461": ["System.IO.FileSystem.Primitives"], "net462": ["System.IO.FileSystem.Primitives"], "net47": ["System.IO.FileSystem.Primitives"], "net471": ["System.IO.FileSystem.Primitives"], "net472": ["System.IO.FileSystem.Primitives"], "net48": ["System.IO.FileSystem.Primitives"], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.IO.FileSystem.Primitives", "id": "System.IO.FileSystem.Primitives", "version": "4.3.0", "sha512": "sha512-WIWVPQlYLP/Zc9I6IakpBk1y8ryVGK83MtZx//zGKKi2hvHQWKAB7moRQCOz5Is/wNDksiYpocf3FeA3le6e5Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Runtime"], "net6.0": ["System.Runtime"], "net7.0": ["System.Runtime"], "net8.0": ["System.Runtime"], "net9.0": ["System.Runtime"], "netcoreapp1.0": ["System.Runtime"], "netcoreapp1.1": ["System.Runtime"], "netcoreapp2.0": ["System.Runtime"], "netcoreapp2.1": ["System.Runtime"], "netcoreapp2.2": ["System.Runtime"], "netcoreapp3.0": ["System.Runtime"], "netcoreapp3.1": ["System.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["System.Runtime"], "netstandard1.4": ["System.Runtime"], "netstandard1.5": ["System.Runtime"], "netstandard1.6": ["System.Runtime"], "netstandard2.0": ["System.Runtime"], "netstandard2.1": ["System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.IO.Pipelines", "id": "System.IO.Pipelines", "version": "8.0.0", "sha512": "sha512-V+tqEehPQKSLV7HcV4agGqmFISK30VNjSQ2KEsmkWL+ZqN30wMAke+mFWcK0LnaaEL2ixamBdzVITZYNxlLrEg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.IO.Pipelines", "id": "System.IO.Pipelines", "version": "8.0.0", "sha512": "sha512-V+tqEehPQKSLV7HcV4agGqmFISK30VNjSQ2KEsmkWL+ZqN30wMAke+mFWcK0LnaaEL2ixamBdzVITZYNxlLrEg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net462": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net47": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net471": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net472": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net48": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net5.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Memory", "id": "System.Memory", "version": "4.5.5", "sha512": "sha512-6MjlNsl7lKw0Q8lAsw2tQ89ul9x6jD2Yk3EEj+dOFoYGOE9eAUO9wNhvd4O/n97oQXlkyzqKXXUnE+kLElFy3A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net451": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net452": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net46": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net461": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.1": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.2": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.3": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.4": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.5": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.6": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.0": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Net.Primitives", "id": "System.Net.Primitives", "version": "4.3.1", "sha512": "sha512-BgdlyYCI7rrdh36p3lMTqbkvaafPETpB1bk9iQlFdQxYE692kiXvmseXs8ghL+gEgQF2xgDc8GH4QLkSgUUs+Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Reflection.Metadata", "id": "System.Reflection.Metadata", "version": "8.0.0", "sha512": "sha512-+6sMdkJjee0B6nm3AlBBl7cQaI0oPniLvvkrkFhmEN3fo/hGONaFdwpAaO+GRTlbZe4kRZzFwU7kSXQW0RyJxg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable"], "net462": ["System.Collections.Immutable"], "net47": ["System.Collections.Immutable"], "net471": ["System.Collections.Immutable"], "net472": ["System.Collections.Immutable"], "net48": ["System.Collections.Immutable"], "net5.0": ["System.Collections.Immutable"], "net6.0": ["System.Collections.Immutable"], "net7.0": ["System.Collections.Immutable"], "net8.0": ["System.Collections.Immutable"], "net9.0": ["System.Collections.Immutable"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable"], "netcoreapp2.1": ["System.Collections.Immutable"], "netcoreapp2.2": ["System.Collections.Immutable"], "netcoreapp3.0": ["System.Collections.Immutable"], "netcoreapp3.1": ["System.Collections.Immutable"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable"], "netstandard2.1": ["System.Collections.Immutable"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Reflection.MetadataLoadContext", "id": "System.Reflection.MetadataLoadContext", "version": "7.0.0", "sha512": "sha512-dqk0PmO2SGulqNpuJlALPc/5vqFVZc6As4ToHeZvd+6B/DomA1/JM1nAOpSU2hkBVytU0GlwsBr4YfKSnGSchg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net462": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net47": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net471": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net472": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net48": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net5.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net6.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net7.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netstandard2.1": ["System.Collections.Immutable", "System.Reflection.Metadata"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Numerics.Vectors", "id": "System.Numerics.Vectors", "version": "4.5.0", "sha512": "sha512-nATsBTD2CKr4AYN6eRszhX4sptImWmBJwB/U6XKCWWfnCcrTBw8XSCm3QA9gjppkHTr8OkXUY21MR91D3QZXsw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Reflection.Metadata", "id": "System.Reflection.Metadata", "version": "8.0.0", "sha512": "sha512-+6sMdkJjee0B6nm3AlBBl7cQaI0oPniLvvkrkFhmEN3fo/hGONaFdwpAaO+GRTlbZe4kRZzFwU7kSXQW0RyJxg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Memory"], "net462": ["System.Collections.Immutable", "System.Memory"], "net47": ["System.Collections.Immutable", "System.Memory"], "net471": ["System.Collections.Immutable", "System.Memory"], "net472": ["System.Collections.Immutable", "System.Memory"], "net48": ["System.Collections.Immutable", "System.Memory"], "net5.0": ["System.Collections.Immutable", "System.Memory"], "net6.0": ["System.Collections.Immutable"], "net7.0": ["System.Collections.Immutable"], "net8.0": ["System.Collections.Immutable"], "net9.0": ["System.Collections.Immutable"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Memory"], "netstandard2.1": ["System.Collections.Immutable", "System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Reflection.MetadataLoadContext", "id": "System.Reflection.MetadataLoadContext", "version": "8.0.0", "sha512": "sha512-vfR5BfUXXy3amp5aDoOTwOt9BJ8CtplaAnEKHbeTbmMW1SJMrSdviTVVRNqDB0eB9o1j/26WD1VA8JGFfr8t+Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net462": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net47": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net471": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net472": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net48": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net5.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net6.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net7.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netstandard2.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Runtime", "id": "System.Runtime", "version": "4.3.1", "sha512": "sha512-Al69mPDfzdD+bKGK2HAfB+lNFOHFqnkqzNnUJmmvUe1/qEPK9M7EiTT4zuycKDPy7ev11xz8XVgJWKP0hm7NIA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Runtime.CompilerServices.Unsafe", "id": "System.Runtime.CompilerServices.Unsafe", "version": "6.0.0", "sha512": "sha512-1AVzAb5OxJNvJLnOADtexNmWgattm2XVOT3TjQTN7Dd4SqoSwai1CsN2fth42uQldJSQdz/sAec0+TzxBFgisw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Runtime.Handles", "id": "System.Runtime.Handles", "version": "4.3.0", "sha512": "sha512-CluvHdVUv54BvLTOCCyybugreDNk/rR8unMPruzXDtxSjvrQOU3M4R831/lQf4YI8VYp668FGQa/01E+Rq8PEQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Security.Cryptography.ProtectedData", "id": "System.Security.Cryptography.ProtectedData", "version": "7.0.0", "sha512": "sha512-a34SHiyaMcLRjw/1IGXokS2cH9j8XoOhs1jUYq3m+kQcnPp6fhmeuqe5U947WqojDsVMhWAsCE6rIg8grBv9BA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Security.Permissions", "id": "System.Security.Permissions", "version": "7.0.0", "sha512": "sha512-XNVTmQ9JuCRwRXRTDoOHEzEt0wmQeRudH9lThP0l3OBja4P3jmRHq/0H0N9Ns1OD6gNmKpjLdOeHCQEXv4iVrA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": ["System.Windows.Extensions"], "net7.0": ["System.Windows.Extensions"], "net8.0": ["System.Windows.Extensions"], "net9.0": ["System.Windows.Extensions"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Security.Cryptography.ProtectedData", "id": "System.Security.Cryptography.ProtectedData", "version": "8.0.0", "sha512": "sha512-hvcXZ/IR+KXxY9lC9S2izw5/fGYoODJR2r9kQSvs5v/HUAnBRuYYZPJrHzaT0CeDRJzIm8BHJb1ZrwHQ59j3uQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory"], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Memory"], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory"], "netcoreapp2.1": ["System.Memory"], "netcoreapp2.2": ["System.Memory"], "netcoreapp3.0": ["System.Memory"], "netcoreapp3.1": ["System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory"], "netstandard2.1": ["System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Security.Principal", "id": "System.Security.Principal", "version": "4.3.0", "sha512": "sha512-24oe0NGJY32e+DFHVQzl2okM9uwYmn0Aa6nehqtVZ55/Al4Yva7S3BN934Kn5qATH7TVTUJkgxhisdfF7mKDfg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Runtime"], "net6.0": ["System.Runtime"], "net7.0": ["System.Runtime"], "net8.0": ["System.Runtime"], "net9.0": ["System.Runtime"], "netcoreapp1.0": ["System.Runtime"], "netcoreapp1.1": ["System.Runtime"], "netcoreapp2.0": ["System.Runtime"], "netcoreapp2.1": ["System.Runtime"], "netcoreapp2.2": ["System.Runtime"], "netcoreapp3.0": ["System.Runtime"], "netcoreapp3.1": ["System.Runtime"], "netstandard": [], "netstandard1.0": ["System.Runtime"], "netstandard1.1": ["System.Runtime"], "netstandard1.2": ["System.Runtime"], "netstandard1.3": ["System.Runtime"], "netstandard1.4": ["System.Runtime"], "netstandard1.5": ["System.Runtime"], "netstandard1.6": ["System.Runtime"], "netstandard2.0": ["System.Runtime"], "netstandard2.1": ["System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Security.Principal.Windows", "id": "System.Security.Principal.Windows", "version": "5.0.0", "sha512": "sha512-RKkgqq8ishctQTGbtXqyuOGkUx1fAhkqb1OoHYdRJRlbYLoLWkSkWYHRN/17DzplsSlZtf2Xr8BXjNhO8nRnzQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": ["Microsoft.Win32.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Security.Principal", "System.Text.Encoding"], "netcoreapp1.1": ["Microsoft.Win32.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Security.Principal", "System.Text.Encoding"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["Microsoft.Win32.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Security.Principal", "System.Text.Encoding"], "netstandard1.4": ["Microsoft.Win32.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Security.Principal", "System.Text.Encoding"], "netstandard1.5": ["Microsoft.Win32.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Security.Principal", "System.Text.Encoding"], "netstandard1.6": ["Microsoft.Win32.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Security.Principal", "System.Text.Encoding"], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Text.Encoding", "id": "System.Text.Encoding", "version": "4.3.0", "sha512": "sha512-b/f+7HMTpxIfeV7H03bkuHKMFylCGfr9/U6gePnfFFW0aF8LOWLDgQCY6V1oWUqDksC3mdNuyChM1vy9TP4sZw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Threading.Channels", "id": "System.Threading.Channels", "version": "8.0.0", "sha512": "sha512-M1s365f1lOc6s2585/ATW+KRRFFnaI6JvSSdE14n9ZKgvWnZHoJGoccqV41XvtRDrHMCMRNlwWFgt9yXTu3xQQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Text.Encoding.CodePages", "id": "System.Text.Encoding.CodePages", "version": "7.0.0", "sha512": "sha512-SFq/rrH52sMHJJsthDdafWPEuxdRCRB7pZ46trR2xSpi1nfKPAbw6amZr9W/LyHTlqS01TRWO7najRuO1vxFig==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Runtime.CompilerServices.Unsafe"], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Threading.Channels", "id": "System.Threading.Channels", "version": "7.0.0", "sha512": "sha512-XXmpdJbyVCagWg3bGfUGNTxKp4EK/3C4Bt8pXhKVYZKwHPjeHPOg0u2wdqHFsojU4u4i9KByAJTyzqLCMqwpUg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Threading.Tasks.Extensions"], "net462": ["System.Threading.Tasks.Extensions"], "net47": ["System.Threading.Tasks.Extensions"], "net471": ["System.Threading.Tasks.Extensions"], "net472": ["System.Threading.Tasks.Extensions"], "net48": ["System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Threading.Tasks", "id": "System.Threading.Tasks", "version": "4.3.0", "sha512": "sha512-fUiP+CyyCjs872OA8trl6p97qma/da1xGq3h4zAbJZk8zyaU4zyEfqW5vbkP80xG/Nimun1vlWBboMEk7XxdEw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Threading.Tasks.Dataflow", "id": "System.Threading.Tasks.Dataflow", "version": "7.0.0", "sha512": "sha512-nB6cUBEEimO35tPK+KmhUF8jxxisO1E+8KU3eDIA9/o156qulMs8YeozOTcVRYHZWvgn1YCDI/ZR2ga9ErXIfg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Threading.Tasks.Extensions", "id": "System.Threading.Tasks.Extensions", "version": "4.5.4", "sha512": "sha512-aAUghud9PHGYc3o9oWPWd0C3xE+TJQw5ZZs78htlR6mr9ky/QEgfXHjyQ2GvOq9H1S0YizcVVKCSin92ZcH8FA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": ["System.Runtime.CompilerServices.Unsafe"], "net451": ["System.Runtime.CompilerServices.Unsafe"], "net452": ["System.Runtime.CompilerServices.Unsafe"], "net46": ["System.Runtime.CompilerServices.Unsafe"], "net461": ["System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netcoreapp1.1": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.1": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.2": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.3": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.4": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.5": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.6": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard2.0": ["System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Threading.ThreadPool", "id": "System.Threading.ThreadPool", "version": "4.3.0", "sha512": "sha512-RQpA+UpI6Tlpeedk5JStYk2DM/M3i5HqabI/yDbfj1xDu9bIz9kdoquVpHbh/wQjOJaOCbcgRH8iQcAUv8dRWQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Runtime", "System.Runtime.Handles"], "net6.0": ["System.Runtime", "System.Runtime.Handles"], "net7.0": ["System.Runtime", "System.Runtime.Handles"], "net8.0": ["System.Runtime", "System.Runtime.Handles"], "net9.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp1.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp1.1": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp2.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp2.1": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp2.2": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp3.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp3.1": ["System.Runtime", "System.Runtime.Handles"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["System.Runtime", "System.Runtime.Handles"], "netstandard1.4": ["System.Runtime", "System.Runtime.Handles"], "netstandard1.5": ["System.Runtime", "System.Runtime.Handles"], "netstandard1.6": ["System.Runtime", "System.Runtime.Handles"], "netstandard2.0": ["System.Runtime", "System.Runtime.Handles"], "netstandard2.1": ["System.Runtime", "System.Runtime.Handles"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Windows.Extensions", "id": "System.Windows.Extensions", "version": "7.0.0", "sha512": "sha512-KNnH0GX7T/oRAzOtJjefboYngi+d/bNGd63j+ZIFFTIR8RM0dwptuImNXiKqvD78kzcWAf3kd3yjcih+UTYkbw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": ["System.Drawing.Common"], "net7.0": ["System.Drawing.Common"], "net8.0": ["System.Drawing.Common"], "net9.0": ["System.Drawing.Common"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit", "id": "xunit", "version": "2.9.2", "sha512": "sha512-bs4ccplaqCT7+jdAJhtt75uKq9qA3Jeld1ugiOgGEGSnzq8gkoa0VUqNEKkMPkBwV5COlAllNJGtGBfgxoZDrA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net20": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net30": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net35": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net40": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net403": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net45": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net451": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net452": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net46": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net461": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net462": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net47": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net471": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net472": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net48": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net5.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net6.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net7.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net8.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net9.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp1.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp1.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp2.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp2.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp2.2": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp3.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp3.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.2": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.3": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.4": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.5": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.6": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard2.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard2.1": ["xunit.core", "xunit.assert", "xunit.analyzers"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit.abstractions", "id": "xunit.abstractions", "version": "2.0.3", "sha512": "sha512-PKJri5f0qEQPFvgY6CZR9XG8JROlWSdC/ZYLkkDQuID++Egn+yWjB+Yf57AZ8U6GRlP7z33uDQ4/r5BZPer2JA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit.analyzers", "id": "xunit.analyzers", "version": "1.16.0", "sha512": "sha512-65QLxnRoOqpAn2hMnjI1FLmQEjzUye2h4MwRVe1k151K+UFG1Ehr/s/MLwNJ6pCNoyoJjOoNuF7OGW4mH2bdaQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, From 4013eeba8b0319170b9a0bdbaf9334b37cf54399 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 11:37:03 +0100 Subject: [PATCH 094/213] C#: Use the newest version of packages instead of the minimum version. --- csharp/paket.dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/paket.dependencies b/csharp/paket.dependencies index 824e2d73a832..58829b5ec06f 100644 --- a/csharp/paket.dependencies +++ b/csharp/paket.dependencies @@ -2,7 +2,7 @@ framework: net9.0 storage: none source https://api.nuget.org/v3/index.json # behave like nuget in choosing transitive dependency versions -strategy: min +strategy: max nuget Basic.CompilerLog.Util nuget Mono.Posix.NETStandard From 347fb1cfd9b75384427d72f35b56866df7cc522d Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 11:37:21 +0100 Subject: [PATCH 095/213] C#: Update dependencies. --- csharp/paket.lock | 96 +++++++++++++++++++++---------------------- csharp/paket.main.bzl | 56 ++++++++++++------------- 2 files changed, 75 insertions(+), 77 deletions(-) diff --git a/csharp/paket.lock b/csharp/paket.lock index b80defd8c436..8bfc5b1650e4 100644 --- a/csharp/paket.lock +++ b/csharp/paket.lock @@ -1,5 +1,5 @@ STORAGE: NONE -STRATEGY: MIN +STRATEGY: MAX RESTRICTION: == net9.0 NUGET remote: https://api.nuget.org/v3/index.json @@ -12,11 +12,11 @@ NUGET MSBuild.StructuredLogger (>= 2.2.243) System.Buffers (>= 4.6) Humanizer.Core (2.14.1) - MessagePack (2.5.187) - MessagePack.Annotations (>= 2.5.187) + MessagePack (2.5.192) + MessagePack.Annotations (>= 2.5.192) Microsoft.NET.StringTools (>= 17.6.3) - MessagePack.Annotations (2.5.187) - Microsoft.Bcl.AsyncInterfaces (8.0) + MessagePack.Annotations (2.5.192) + Microsoft.Bcl.AsyncInterfaces (9.0) Microsoft.Build (17.12.6) Microsoft.Build.Framework (>= 17.12.6) Microsoft.NET.StringTools (>= 17.12.6) @@ -25,11 +25,11 @@ NUGET System.Reflection.Metadata (>= 8.0) System.Reflection.MetadataLoadContext (>= 8.0) Microsoft.Build.Framework (17.12.6) - Microsoft.Build.Utilities.Core (17.5) - Microsoft.Build.Framework (>= 17.5) - Microsoft.NET.StringTools (>= 17.5) - System.Collections.Immutable (>= 6.0) - System.Configuration.ConfigurationManager (>= 6.0) + Microsoft.Build.Utilities.Core (17.12.6) + Microsoft.Build.Framework (>= 17.12.6) + Microsoft.NET.StringTools (>= 17.12.6) + System.Collections.Immutable (>= 8.0) + System.Configuration.ConfigurationManager (>= 8.0) Microsoft.CodeAnalysis (4.12) Humanizer.Core (>= 2.14.1) Microsoft.Bcl.AsyncInterfaces (>= 8.0) @@ -47,7 +47,7 @@ NUGET System.Text.Encoding.CodePages (>= 7.0) System.Threading.Channels (>= 7.0) System.Threading.Tasks.Extensions (>= 4.5.4) - Microsoft.CodeAnalysis.Analyzers (3.3.4) + Microsoft.CodeAnalysis.Analyzers (3.11) Microsoft.CodeAnalysis.Common (4.12) Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) System.Collections.Immutable (>= 8.0) @@ -99,8 +99,8 @@ NUGET Microsoft.NET.Test.Sdk (17.12) Microsoft.CodeCoverage (>= 17.12) Microsoft.TestPlatform.TestHost (>= 17.12) - Microsoft.NETCore.Platforms (1.1.1) - Microsoft.NETCore.Targets (1.1.3) + Microsoft.NETCore.Platforms (7.0.4) + Microsoft.NETCore.Targets (5.0) Microsoft.TestPlatform.ObjectModel (17.12) System.Reflection.Metadata (>= 1.6) Microsoft.TestPlatform.TestHost (17.12) @@ -111,32 +111,33 @@ NUGET Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) Mono.Posix.NETStandard (1.0) - MSBuild.StructuredLogger (2.2.243) + MSBuild.StructuredLogger (2.2.386) Microsoft.Build.Framework (>= 17.5) Microsoft.Build.Utilities.Core (>= 17.5) + System.Collections.Immutable (>= 8.0) Newtonsoft.Json (13.0.3) System.Buffers (4.6) - System.Collections.Immutable (8.0) - System.Composition (8.0) - System.Composition.AttributedModel (>= 8.0) - System.Composition.Convention (>= 8.0) - System.Composition.Hosting (>= 8.0) - System.Composition.Runtime (>= 8.0) - System.Composition.TypedParts (>= 8.0) - System.Composition.AttributedModel (8.0) - System.Composition.Convention (8.0) - System.Composition.AttributedModel (>= 8.0) - System.Composition.Hosting (8.0) - System.Composition.Runtime (>= 8.0) - System.Composition.Runtime (8.0) - System.Composition.TypedParts (8.0) - System.Composition.AttributedModel (>= 8.0) - System.Composition.Hosting (>= 8.0) - System.Composition.Runtime (>= 8.0) - System.Configuration.ConfigurationManager (8.0) - System.Diagnostics.EventLog (>= 8.0) - System.Security.Cryptography.ProtectedData (>= 8.0) - System.Diagnostics.EventLog (8.0) + System.Collections.Immutable (9.0) + System.Composition (9.0) + System.Composition.AttributedModel (>= 9.0) + System.Composition.Convention (>= 9.0) + System.Composition.Hosting (>= 9.0) + System.Composition.Runtime (>= 9.0) + System.Composition.TypedParts (>= 9.0) + System.Composition.AttributedModel (9.0) + System.Composition.Convention (9.0) + System.Composition.AttributedModel (>= 9.0) + System.Composition.Hosting (9.0) + System.Composition.Runtime (>= 9.0) + System.Composition.Runtime (9.0) + System.Composition.TypedParts (9.0) + System.Composition.AttributedModel (>= 9.0) + System.Composition.Hosting (>= 9.0) + System.Composition.Runtime (>= 9.0) + System.Configuration.ConfigurationManager (9.0) + System.Diagnostics.EventLog (>= 9.0) + System.Security.Cryptography.ProtectedData (>= 9.0) + System.Diagnostics.EventLog (9.0) System.IO (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -154,41 +155,38 @@ NUGET System.Threading.Tasks (>= 4.3) System.IO.FileSystem.Primitives (4.3) System.Runtime (>= 4.3) - System.IO.Pipelines (8.0) - System.Memory (4.5.5) + System.IO.Pipelines (9.0) + System.Memory (4.6) System.Net.Primitives (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) System.Runtime (>= 4.3.1) System.Runtime.Handles (>= 4.3) - System.Numerics.Vectors (4.5) - System.Reflection.Metadata (8.0) - System.Collections.Immutable (>= 8.0) - System.Reflection.MetadataLoadContext (8.0) - System.Collections.Immutable (>= 8.0) - System.Reflection.Metadata (>= 8.0) + System.Numerics.Vectors (4.6) + System.Reflection.Metadata (9.0) + System.Reflection.MetadataLoadContext (9.0) System.Runtime (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime.CompilerServices.Unsafe (6.0) + System.Runtime.CompilerServices.Unsafe (6.1) System.Runtime.Handles (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Security.Cryptography.ProtectedData (8.0) + System.Security.Cryptography.ProtectedData (9.0) System.Security.Principal (4.3) System.Runtime (>= 4.3) System.Text.Encoding (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Text.Encoding.CodePages (7.0) - System.Threading.Channels (7.0) + System.Text.Encoding.CodePages (9.0) + System.Threading.Channels (9.0) System.Threading.Tasks (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Threading.Tasks.Extensions (4.5.4) + System.Threading.Tasks.Extensions (4.6) System.Threading.ThreadPool (4.3) System.Runtime (>= 4.3) System.Runtime.Handles (>= 4.3) @@ -197,7 +195,7 @@ NUGET xunit.assert (>= 2.9.2) xunit.core (2.9.2) xunit.abstractions (2.0.3) - xunit.analyzers (1.16) + xunit.analyzers (1.17) xunit.assert (2.9.2) xunit.core (2.9.2) xunit.extensibility.core (2.9.2) diff --git a/csharp/paket.main.bzl b/csharp/paket.main.bzl index 413bf68ddf3f..fa79062ab441 100644 --- a/csharp/paket.main.bzl +++ b/csharp/paket.main.bzl @@ -9,14 +9,14 @@ def main(): packages = [ {"name": "Basic.CompilerLog.Util", "id": "Basic.CompilerLog.Util", "version": "0.9.3", "sha512": "sha512-hgu/4KttHz9bXOISmomz1uO4WidkXqBbSu4MjVgj3SeJ/bH4t+nkZ5qybpqpZJHf04hdXlyt/ux0OWv5/xEKRQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net462": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net47": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net471": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net472": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net48": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net5.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net6.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net7.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net8.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net9.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.2": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Humanizer.Core", "id": "Humanizer.Core", "version": "2.14.1", "sha512": "sha512-yzqGU/HKNLZ9Uvr6kvSc3wYV/S5O/IvklIUW5WF7MuivGLY8wS5IZnLPkt7D1KW8Et2Enl0I3Lzg2vGWM24Xsw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MessagePack", "id": "MessagePack", "version": "2.5.187", "sha512": "sha512-gZ6QLyipngHr+n/XWWm7TM26j9vkM6+B6RXBuv+ia/DjJsG6pJaQbVuz/+RBFJrSd98eTk+CqHwrE1DtFyR1bw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net7.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net8.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "2.5.187", "sha512": "sha512-1IThHnbMw6Ah9Mb/bZfWEwZDo3ZbsU9usGAOeCs/oPWsklrdxVDNZHjIg6myvjlQvL7oMhagEeb+07kjL410aQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.Bcl.AsyncInterfaces", "id": "Microsoft.Bcl.AsyncInterfaces", "version": "8.0.0", "sha512": "sha512-ecsHc9lEZZJM7k5HHZA1PV2N+ELEarLFcssV2bn7XQIJoaiNZDkplTNcX+VKANfDGURAuEyVFCcRu7aFy16VUg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Threading.Tasks.Extensions"], "net462": ["System.Threading.Tasks.Extensions"], "net47": ["System.Threading.Tasks.Extensions"], "net471": ["System.Threading.Tasks.Extensions"], "net472": ["System.Threading.Tasks.Extensions"], "net48": ["System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MessagePack", "id": "MessagePack", "version": "2.5.192", "sha512": "sha512-SnrwSQIKWfxcQvzE1TCUPvJ7A/44KFBDcmCc+YUDIq8QalCf0bGAjiBoAFewhJ81QuS5FsCNCOcKn+IURYlbAQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net7.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net8.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "2.5.192", "sha512": "sha512-pE/SD2N0+nDAU8BtTHqjyIhLM2L5Mb0NiO4hW0ybiv2I+BbK0JEaGtbKpeEmOvKT+5s2hds0gvk/GrAHhgcpdw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.Bcl.AsyncInterfaces", "id": "Microsoft.Bcl.AsyncInterfaces", "version": "9.0.0", "sha512": "sha512-bYp2ksSR5uB6xqOa4NyD2gBOeFrc2n8FAWoh781MNMDcPjk1ysD7DNpv7r7sQOXfdFJT6F/syX7fN4lmUsn+RQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Threading.Tasks.Extensions"], "net462": ["System.Threading.Tasks.Extensions"], "net47": ["System.Threading.Tasks.Extensions"], "net471": ["System.Threading.Tasks.Extensions"], "net472": ["System.Threading.Tasks.Extensions"], "net48": ["System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.Build", "id": "Microsoft.Build", "version": "17.12.6", "sha512": "sha512-YEiL5xKowbwnr52YroALNHg8YurjLyFTlhv3USrswhubuxN2ldY1TmQpBKQ4K28UgWJV9BxTVXY9/CecMNDeOA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.Build.Framework", "id": "Microsoft.Build.Framework", "version": "17.12.6", "sha512": "sha512-UjfxnrQN9BPVtO0Kvv2FB5dpN2CX5snc7coq5vVQdbCV6kdSpI/r+GZTLvU/5BTT8y8bvIUqoocxRR674N6bWg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.Build.Utilities.Core", "id": "Microsoft.Build.Utilities.Core", "version": "17.5.0", "sha512": "sha512-La1NFQ7SVz1pVGEUnG15BQG26jJkRMCiitySBXLhuTYf9IG6eZ5j5UFjnM4EFKSVKbictRv+D/F0dQtsCiK9ag==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net462": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net47": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net471": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.Build.Utilities.Core", "id": "Microsoft.Build.Utilities.Core", "version": "17.12.6", "sha512": "sha512-YPtNsiLEPn3g3EcO+Kyr7fIdufg6wdzibzufclQYZjIDS80krFsYi2rTpeTmHtlCK0PhyLvxJAQZ3NecgJHTkg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Text.Encoding.CodePages", "System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.CodeAnalysis", "id": "Microsoft.CodeAnalysis", "version": "4.12.0", "sha512": "sha512-saGSG86irNb5MX0/7j0Lx2T0jSGQuqa6QlohBHBcTzObPyMunQZIuIWVXlEiKwcrcEQm4rtUg/5FW43s0dqH7Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net9.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.CodeAnalysis.Analyzers", "id": "Microsoft.CodeAnalysis.Analyzers", "version": "3.3.4", "sha512": "sha512-I+Riw6/6WjNICydoiNpDjN/GGP7u4XsL6VsI9lG/OjFufH3flvSEy/fxNhGDVGwZWwq/5BlnqX+LH2dmheaPfg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.CodeAnalysis.Analyzers", "id": "Microsoft.CodeAnalysis.Analyzers", "version": "3.11.0", "sha512": "sha512-tP9SLzLK72XCExlh8KXfrKbU6ycmZL3ExGl/a3Ml7LNy2Uaam7gFjjUmdzyTYkMXTyckCHHpzx7bD6BMumh8Bg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.CodeAnalysis.Common", "id": "Microsoft.CodeAnalysis.Common", "version": "4.12.0", "sha512": "sha512-83sYPF0SekVhecApCFXsLCsQL9qFzAl5ieCEqVb8Uo08nV34YD3cfq7FLv6EkhnAwPbP7ky19sAEEqYLDUrxWA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net462": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net47": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net471": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net472": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net48": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net5.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net6.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net7.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.CodeAnalysis.CSharp", "id": "Microsoft.CodeAnalysis.CSharp", "version": "4.12.0", "sha512": "sha512-Dbb/taxFill9/+2HRJufXW3udAtJaQw3+LzbWTDyYx7Z02HVdU5ydMXXTqg5lFgSmLDNBe+B8jRuI2eYw8OBOA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.CodeAnalysis.CSharp.Workspaces", "id": "Microsoft.CodeAnalysis.CSharp.Workspaces", "version": "4.12.0", "sha512": "sha512-YwFqDAYHJrf02FyGU8nQnaWNryZXuDV0r8pVgWjRtxAFDWfaU5CZxvU/4NsS6GSnEsWp6W/e49QMHsDXTJW/KA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata", "System.Threading.Channels"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, @@ -27,47 +27,47 @@ def main(): {"name": "Microsoft.Extensions.ObjectPool", "id": "Microsoft.Extensions.ObjectPool", "version": "9.0.0", "sha512": "sha512-dY64S9XmssfAjwvuGMHleFj2cKIhIFUU2D+Kr1D1Y+92mAPN/39HQMJay2FHxSRcDEI9hATivRV/I1N7QxVJcQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.NET.StringTools", "id": "Microsoft.NET.StringTools", "version": "17.12.6", "sha512": "sha512-uCT/G0W1wUteqfrriWHfLfFmArka8ISo6nUkC5gQzYZYm2PSTuqfS14DEsY0gqDuQpcLLLaYTDcEM0SA2Za5vA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.NET.Test.Sdk", "id": "Microsoft.NET.Test.Sdk", "version": "17.12.0", "sha512": "sha512-hGf8I8+yo15etavoMd+7OXcOG6/G7HYPDEJg5aQnhMzsxaUpq+udNZzSxmEN9rGTWMZOAVFcyNXNL7YBsN6chw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": ["Microsoft.CodeCoverage"], "net47": ["Microsoft.CodeCoverage"], "net471": ["Microsoft.CodeCoverage"], "net472": ["Microsoft.CodeCoverage"], "net48": ["Microsoft.CodeCoverage"], "net5.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net6.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net7.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net8.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net9.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.NETCore.Platforms", "id": "Microsoft.NETCore.Platforms", "version": "1.1.1", "sha512": "sha512-mDUJD1eLXIzmUnWCzWlmNQZGDp/cVGT8KyhzMcJNk2nlfdFUOoZai9idT8/FacJr8Nv8zhAmdf39FHm5qWUoGQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "Microsoft.NETCore.Targets", "id": "Microsoft.NETCore.Targets", "version": "1.1.3", "sha512": "sha512-pxwq8g2PYRiEF5KXVjmZFMNTqsg2Gr1puv/pR1sqAduAKHAGbaCuJ6+yc3pAJseClQUD29S2Ubrm7n/ZD78dUg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.NETCore.Platforms", "id": "Microsoft.NETCore.Platforms", "version": "7.0.4", "sha512": "sha512-mcQWjuDBh4WHGG4WcBI0k025WAdA2afMm6fs42sm1f+3gRyNQUiuMVT5gAWNUGSHmlu6qn/TCnAQpfl4Gm6cBw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Microsoft.NETCore.Targets", "id": "Microsoft.NETCore.Targets", "version": "5.0.0", "sha512": "sha512-hYHm3JAjQO/nySxcl1EpZhYEW+2P3H1eLZNr+QxgO5TnLS6hqtfi5WchjQzjid45MYmhy2X7IOmcWtDP4fpMGw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.TestPlatform.ObjectModel", "id": "Microsoft.TestPlatform.ObjectModel", "version": "17.12.0", "sha512": "sha512-klsXMgAPNWYo3ceakLkod4wYrk4lAV2Ehi676zUKgiVpQ5Yj6q3vsMhk/3pm97Ltk/hdcSW0rJKJvcQvTzPgYA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Reflection.Metadata"], "net462": ["System.Reflection.Metadata"], "net47": ["System.Reflection.Metadata"], "net471": ["System.Reflection.Metadata"], "net472": ["System.Reflection.Metadata"], "net48": ["System.Reflection.Metadata"], "net5.0": ["System.Reflection.Metadata"], "net6.0": ["System.Reflection.Metadata"], "net7.0": ["System.Reflection.Metadata"], "net8.0": ["System.Reflection.Metadata"], "net9.0": ["System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Reflection.Metadata"], "netcoreapp2.1": ["System.Reflection.Metadata"], "netcoreapp2.2": ["System.Reflection.Metadata"], "netcoreapp3.0": ["System.Reflection.Metadata"], "netcoreapp3.1": ["System.Reflection.Metadata"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Reflection.Metadata"], "netstandard2.1": ["System.Reflection.Metadata"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.TestPlatform.TestHost", "id": "Microsoft.TestPlatform.TestHost", "version": "17.12.0", "sha512": "sha512-gYM2BOGQvFEP2fZt61f3f5Gu+imL1G1bvGUrbJjpYcl66R6uzs5yESg0XMn8IgUgldz8RldOOaYmjk2KcSeG1Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net6.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net7.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net8.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net9.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.Win32.Primitives", "id": "Microsoft.Win32.Primitives", "version": "4.3.0", "sha512": "sha512-Nm8Hp51y9tYcK3xD6qk43Wjftrg1mdH24CCJsTb6gr7HS21U1uA+CKPGEtUcVZbjU1y8Kynzm5eoJ7Pnx5gm8A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Mono.Posix.NETStandard", "id": "Mono.Posix.NETStandard", "version": "1.0.0", "sha512": "sha512-RtGiutQZJAmajvQ0QvBvh73VJye85iW9f9tjZlzF88idLxNMo4lAktP/4Y9ilCpais0LDO0tpoICt9Hdv6wooA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MSBuild.StructuredLogger", "id": "MSBuild.StructuredLogger", "version": "2.2.243", "sha512": "sha512-Egw6dLclkDtfoVK+ncghRfYDEWiHjjmhbJFdqeZfqL/Ddtg+JoHzSMblBBTrn317coXZ7WMDELW3C9ZCpn0ByQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net462": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net47": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net471": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net472": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net48": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MSBuild.StructuredLogger", "id": "MSBuild.StructuredLogger", "version": "2.2.386", "sha512": "sha512-m8ErawcbeDJ+nWtN62vh2OPHARvLpSqhOBCedtYniPGB059wSs2vuGPxfBcVGqVcjpZgntEY4vDOzGyAVB7atA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Newtonsoft.Json", "id": "Newtonsoft.Json", "version": "13.0.3", "sha512": "sha512-mbJSvHfRxfX3tR/U6n1WU+mWHXswYc+SB/hkOpx8yZZe68hNZGfymJu0cjsaJEkVzCMqePiU6LdIyogqfIn7kg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Buffers", "id": "System.Buffers", "version": "4.6.0", "sha512": "sha512-iRbJyTSX9bJVpURLGLiW8Fgk5Vfm5iGCztw4IG4IJYcxJy+BXTCEgEWFeJtO6c+kPnUmQu87KK5m188+qbErcQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Collections.Immutable", "id": "System.Collections.Immutable", "version": "8.0.0", "sha512": "sha512-BXqVkcIrhimvvem6q2ChWkuW6XYYirvb6FlhvuwaMoBqBdpcr4nehJBKP65Tw40UqcUM6oDoODsecM0yjZ6AUw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Runtime.CompilerServices.Unsafe"], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Composition", "id": "System.Composition", "version": "8.0.0", "sha512": "sha512-/AZ/S+sX6awiSeSvOv7997aiwbU6HCcOBJDLecdYQJjDo+4nYCrWwWKQQIZ38VZ6BLh1pDmcYFPZockIuoRIYw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net462": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net47": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net471": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net472": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net48": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net5.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net6.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net7.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net8.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net9.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp2.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp2.2": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp3.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp3.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netstandard2.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Composition.AttributedModel", "id": "System.Composition.AttributedModel", "version": "8.0.0", "sha512": "sha512-gmEwpwXz+COPtuAASK+ichAg8+0oQAaPOV59g6fDdnt1KWbrymdixAn06bNbkdCUGcBXb8RX5k79cqg0Hqlv1g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Composition.Convention", "id": "System.Composition.Convention", "version": "8.0.0", "sha512": "sha512-MP7qMadQGUcMOEyGON5dmy9T+OXubvIx04kFHvTVPfZ/9+ns8dqmFToxoF7IDzJVSWmtOQHDUP2fL1x8F6slTA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel"], "net462": ["System.Composition.AttributedModel"], "net47": ["System.Composition.AttributedModel"], "net471": ["System.Composition.AttributedModel"], "net472": ["System.Composition.AttributedModel"], "net48": ["System.Composition.AttributedModel"], "net5.0": ["System.Composition.AttributedModel"], "net6.0": ["System.Composition.AttributedModel"], "net7.0": ["System.Composition.AttributedModel"], "net8.0": ["System.Composition.AttributedModel"], "net9.0": ["System.Composition.AttributedModel"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel"], "netcoreapp2.1": ["System.Composition.AttributedModel"], "netcoreapp2.2": ["System.Composition.AttributedModel"], "netcoreapp3.0": ["System.Composition.AttributedModel"], "netcoreapp3.1": ["System.Composition.AttributedModel"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel"], "netstandard2.1": ["System.Composition.AttributedModel"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Composition.Hosting", "id": "System.Composition.Hosting", "version": "8.0.0", "sha512": "sha512-HK6mWN38TLXo0jQOzR6so8cH1J8/6MzCfSsQS15bWbFEYKeonKRAZKyTC2E92o+wB1KCkocNpOy01ix61JnWjQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.Runtime"], "net462": ["System.Composition.Runtime"], "net47": ["System.Composition.Runtime"], "net471": ["System.Composition.Runtime"], "net472": ["System.Composition.Runtime"], "net48": ["System.Composition.Runtime"], "net5.0": ["System.Composition.Runtime"], "net6.0": ["System.Composition.Runtime"], "net7.0": ["System.Composition.Runtime"], "net8.0": ["System.Composition.Runtime"], "net9.0": ["System.Composition.Runtime"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.Runtime"], "netcoreapp2.1": ["System.Composition.Runtime"], "netcoreapp2.2": ["System.Composition.Runtime"], "netcoreapp3.0": ["System.Composition.Runtime"], "netcoreapp3.1": ["System.Composition.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.Runtime"], "netstandard2.1": ["System.Composition.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Composition.Runtime", "id": "System.Composition.Runtime", "version": "8.0.0", "sha512": "sha512-hgGA3KDIx9FN3WYkpMvy0pUqWAul9BTehmqq49dqPxu5E+MbUKqgksU5XRP8M9LoBPZFa8FqBbKeFgCZ3rja2w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Composition.TypedParts", "id": "System.Composition.TypedParts", "version": "8.0.0", "sha512": "sha512-rKu0GdZ4JYOWUF7br1W7UQFI/UgzWTU03CHY6tnTLZXCMth6YSADGJRRQYrLzpwh2+NuNcBIuv7a7x8J1xsfdw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net462": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net47": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net471": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net472": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net48": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net5.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net6.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net7.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net8.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net9.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp2.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp2.2": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp3.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp3.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netstandard2.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Configuration.ConfigurationManager", "id": "System.Configuration.ConfigurationManager", "version": "8.0.0", "sha512": "sha512-WLn7WxNMGs8+pboojHpid8CJiNhcr2j7kA0gmI8fgU5LF0JGKGqHhSSHc8WW0h77svQSS29KO+hr+xKeuS2J9A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Security.Cryptography.ProtectedData"], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Security.Cryptography.ProtectedData"], "net6.0": ["System.Security.Cryptography.ProtectedData"], "net7.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net8.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net9.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Security.Cryptography.ProtectedData"], "netcoreapp2.1": ["System.Security.Cryptography.ProtectedData"], "netcoreapp2.2": ["System.Security.Cryptography.ProtectedData"], "netcoreapp3.0": ["System.Security.Cryptography.ProtectedData"], "netcoreapp3.1": ["System.Security.Cryptography.ProtectedData"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Security.Cryptography.ProtectedData"], "netstandard2.1": ["System.Security.Cryptography.ProtectedData"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Diagnostics.EventLog", "id": "System.Diagnostics.EventLog", "version": "8.0.0", "sha512": "sha512-um5/JzI6kqUKdoRX4qtIrMql36C6GQgspx2ntHO3HNO23QNuRC4Qn8Fe+7TCZ4gamEQJeuTt3Dy4hxUsjJURpQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Collections.Immutable", "id": "System.Collections.Immutable", "version": "9.0.0", "sha512": "sha512-z/Oo7nxWmZ0Y578vj8EUVrFJZ3DX6OMuUGlgeYgeeUZOFGT89XfaM8fDFMvJy6+mOIqW6ux5NdNzEnlTnQGJ7A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Composition", "id": "System.Composition", "version": "9.0.0", "sha512": "sha512-aWcyK90nIChHyxq7rpQ83Bbvt/t9l1X6yQtkvODaZ+rJlYHUMVpSji0YXIZTX5VlcWRCVRFdeEY767BCOzueaw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net462": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net47": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net471": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net472": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net48": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net5.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net6.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net7.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net8.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "net9.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp2.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp2.2": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp3.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netcoreapp3.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"], "netstandard2.1": ["System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Hosting", "System.Composition.Runtime", "System.Composition.TypedParts"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Composition.AttributedModel", "id": "System.Composition.AttributedModel", "version": "9.0.0", "sha512": "sha512-oYuQzlIvO31GxSlTo6NCU+RnK9dVb1m154BNE7VGm9PUyJM+RrOQss8cNbMj+iIWVcp6VRnyJlBJ3MfzYo14AA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Composition.Convention", "id": "System.Composition.Convention", "version": "9.0.0", "sha512": "sha512-3efhxn/7hQI9kNy6M6UUwWrMJCzdBZZ4hkYS3MUxqXyGdQ2sLCWToX1nLnnrRYafcdRSMOY2naMPNlRAEKDAGA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel"], "net462": ["System.Composition.AttributedModel"], "net47": ["System.Composition.AttributedModel"], "net471": ["System.Composition.AttributedModel"], "net472": ["System.Composition.AttributedModel"], "net48": ["System.Composition.AttributedModel"], "net5.0": ["System.Composition.AttributedModel"], "net6.0": ["System.Composition.AttributedModel"], "net7.0": ["System.Composition.AttributedModel"], "net8.0": ["System.Composition.AttributedModel"], "net9.0": ["System.Composition.AttributedModel"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel"], "netcoreapp2.1": ["System.Composition.AttributedModel"], "netcoreapp2.2": ["System.Composition.AttributedModel"], "netcoreapp3.0": ["System.Composition.AttributedModel"], "netcoreapp3.1": ["System.Composition.AttributedModel"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel"], "netstandard2.1": ["System.Composition.AttributedModel"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Composition.Hosting", "id": "System.Composition.Hosting", "version": "9.0.0", "sha512": "sha512-zLPGbMYw6y2GoNBjcoPnvXt7wSJM/qIG1fU2Do8kDObDTYWHG6fFOhulSViX0Ip2j+qGeuCESqEswCRG+xDvwA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.Runtime"], "net462": ["System.Composition.Runtime"], "net47": ["System.Composition.Runtime"], "net471": ["System.Composition.Runtime"], "net472": ["System.Composition.Runtime"], "net48": ["System.Composition.Runtime"], "net5.0": ["System.Composition.Runtime"], "net6.0": ["System.Composition.Runtime"], "net7.0": ["System.Composition.Runtime"], "net8.0": ["System.Composition.Runtime"], "net9.0": ["System.Composition.Runtime"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.Runtime"], "netcoreapp2.1": ["System.Composition.Runtime"], "netcoreapp2.2": ["System.Composition.Runtime"], "netcoreapp3.0": ["System.Composition.Runtime"], "netcoreapp3.1": ["System.Composition.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.Runtime"], "netstandard2.1": ["System.Composition.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Composition.Runtime", "id": "System.Composition.Runtime", "version": "9.0.0", "sha512": "sha512-P777aBPIwmLvL0Q8mPA7RiiomfjqLTbpX/xzKpk7YTJLcvPDMTvRIfNFognEpfJYRLadBymaBIU81vW3MzZYnA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Composition.TypedParts", "id": "System.Composition.TypedParts", "version": "9.0.0", "sha512": "sha512-7b7mkn4H0149jNKD1tZRUG2gmkszNzO6YAGV+xEsxdfIU+5SLhxWRYJpqm1zKzKNdzpKUW93oyEFGcTuoNvqGg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net462": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net47": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net471": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net472": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net48": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net5.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net6.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net7.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net8.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "net9.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp2.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp2.2": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp3.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netcoreapp3.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"], "netstandard2.1": ["System.Composition.AttributedModel", "System.Composition.Hosting", "System.Composition.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Configuration.ConfigurationManager", "id": "System.Configuration.ConfigurationManager", "version": "9.0.0", "sha512": "sha512-RMASWXcds+sKAl/W6itFM8hvq9aha8CRqSv2nrjb8TUTSMLjjn80h1Lrob7km+v/1UfpUU/Nr67egAjZjsCgIw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Security.Cryptography.ProtectedData"], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Security.Cryptography.ProtectedData"], "net6.0": ["System.Security.Cryptography.ProtectedData"], "net7.0": ["System.Security.Cryptography.ProtectedData"], "net8.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net9.0": ["System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Security.Cryptography.ProtectedData"], "netcoreapp2.1": ["System.Security.Cryptography.ProtectedData"], "netcoreapp2.2": ["System.Security.Cryptography.ProtectedData"], "netcoreapp3.0": ["System.Security.Cryptography.ProtectedData"], "netcoreapp3.1": ["System.Security.Cryptography.ProtectedData"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Security.Cryptography.ProtectedData"], "netstandard2.1": ["System.Security.Cryptography.ProtectedData"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Diagnostics.EventLog", "id": "System.Diagnostics.EventLog", "version": "9.0.0", "sha512": "sha512-ouyDUtZFOgkAPYmYUzioIjMxmgdI/E3j1sIuAbkXv4cTFOisf5FvQrbwi0KC84GUJMjkImXbaZqlTH9M5dJz2Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.IO", "id": "System.IO", "version": "4.3.0", "sha512": "sha512-v8paIePhmGuXZbE9xvvNb4uJ5ME4OFXR1+8la/G/L1GIl2nbU2WFnddgb79kVK3U2us7q1aZT/uY/R0D/ovB5g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Text.Encoding", "System.Threading.Tasks"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.IO.FileSystem", "id": "System.IO.FileSystem", "version": "4.3.0", "sha512": "sha512-T7WB1vhblSmgkaDpdGM3Uqo55Qsr5sip5eyowrwiXOoHBkzOx3ePd9+Zh97r9NzOwFCxqX7awO6RBxQuao7n7g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": ["System.IO.FileSystem.Primitives"], "net461": ["System.IO.FileSystem.Primitives"], "net462": ["System.IO.FileSystem.Primitives"], "net47": ["System.IO.FileSystem.Primitives"], "net471": ["System.IO.FileSystem.Primitives"], "net472": ["System.IO.FileSystem.Primitives"], "net48": ["System.IO.FileSystem.Primitives"], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.IO", "System.IO.FileSystem.Primitives", "System.Runtime", "System.Runtime.Handles", "System.Text.Encoding", "System.Threading.Tasks"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.IO.FileSystem.Primitives", "id": "System.IO.FileSystem.Primitives", "version": "4.3.0", "sha512": "sha512-WIWVPQlYLP/Zc9I6IakpBk1y8ryVGK83MtZx//zGKKi2hvHQWKAB7moRQCOz5Is/wNDksiYpocf3FeA3le6e5Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Runtime"], "net6.0": ["System.Runtime"], "net7.0": ["System.Runtime"], "net8.0": ["System.Runtime"], "net9.0": ["System.Runtime"], "netcoreapp1.0": ["System.Runtime"], "netcoreapp1.1": ["System.Runtime"], "netcoreapp2.0": ["System.Runtime"], "netcoreapp2.1": ["System.Runtime"], "netcoreapp2.2": ["System.Runtime"], "netcoreapp3.0": ["System.Runtime"], "netcoreapp3.1": ["System.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["System.Runtime"], "netstandard1.4": ["System.Runtime"], "netstandard1.5": ["System.Runtime"], "netstandard1.6": ["System.Runtime"], "netstandard2.0": ["System.Runtime"], "netstandard2.1": ["System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.IO.Pipelines", "id": "System.IO.Pipelines", "version": "8.0.0", "sha512": "sha512-V+tqEehPQKSLV7HcV4agGqmFISK30VNjSQ2KEsmkWL+ZqN30wMAke+mFWcK0LnaaEL2ixamBdzVITZYNxlLrEg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net462": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net47": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net471": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net472": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net48": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net5.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Memory", "id": "System.Memory", "version": "4.5.5", "sha512": "sha512-6MjlNsl7lKw0Q8lAsw2tQ89ul9x6jD2Yk3EEj+dOFoYGOE9eAUO9wNhvd4O/n97oQXlkyzqKXXUnE+kLElFy3A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net451": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net452": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net46": ["System.Buffers", "System.Runtime.CompilerServices.Unsafe"], "net461": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.1": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.2": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.3": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.4": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.5": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard1.6": ["System.Buffers", "System.Runtime", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.0": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.IO.Pipelines", "id": "System.IO.Pipelines", "version": "9.0.0", "sha512": "sha512-XIeVKR80wuDl05DI4Hufye7TT4D1Ca1Bm4zJPc7mgnodrCy0OfcQ1C00A7se56dMvg48cI64TMD+YKcZl+qOaA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net462": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net47": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net471": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net472": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net48": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net5.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net6.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net7.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["System.Buffers", "System.Memory", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Memory", "id": "System.Memory", "version": "4.6.0", "sha512": "sha512-TY7NpV4Vv0vwanZ6J8vrLGfybbPKhAvL3oTx7EndsZ/J/71sm01JPCHImtvYtwh1vmFat/GPS/id9htqIPK+6g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Buffers", "System.Numerics.Vectors", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Net.Primitives", "id": "System.Net.Primitives", "version": "4.3.1", "sha512": "sha512-BgdlyYCI7rrdh36p3lMTqbkvaafPETpB1bk9iQlFdQxYE692kiXvmseXs8ghL+gEgQF2xgDc8GH4QLkSgUUs+Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime", "System.Runtime.Handles"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Numerics.Vectors", "id": "System.Numerics.Vectors", "version": "4.5.0", "sha512": "sha512-nATsBTD2CKr4AYN6eRszhX4sptImWmBJwB/U6XKCWWfnCcrTBw8XSCm3QA9gjppkHTr8OkXUY21MR91D3QZXsw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Reflection.Metadata", "id": "System.Reflection.Metadata", "version": "8.0.0", "sha512": "sha512-+6sMdkJjee0B6nm3AlBBl7cQaI0oPniLvvkrkFhmEN3fo/hGONaFdwpAaO+GRTlbZe4kRZzFwU7kSXQW0RyJxg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Memory"], "net462": ["System.Collections.Immutable", "System.Memory"], "net47": ["System.Collections.Immutable", "System.Memory"], "net471": ["System.Collections.Immutable", "System.Memory"], "net472": ["System.Collections.Immutable", "System.Memory"], "net48": ["System.Collections.Immutable", "System.Memory"], "net5.0": ["System.Collections.Immutable", "System.Memory"], "net6.0": ["System.Collections.Immutable"], "net7.0": ["System.Collections.Immutable"], "net8.0": ["System.Collections.Immutable"], "net9.0": ["System.Collections.Immutable"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Memory"], "netstandard2.1": ["System.Collections.Immutable", "System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Reflection.MetadataLoadContext", "id": "System.Reflection.MetadataLoadContext", "version": "8.0.0", "sha512": "sha512-vfR5BfUXXy3amp5aDoOTwOt9BJ8CtplaAnEKHbeTbmMW1SJMrSdviTVVRNqDB0eB9o1j/26WD1VA8JGFfr8t+Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net462": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net47": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net471": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net472": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net48": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net5.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net6.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net7.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net8.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netstandard2.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Numerics.Vectors", "id": "System.Numerics.Vectors", "version": "4.6.0", "sha512": "sha512-dxZWbnnb21+5QuKAiUEntJirh5KiU1nqlLWtBu4v9/Fx1RnsgNn8T4XbmQhvCq/T94201P6EsGG2z2Y5ded1yA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Reflection.Metadata", "id": "System.Reflection.Metadata", "version": "9.0.0", "sha512": "sha512-jz+Y2m/CpdPvdjCNRigiWJYKFusdkfJlxDx4V5cWX2TubAMaz5CZpODBD/P2+20SpWvmZG6J3UYjl+R2Yg7yFw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Memory"], "net462": ["System.Collections.Immutable", "System.Memory"], "net47": ["System.Collections.Immutable", "System.Memory"], "net471": ["System.Collections.Immutable", "System.Memory"], "net472": ["System.Collections.Immutable", "System.Memory"], "net48": ["System.Collections.Immutable", "System.Memory"], "net5.0": ["System.Collections.Immutable", "System.Memory"], "net6.0": ["System.Collections.Immutable", "System.Memory"], "net7.0": ["System.Collections.Immutable", "System.Memory"], "net8.0": ["System.Collections.Immutable"], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Memory"], "netstandard2.1": ["System.Collections.Immutable", "System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Reflection.MetadataLoadContext", "id": "System.Reflection.MetadataLoadContext", "version": "9.0.0", "sha512": "sha512-or1DAn2dl2SjxPA4tuDG9RxTxeERdHIU7gUJjNf8WhT6D08ZsHbmSZpP2rKpgGOXHMhmXf3CTDNmfa4cSD2DtA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net462": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net47": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net471": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net472": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net48": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net5.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net6.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net7.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "net8.0": ["System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"], "netstandard2.1": ["System.Collections.Immutable", "System.Reflection.Metadata", "System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Runtime", "id": "System.Runtime", "version": "4.3.1", "sha512": "sha512-Al69mPDfzdD+bKGK2HAfB+lNFOHFqnkqzNnUJmmvUe1/qEPK9M7EiTT4zuycKDPy7ev11xz8XVgJWKP0hm7NIA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Runtime.CompilerServices.Unsafe", "id": "System.Runtime.CompilerServices.Unsafe", "version": "6.0.0", "sha512": "sha512-1AVzAb5OxJNvJLnOADtexNmWgattm2XVOT3TjQTN7Dd4SqoSwai1CsN2fth42uQldJSQdz/sAec0+TzxBFgisw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Runtime.CompilerServices.Unsafe", "id": "System.Runtime.CompilerServices.Unsafe", "version": "6.1.0", "sha512": "sha512-iY0upfdQeiaCfoxT+m4XJyb0IJNk4B9TLQFanOCOrU9X5x1x2TjKx0OFbLmg1VG2dOyL5nHMn198SBQ91Yy1kQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Runtime.Handles", "id": "System.Runtime.Handles", "version": "4.3.0", "sha512": "sha512-CluvHdVUv54BvLTOCCyybugreDNk/rR8unMPruzXDtxSjvrQOU3M4R831/lQf4YI8VYp668FGQa/01E+Rq8PEQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Security.Cryptography.ProtectedData", "id": "System.Security.Cryptography.ProtectedData", "version": "8.0.0", "sha512": "sha512-hvcXZ/IR+KXxY9lC9S2izw5/fGYoODJR2r9kQSvs5v/HUAnBRuYYZPJrHzaT0CeDRJzIm8BHJb1ZrwHQ59j3uQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory"], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Memory"], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory"], "netcoreapp2.1": ["System.Memory"], "netcoreapp2.2": ["System.Memory"], "netcoreapp3.0": ["System.Memory"], "netcoreapp3.1": ["System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory"], "netstandard2.1": ["System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Security.Cryptography.ProtectedData", "id": "System.Security.Cryptography.ProtectedData", "version": "9.0.0", "sha512": "sha512-Mbc5s1XBLje0N1idqILQUqWnG8RVj9p7uK110yxZXTzZq3CN7jaCFEySK52kA+dPYtByzcRtA/FUnK4o/sinSw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory"], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Memory"], "net6.0": ["System.Memory"], "net7.0": ["System.Memory"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory"], "netcoreapp2.1": ["System.Memory"], "netcoreapp2.2": ["System.Memory"], "netcoreapp3.0": ["System.Memory"], "netcoreapp3.1": ["System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory"], "netstandard2.1": ["System.Memory"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Security.Principal", "id": "System.Security.Principal", "version": "4.3.0", "sha512": "sha512-24oe0NGJY32e+DFHVQzl2okM9uwYmn0Aa6nehqtVZ55/Al4Yva7S3BN934Kn5qATH7TVTUJkgxhisdfF7mKDfg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Runtime"], "net6.0": ["System.Runtime"], "net7.0": ["System.Runtime"], "net8.0": ["System.Runtime"], "net9.0": ["System.Runtime"], "netcoreapp1.0": ["System.Runtime"], "netcoreapp1.1": ["System.Runtime"], "netcoreapp2.0": ["System.Runtime"], "netcoreapp2.1": ["System.Runtime"], "netcoreapp2.2": ["System.Runtime"], "netcoreapp3.0": ["System.Runtime"], "netcoreapp3.1": ["System.Runtime"], "netstandard": [], "netstandard1.0": ["System.Runtime"], "netstandard1.1": ["System.Runtime"], "netstandard1.2": ["System.Runtime"], "netstandard1.3": ["System.Runtime"], "netstandard1.4": ["System.Runtime"], "netstandard1.5": ["System.Runtime"], "netstandard1.6": ["System.Runtime"], "netstandard2.0": ["System.Runtime"], "netstandard2.1": ["System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Text.Encoding", "id": "System.Text.Encoding", "version": "4.3.0", "sha512": "sha512-b/f+7HMTpxIfeV7H03bkuHKMFylCGfr9/U6gePnfFFW0aF8LOWLDgQCY6V1oWUqDksC3mdNuyChM1vy9TP4sZw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Text.Encoding.CodePages", "id": "System.Text.Encoding.CodePages", "version": "7.0.0", "sha512": "sha512-SFq/rrH52sMHJJsthDdafWPEuxdRCRB7pZ46trR2xSpi1nfKPAbw6amZr9W/LyHTlqS01TRWO7najRuO1vxFig==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Runtime.CompilerServices.Unsafe"], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Threading.Channels", "id": "System.Threading.Channels", "version": "7.0.0", "sha512": "sha512-XXmpdJbyVCagWg3bGfUGNTxKp4EK/3C4Bt8pXhKVYZKwHPjeHPOg0u2wdqHFsojU4u4i9KByAJTyzqLCMqwpUg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Threading.Tasks.Extensions"], "net462": ["System.Threading.Tasks.Extensions"], "net47": ["System.Threading.Tasks.Extensions"], "net471": ["System.Threading.Tasks.Extensions"], "net472": ["System.Threading.Tasks.Extensions"], "net48": ["System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Text.Encoding.CodePages", "id": "System.Text.Encoding.CodePages", "version": "9.0.0", "sha512": "sha512-rMAcE2cpS8RvPR5iK6WkYdZKJLsUw5BRqG3d/LR0dl8x17ezOj43AWRhp4LRIFgydWjOOn/Z4w//l8wcowngvQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Threading.Channels", "id": "System.Threading.Channels", "version": "9.0.0", "sha512": "sha512-6q+SC/qL5eeX9t3zUjmtsccStVusUvYXdJFYGf3ihM/8TionV+iZxi3mxDPPFXOiepRe7WgrIOuoaCi4+bwZ0g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Bcl.AsyncInterfaces", "System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Threading.Tasks", "id": "System.Threading.Tasks", "version": "4.3.0", "sha512": "sha512-fUiP+CyyCjs872OA8trl6p97qma/da1xGq3h4zAbJZk8zyaU4zyEfqW5vbkP80xG/Nimun1vlWBboMEk7XxdEw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net6.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net7.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net8.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "net9.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp2.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netcoreapp3.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard": [], "netstandard1.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.2": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.3": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.4": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.5": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard1.6": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.0": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"], "netstandard2.1": ["Microsoft.NETCore.Platforms", "Microsoft.NETCore.Targets", "System.Runtime"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "System.Threading.Tasks.Extensions", "id": "System.Threading.Tasks.Extensions", "version": "4.5.4", "sha512": "sha512-aAUghud9PHGYc3o9oWPWd0C3xE+TJQw5ZZs78htlR6mr9ky/QEgfXHjyQ2GvOq9H1S0YizcVVKCSin92ZcH8FA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": ["System.Runtime.CompilerServices.Unsafe"], "net451": ["System.Runtime.CompilerServices.Unsafe"], "net452": ["System.Runtime.CompilerServices.Unsafe"], "net46": ["System.Runtime.CompilerServices.Unsafe"], "net461": ["System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netcoreapp1.1": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.1": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.2": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.3": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.4": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.5": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard1.6": ["System.Runtime", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks"], "netstandard2.0": ["System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "System.Threading.Tasks.Extensions", "id": "System.Threading.Tasks.Extensions", "version": "4.6.0", "sha512": "sha512-ph8eP2gKhA6mNhj/teYwn9xCrHMc7+nBMlSMKX7BUXcZn33RVLe45TWABkcgyS6TJWYx1v1WwtylHmF3Fvg0qQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "System.Threading.ThreadPool", "id": "System.Threading.ThreadPool", "version": "4.3.0", "sha512": "sha512-RQpA+UpI6Tlpeedk5JStYk2DM/M3i5HqabI/yDbfj1xDu9bIz9kdoquVpHbh/wQjOJaOCbcgRH8iQcAUv8dRWQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": ["System.Runtime", "System.Runtime.Handles"], "net6.0": ["System.Runtime", "System.Runtime.Handles"], "net7.0": ["System.Runtime", "System.Runtime.Handles"], "net8.0": ["System.Runtime", "System.Runtime.Handles"], "net9.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp1.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp1.1": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp2.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp2.1": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp2.2": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp3.0": ["System.Runtime", "System.Runtime.Handles"], "netcoreapp3.1": ["System.Runtime", "System.Runtime.Handles"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": ["System.Runtime", "System.Runtime.Handles"], "netstandard1.4": ["System.Runtime", "System.Runtime.Handles"], "netstandard1.5": ["System.Runtime", "System.Runtime.Handles"], "netstandard1.6": ["System.Runtime", "System.Runtime.Handles"], "netstandard2.0": ["System.Runtime", "System.Runtime.Handles"], "netstandard2.1": ["System.Runtime", "System.Runtime.Handles"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit", "id": "xunit", "version": "2.9.2", "sha512": "sha512-bs4ccplaqCT7+jdAJhtt75uKq9qA3Jeld1ugiOgGEGSnzq8gkoa0VUqNEKkMPkBwV5COlAllNJGtGBfgxoZDrA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net20": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net30": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net35": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net40": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net403": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net45": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net451": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net452": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net46": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net461": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net462": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net47": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net471": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net472": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net48": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net5.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net6.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net7.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net8.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "net9.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp1.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp1.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp2.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp2.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp2.2": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp3.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netcoreapp3.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.1": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.2": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.3": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.4": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.5": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard1.6": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard2.0": ["xunit.core", "xunit.assert", "xunit.analyzers"], "netstandard2.1": ["xunit.core", "xunit.assert", "xunit.analyzers"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit.abstractions", "id": "xunit.abstractions", "version": "2.0.3", "sha512": "sha512-PKJri5f0qEQPFvgY6CZR9XG8JROlWSdC/ZYLkkDQuID++Egn+yWjB+Yf57AZ8U6GRlP7z33uDQ4/r5BZPer2JA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "xunit.analyzers", "id": "xunit.analyzers", "version": "1.16.0", "sha512": "sha512-65QLxnRoOqpAn2hMnjI1FLmQEjzUye2h4MwRVe1k151K+UFG1Ehr/s/MLwNJ6pCNoyoJjOoNuF7OGW4mH2bdaQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "xunit.analyzers", "id": "xunit.analyzers", "version": "1.17.0", "sha512": "sha512-36BC2a5gEL5TDXjkzhD8dK4toNcPGdwFb4tbIODwTp4eXhRS6BURiTclfZD2vFNTq4obCzPOdwnayhppP4qtUg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit.assert", "id": "xunit.assert", "version": "2.9.2", "sha512": "sha512-huNfINLH5HnyiPImimKv7liIJJ2MgRdJYT7ky3464zR62SH7o9JjsgMiSZRXha46kgTCNjKSNN1VvctC+USp7w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit.core", "id": "xunit.core", "version": "2.9.2", "sha512": "sha512-kW48d7YL7ryT4zuWTjJN491cJwY8aYiIAxDaXJRebgMIw40PmlREiiaIz33QUFmglcfLlaoRyZcI4sl70kARiw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net20": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net30": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net35": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net40": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net403": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net45": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net451": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net452": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net46": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net461": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net462": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net47": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net471": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net472": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net48": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net5.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net6.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net7.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net8.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "net9.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netcoreapp1.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netcoreapp1.1": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netcoreapp2.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netcoreapp2.1": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netcoreapp2.2": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netcoreapp3.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netcoreapp3.1": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard1.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard1.1": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard1.2": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard1.3": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard1.4": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard1.5": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard1.6": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard2.0": ["xunit.extensibility.core", "xunit.extensibility.execution"], "netstandard2.1": ["xunit.extensibility.core", "xunit.extensibility.execution"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "xunit.extensibility.core", "id": "xunit.extensibility.core", "version": "2.9.2", "sha512": "sha512-sosk+dg5Cn4N9MKOjQ1wFTvfgduqiX1DLRZHEYXIaLOuTJbCJeXfn7XhAVDGY+zeB8aX3jCKL8BcDp4EJCdZXw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": ["xunit.abstractions"], "net451": ["xunit.abstractions"], "net452": ["xunit.abstractions"], "net46": ["xunit.abstractions"], "net461": ["xunit.abstractions"], "net462": ["xunit.abstractions"], "net47": ["xunit.abstractions"], "net471": ["xunit.abstractions"], "net472": ["xunit.abstractions"], "net48": ["xunit.abstractions"], "net5.0": ["xunit.abstractions"], "net6.0": ["xunit.abstractions"], "net7.0": ["xunit.abstractions"], "net8.0": ["xunit.abstractions"], "net9.0": ["xunit.abstractions"], "netcoreapp1.0": ["xunit.abstractions"], "netcoreapp1.1": ["xunit.abstractions"], "netcoreapp2.0": ["xunit.abstractions"], "netcoreapp2.1": ["xunit.abstractions"], "netcoreapp2.2": ["xunit.abstractions"], "netcoreapp3.0": ["xunit.abstractions"], "netcoreapp3.1": ["xunit.abstractions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": ["xunit.abstractions"], "netstandard1.2": ["xunit.abstractions"], "netstandard1.3": ["xunit.abstractions"], "netstandard1.4": ["xunit.abstractions"], "netstandard1.5": ["xunit.abstractions"], "netstandard1.6": ["xunit.abstractions"], "netstandard2.0": ["xunit.abstractions"], "netstandard2.1": ["xunit.abstractions"]}, "targeting_pack_overrides": [], "framework_list": []}, From 6a0d56a1464f349c78044ac12953bdb720044854 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 15:45:10 +0100 Subject: [PATCH 096/213] C#: Update DataQuality output. Roslyn now correctly finds the compile time target. --- .../Telemetry/DatabaseQuality/IsNotOkayCall.expected | 1 - .../query-tests/Telemetry/DatabaseQuality/NoTarget.expected | 1 - csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected index 205022b71802..7555a37394b5 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected @@ -1,4 +1,3 @@ | Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer | | Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer | | Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer | -| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null | diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected index 84b6994e033a..7ae469cf84e3 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected @@ -10,6 +10,5 @@ | Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer | | Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer | | Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer | -| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null | | Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 | | Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T | diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs index c3ec759d6879..31f4deda5df5 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs @@ -31,7 +31,7 @@ public Test() Span guidBytes = stackalloc byte[16]; guidBytes[08] = 1; // TODO: this indexer call has no target, because the target is a `ref` returning getter. - new MyList([new(), new Test()]); // TODO: the `new()` call has no target, which is unexpected, as we know at compile time, that this is a `new Test()` call. + new MyList([new(), new Test()]); } public int MyProperty1 { get; } From 61fa889190e89ab423fd8fa5185d8f360f9d0ada Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 16:04:15 +0100 Subject: [PATCH 097/213] C#: Update the format test expected output as the params keyword is now extracted correctly. --- .../format/StringFormatItemParameter.expected | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected b/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected index 978e1340492e..53106dd756e1 100644 --- a/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected +++ b/csharp/ql/test/library-tests/frameworks/format/StringFormatItemParameter.expected @@ -1,4 +1,3 @@ -| Console | Write(string, ReadOnlySpan) | arg | | Console | Write(string, object) | arg0 | | Console | Write(string, object, object) | arg0 | | Console | Write(string, object, object) | arg1 | @@ -6,7 +5,7 @@ | Console | Write(string, object, object, object) | arg1 | | Console | Write(string, object, object, object) | arg2 | | Console | Write(string, params Object[]) | arg | -| Console | WriteLine(string, ReadOnlySpan) | arg | +| Console | Write(string, params ReadOnlySpan) | arg | | Console | WriteLine(string, object) | arg0 | | Console | WriteLine(string, object, object) | arg0 | | Console | WriteLine(string, object, object) | arg1 | @@ -14,10 +13,10 @@ | Console | WriteLine(string, object, object, object) | arg1 | | Console | WriteLine(string, object, object, object) | arg2 | | Console | WriteLine(string, params Object[]) | arg | +| Console | WriteLine(string, params ReadOnlySpan) | arg | | Debug | Assert(bool, string, string, params Object[]) | args | | Debug | Print(string, params Object[]) | args | | Debug | WriteLine(string, params Object[]) | args | -| StringBuilder | AppendFormat(IFormatProvider, string, ReadOnlySpan) | args | | StringBuilder | AppendFormat(IFormatProvider, string, object) | arg0 | | StringBuilder | AppendFormat(IFormatProvider, string, object, object) | arg0 | | StringBuilder | AppendFormat(IFormatProvider, string, object, object) | arg1 | @@ -25,7 +24,7 @@ | StringBuilder | AppendFormat(IFormatProvider, string, object, object, object) | arg1 | | StringBuilder | AppendFormat(IFormatProvider, string, object, object, object) | arg2 | | StringBuilder | AppendFormat(IFormatProvider, string, params Object[]) | args | -| StringBuilder | AppendFormat(string, ReadOnlySpan) | args | +| StringBuilder | AppendFormat(IFormatProvider, string, params ReadOnlySpan) | args | | StringBuilder | AppendFormat(string, object) | arg0 | | StringBuilder | AppendFormat(string, object, object) | arg0 | | StringBuilder | AppendFormat(string, object, object) | arg1 | @@ -33,8 +32,8 @@ | StringBuilder | AppendFormat(string, object, object, object) | arg1 | | StringBuilder | AppendFormat(string, object, object, object) | arg2 | | StringBuilder | AppendFormat(string, params Object[]) | args | +| StringBuilder | AppendFormat(string, params ReadOnlySpan) | args | | Strings | MyStringFormat(string, params Object[]) | args | -| TextWriter | Write(string, ReadOnlySpan) | arg | | TextWriter | Write(string, object) | arg0 | | TextWriter | Write(string, object, object) | arg0 | | TextWriter | Write(string, object, object) | arg1 | @@ -42,7 +41,7 @@ | TextWriter | Write(string, object, object, object) | arg1 | | TextWriter | Write(string, object, object, object) | arg2 | | TextWriter | Write(string, params Object[]) | arg | -| TextWriter | WriteLine(string, ReadOnlySpan) | arg | +| TextWriter | Write(string, params ReadOnlySpan) | arg | | TextWriter | WriteLine(string, object) | arg0 | | TextWriter | WriteLine(string, object, object) | arg0 | | TextWriter | WriteLine(string, object, object) | arg1 | @@ -50,7 +49,7 @@ | TextWriter | WriteLine(string, object, object, object) | arg1 | | TextWriter | WriteLine(string, object, object, object) | arg2 | | TextWriter | WriteLine(string, params Object[]) | arg | -| string | Format(IFormatProvider, string, ReadOnlySpan) | args | +| TextWriter | WriteLine(string, params ReadOnlySpan) | arg | | string | Format(IFormatProvider, string, object) | arg0 | | string | Format(IFormatProvider, string, object, object) | arg0 | | string | Format(IFormatProvider, string, object, object) | arg1 | @@ -58,7 +57,7 @@ | string | Format(IFormatProvider, string, object, object, object) | arg1 | | string | Format(IFormatProvider, string, object, object, object) | arg2 | | string | Format(IFormatProvider, string, params Object[]) | args | -| string | Format(string, ReadOnlySpan) | args | +| string | Format(IFormatProvider, string, params ReadOnlySpan) | args | | string | Format(string, object) | arg0 | | string | Format(string, object, object) | arg0 | | string | Format(string, object, object) | arg1 | @@ -66,3 +65,4 @@ | string | Format(string, object, object, object) | arg1 | | string | Format(string, object, object, object) | arg2 | | string | Format(string, params Object[]) | args | +| string | Format(string, params ReadOnlySpan) | args | From f94aaee53cc768cd3910da2aee461a9a7a6f1400 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 16:11:46 +0100 Subject: [PATCH 098/213] C#: Update integration tests expected output. --- .../Assemblies.expected | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected index 18cbc068ace1..a706f914cd9f 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected @@ -2,6 +2,7 @@ | [...]/csharp/tools/[...]/Humanizer.dll | | [...]/csharp/tools/[...]/MessagePack.Annotations.dll | | [...]/csharp/tools/[...]/MessagePack.dll | +| [...]/csharp/tools/[...]/Microsoft.Bcl.AsyncInterfaces.dll | | [...]/csharp/tools/[...]/Microsoft.Build.Framework.dll | | [...]/csharp/tools/[...]/Microsoft.Build.Utilities.Core.dll | | [...]/csharp/tools/[...]/Microsoft.Build.dll | @@ -18,7 +19,6 @@ | [...]/csharp/tools/[...]/Microsoft.VisualBasic.dll | | [...]/csharp/tools/[...]/Microsoft.Win32.Primitives.dll | | [...]/csharp/tools/[...]/Microsoft.Win32.Registry.dll | -| [...]/csharp/tools/[...]/Microsoft.Win32.SystemEvents.dll | | [...]/csharp/tools/[...]/Mono.Posix.NETStandard.dll | | [...]/csharp/tools/[...]/Newtonsoft.Json.dll | | [...]/csharp/tools/[...]/StructuredLogger.dll | @@ -58,7 +58,6 @@ | [...]/csharp/tools/[...]/System.Diagnostics.Tools.dll | | [...]/csharp/tools/[...]/System.Diagnostics.TraceSource.dll | | [...]/csharp/tools/[...]/System.Diagnostics.Tracing.dll | -| [...]/csharp/tools/[...]/System.Drawing.Common.dll | | [...]/csharp/tools/[...]/System.Drawing.Primitives.dll | | [...]/csharp/tools/[...]/System.Drawing.dll | | [...]/csharp/tools/[...]/System.Dynamic.Runtime.dll | @@ -155,7 +154,6 @@ | [...]/csharp/tools/[...]/System.Security.Cryptography.ProtectedData.dll | | [...]/csharp/tools/[...]/System.Security.Cryptography.X509Certificates.dll | | [...]/csharp/tools/[...]/System.Security.Cryptography.dll | -| [...]/csharp/tools/[...]/System.Security.Permissions.dll | | [...]/csharp/tools/[...]/System.Security.Principal.Windows.dll | | [...]/csharp/tools/[...]/System.Security.Principal.dll | | [...]/csharp/tools/[...]/System.Security.SecureString.dll | @@ -183,7 +181,6 @@ | [...]/csharp/tools/[...]/System.ValueTuple.dll | | [...]/csharp/tools/[...]/System.Web.HttpUtility.dll | | [...]/csharp/tools/[...]/System.Web.dll | -| [...]/csharp/tools/[...]/System.Windows.Extensions.dll | | [...]/csharp/tools/[...]/System.Windows.dll | | [...]/csharp/tools/[...]/System.Xml.Linq.dll | | [...]/csharp/tools/[...]/System.Xml.ReaderWriter.dll | From d83f2215f63cf473c8fe0c2dbbfb85afa97a0574 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 16:29:33 +0100 Subject: [PATCH 099/213] C#: Update Parameters test to only inspect parameters from source code. --- csharp/ql/test/library-tests/methods/Parameters4.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/test/library-tests/methods/Parameters4.ql b/csharp/ql/test/library-tests/methods/Parameters4.ql index aa103547f86a..832f6c1ea37e 100644 --- a/csharp/ql/test/library-tests/methods/Parameters4.ql +++ b/csharp/ql/test/library-tests/methods/Parameters4.ql @@ -4,5 +4,5 @@ import csharp -where forall(Parameter p | p.isParams() | p.getType() instanceof ArrayType) +where forall(Parameter p | p.isParams() and p.fromSource() | p.getType() instanceof ArrayType) select 1 From b9253222a64867d7336cd3a58411e28e1c2eab39 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 4 Dec 2024 16:42:23 +0100 Subject: [PATCH 100/213] C#: Add change-note. --- csharp/ql/lib/change-notes/2024-12-04-dotnet9.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2024-12-04-dotnet9.md diff --git a/csharp/ql/lib/change-notes/2024-12-04-dotnet9.md b/csharp/ql/lib/change-notes/2024-12-04-dotnet9.md new file mode 100644 index 000000000000..e166040e1551 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-12-04-dotnet9.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The C# extractor now supports *basic* extraction of .NET 9 projects. There might be limited support for extraction of code using the new C# 13 language features. From af2234453bef919b66c604aa45d2a419b21402e0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 6 Dec 2024 09:10:55 +0100 Subject: [PATCH 101/213] C#: Update dependencies (binlog package needs to be updated). --- csharp/paket.lock | 12 +++++++----- csharp/paket.main.bzl | 7 ++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/csharp/paket.lock b/csharp/paket.lock index 8bfc5b1650e4..1d8e48895b34 100644 --- a/csharp/paket.lock +++ b/csharp/paket.lock @@ -3,7 +3,7 @@ STRATEGY: MAX RESTRICTION: == net9.0 NUGET remote: https://api.nuget.org/v3/index.json - Basic.CompilerLog.Util (0.9.3) + Basic.CompilerLog.Util (0.9.4) MessagePack (>= 2.5.187) Microsoft.CodeAnalysis (>= 4.11) Microsoft.CodeAnalysis.CSharp (>= 4.11) @@ -12,10 +12,12 @@ NUGET MSBuild.StructuredLogger (>= 2.2.243) System.Buffers (>= 4.6) Humanizer.Core (2.14.1) - MessagePack (2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.NET.StringTools (>= 17.6.3) - MessagePack.Annotations (2.5.192) + MessagePack (3.0.3) + MessagePack.Annotations (>= 3.0.3) + MessagePackAnalyzer (>= 3.0.3) + Microsoft.NET.StringTools (>= 17.11.4) + MessagePack.Annotations (3.0.3) + MessagePackAnalyzer (3.0.3) Microsoft.Bcl.AsyncInterfaces (9.0) Microsoft.Build (17.12.6) Microsoft.Build.Framework (>= 17.12.6) diff --git a/csharp/paket.main.bzl b/csharp/paket.main.bzl index fa79062ab441..4887b7c333ff 100644 --- a/csharp/paket.main.bzl +++ b/csharp/paket.main.bzl @@ -7,10 +7,11 @@ def main(): nuget_repo( name = "paket.main", packages = [ - {"name": "Basic.CompilerLog.Util", "id": "Basic.CompilerLog.Util", "version": "0.9.3", "sha512": "sha512-hgu/4KttHz9bXOISmomz1uO4WidkXqBbSu4MjVgj3SeJ/bH4t+nkZ5qybpqpZJHf04hdXlyt/ux0OWv5/xEKRQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net462": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net47": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net471": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net472": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net48": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net5.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net6.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net7.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net8.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net9.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.2": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "Basic.CompilerLog.Util", "id": "Basic.CompilerLog.Util", "version": "0.9.4", "sha512": "sha512-VJMBSOOcdPD6ihA5k1gnVkDbH9GCABmx1055fFikEImT2dFp4yZhN7zMd8PW14tIb3BXIieP557n8xE+J2Y8Dw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net462": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net47": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net471": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net472": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net48": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net5.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net6.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net7.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net8.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net9.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.2": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"]}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Humanizer.Core", "id": "Humanizer.Core", "version": "2.14.1", "sha512": "sha512-yzqGU/HKNLZ9Uvr6kvSc3wYV/S5O/IvklIUW5WF7MuivGLY8wS5IZnLPkt7D1KW8Et2Enl0I3Lzg2vGWM24Xsw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MessagePack", "id": "MessagePack", "version": "2.5.192", "sha512": "sha512-SnrwSQIKWfxcQvzE1TCUPvJ7A/44KFBDcmCc+YUDIq8QalCf0bGAjiBoAFewhJ81QuS5FsCNCOcKn+IURYlbAQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net7.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net8.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, - {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "2.5.192", "sha512": "sha512-pE/SD2N0+nDAU8BtTHqjyIhLM2L5Mb0NiO4hW0ybiv2I+BbK0JEaGtbKpeEmOvKT+5s2hds0gvk/GrAHhgcpdw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MessagePack", "id": "MessagePack", "version": "3.0.3", "sha512": "sha512-rFOP00M8dZRRVVjg11M79hU9lhMziIkmqIc9CQ9QhK0R+us1mmpuEGwvnFupqN4F3zYEEoAM36SAdVC+i+mw+Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net6.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net7.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net8.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "netcoreapp3.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"]}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "3.0.3", "sha512": "sha512-LYOfElsnLTHsEs7VRd07mBiQjJos15mst8jP0v0zRx+t1OgUMUbbmQx6yO2fOww7vCyaX7vwXsoNuVJSdJdHPA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, + {"name": "MessagePackAnalyzer", "id": "MessagePackAnalyzer", "version": "3.0.3", "sha512": "sha512-gsMDGQbQv5dwGGKo2N6mC4TvIVaqKHqowgtqOMcVDLPnYUFdCViW2A+sssnBXJLR4m+zbFVHI7EBSR86svG+AQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.Bcl.AsyncInterfaces", "id": "Microsoft.Bcl.AsyncInterfaces", "version": "9.0.0", "sha512": "sha512-bYp2ksSR5uB6xqOa4NyD2gBOeFrc2n8FAWoh781MNMDcPjk1ysD7DNpv7r7sQOXfdFJT6F/syX7fN4lmUsn+RQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Threading.Tasks.Extensions"], "net462": ["System.Threading.Tasks.Extensions"], "net47": ["System.Threading.Tasks.Extensions"], "net471": ["System.Threading.Tasks.Extensions"], "net472": ["System.Threading.Tasks.Extensions"], "net48": ["System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.Build", "id": "Microsoft.Build", "version": "17.12.6", "sha512": "sha512-YEiL5xKowbwnr52YroALNHg8YurjLyFTlhv3USrswhubuxN2ldY1TmQpBKQ4K28UgWJV9BxTVXY9/CecMNDeOA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Collections.Immutable", "System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": []}, {"name": "Microsoft.Build.Framework", "id": "Microsoft.Build.Framework", "version": "17.12.6", "sha512": "sha512-UjfxnrQN9BPVtO0Kvv2FB5dpN2CX5snc7coq5vVQdbCV6kdSpI/r+GZTLvU/5BTT8y8bvIUqoocxRR674N6bWg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": []}, From d7d4658aaedba635fad11516c2dbe77b76b73c05 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:52:55 +0000 Subject: [PATCH 102/213] Rust: Add % of files extractor without errors to summary stats. --- rust/ql/src/queries/summary/SummaryStats.ql | 5 +++++ rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 1 + 2 files changed, 6 insertions(+) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index ffe7cbf1a8fa..2e30fde143aa 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -32,6 +32,11 @@ where key = "Files extracted - without errors" and value = count(SuccessfullyExtractedFile f | exists(f.getRelativePath())) or + key = "Files extracted - without errors %" and + value = + (count(SuccessfullyExtractedFile f | exists(f.getRelativePath())) * 100) / + count(ExtractedFile f | exists(f.getRelativePath())) + or key = "Lines of code extracted" and value = getLinesOfCode() or key = "Lines of user code extracted" and value = getLinesOfUserCode() diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index 9372843039cb..a5295af6e104 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -5,6 +5,7 @@ | Files extracted - total | 7 | | Files extracted - with errors | 3 | | Files extracted - without errors | 4 | +| Files extracted - without errors % | 57 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 0 | From 4e079d34b9bc75efeda51f573d5626655e9581d8 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 6 Dec 2024 15:55:30 +0100 Subject: [PATCH 103/213] C#: Clean up dependencies Newtonsoft.Json and dont override nowarn. --- csharp/autobuilder/Semmle.Autobuild.CSharp/BUILD.bazel | 1 - csharp/autobuilder/Semmle.Autobuild.CSharp/paket.references | 1 - .../Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel | 2 +- .../paket.references | 1 + 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/BUILD.bazel b/csharp/autobuilder/Semmle.Autobuild.CSharp/BUILD.bazel index 99cf29e52207..7ef9b1eb5b3b 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/BUILD.bazel +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/BUILD.bazel @@ -17,6 +17,5 @@ codeql_csharp_binary( "//csharp/extractor/Semmle.Extraction.CSharp.Standalone:bin/Semmle.Extraction.CSharp.Standalone", "//csharp/extractor/Semmle.Util", "@paket.main//microsoft.build", - "@paket.main//newtonsoft.json", ], ) diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/paket.references b/csharp/autobuilder/Semmle.Autobuild.CSharp/paket.references index 53fe17d215e9..ec65ce95b918 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/paket.references +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/paket.references @@ -1,2 +1 @@ -Newtonsoft.Json Microsoft.Build diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel index 4be9954a2740..8be8aaa8408b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel @@ -11,10 +11,10 @@ codeql_csharp_library( ]), allow_unsafe_blocks = True, internals_visible_to = ["Semmle.Extraction.Tests"], - nowarn = ["CA1822"], visibility = ["//csharp:__subpackages__"], deps = [ "//csharp/extractor/Semmle.Extraction.CSharp", "//csharp/extractor/Semmle.Util", + "@paket.main//newtonsoft.json", ], ) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/paket.references b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/paket.references index e69de29bb2d1..99e44f5d76ed 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/paket.references +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/paket.references @@ -0,0 +1 @@ +Newtonsoft.Json From 1935c26b568906b9544881864c0771bb28e9dfb3 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 14:15:41 +0000 Subject: [PATCH 104/213] Trivial variable name fixes --- .../semmle/go/dataflow/ExternalValueFlow/completetest.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql index 372283d0a6cc..efd5f0d5bb38 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql @@ -9,9 +9,9 @@ import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineFlowTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { sourceNode(src, "qltest") } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node src) { sinkNode(src, "qltest") } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } import ValueFlowTest From ec7cbf93d9f887c932b1bb780eb104a04349da40 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 10:45:04 +0000 Subject: [PATCH 105/213] Add failing test for flow out of varargs parameter --- .../library-tests/semmle/go/dataflow/VarArgs/main.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go index 8e3a498656af..84e769659806 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go @@ -4,7 +4,7 @@ func source() string { return "untrusted data" } -func sink(string) { +func sink(any) { } type A struct { @@ -19,6 +19,10 @@ func functionWithVarArgsParameter(s ...string) string { return s[1] } +func functionWithVarArgsOutParameter(in string, out ...*string) { + *out[0] = in +} + func functionWithSliceOfStructsParameter(s []A) string { return s[1].f } @@ -38,6 +42,12 @@ func main() { sink(functionWithVarArgsParameter(sSlice...)) // $ hasValueFlow="call to functionWithVarArgsParameter" sink(functionWithVarArgsParameter(s0, s1)) // $ hasValueFlow="call to functionWithVarArgsParameter" + var out1 *string + var out2 *string + functionWithVarArgsOutParameter(source(), out1, out2) + sink(out1) // $ MISSING: hasValueFlow="out1" + sink(out2) // $ MISSING: hasValueFlow="out2" + sliceOfStructs := []A{{f: source()}} sink(sliceOfStructs[0].f) // $ hasValueFlow="selection of f" From 69f087a46d582772686e2d075d7ed2e5bc5e19bf Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 13:17:18 +0000 Subject: [PATCH 106/213] Fix pre-existing failing test in VarArgsWithFunctionModels It was failing for a silly reason. --- .../go/dataflow/VarArgsWithFunctionModels/main.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go index c561de0da2f0..f7248f1f6a2b 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go @@ -21,10 +21,11 @@ func main() { s0 := "" s1 := source() sSlice := []string{s0, s1} - sink(test.FunctionWithParameter(sSlice[1])) // $ hasValueFlow="call to FunctionWithParameter" - sink(test.FunctionWithSliceParameter(sSlice)) // $ hasTaintFlow="call to FunctionWithSliceParameter" MISSING: hasValueFlow="call to FunctionWithSliceParameter" - sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ hasTaintFlow="call to FunctionWithVarArgsParameter" MISSING: hasValueFlow="call to FunctionWithVarArgsParameter" - sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ MISSING: hasValueFlow="call to FunctionWithVarArgsParameter" + sink(test.FunctionWithParameter(sSlice[1])) // $ hasValueFlow="call to FunctionWithParameter" + sink(test.FunctionWithSliceParameter(sSlice)) // $ hasTaintFlow="call to FunctionWithSliceParameter" MISSING: hasValueFlow="call to FunctionWithSliceParameter" + sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ hasTaintFlow="call to FunctionWithVarArgsParameter" MISSING: hasValueFlow="call to FunctionWithVarArgsParameter" + randomFunctionWithMoreThanOneParameter(1, 2, 3, 4, 5) // This is needed to make the next line pass, because we need to have seen a call to a function with at least 2 parameters for ParameterInput to exist with index 1. + sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ hasValueFlow="call to FunctionWithVarArgsParameter" sliceOfStructs := []test.A{{Field: source()}} sink(sliceOfStructs[0].Field) // $ hasValueFlow="selection of Field" @@ -37,3 +38,6 @@ func main() { sink(test.FunctionWithVarArgsOfStructsParameter(aSlice...)) // $ MISSING: hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" sink(test.FunctionWithVarArgsOfStructsParameter(a0, a1)) // $ MISSING: hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" } + +func randomFunctionWithMoreThanOneParameter(i1, i2, i3, i4, i5 int) { +} From 1612a7a9a07a1f8f78c9a158622e133675622ad2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 13:40:08 +0000 Subject: [PATCH 107/213] Delete accidentally committed binary --- .../semmle.go.Packages | Bin 1142176 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/semmle.go.Packages diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/semmle.go.Packages b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/semmle.go.Packages deleted file mode 100755 index e3880ac8d5d9d893c3ee41a8c4aafe2702f1a859..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1142176 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�MD|S##F~b&+)q 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

q}H7R1tPs&LZJwhx4uZ%vC`ArbuAE) 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 z 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

!KeL;T0`mHG(t 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 ?Mn&jw~`7a;9p;ANR&ixFRgK>3}7m{*7} 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ΠHcAY${9) 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%0AWsK%`mhSn9IG6Ky>s91hq-G0t}`}+z8ksK$fd-w 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 From 96c8af89433b0054f14bff982cb5215a8dd31010 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 13:04:19 +0000 Subject: [PATCH 108/213] Test flow out of varargs param with function models --- .../semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql | 3 +++ .../semmle/go/dataflow/VarArgsWithFunctionModels/go.mod | 2 +- .../semmle/go/dataflow/VarArgsWithFunctionModels/main.go | 8 +++++++- .../vendor/github.com/nonexistent/test/stub.go | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql index 80f711e33129..22da81845c0e 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql @@ -19,6 +19,9 @@ class SummaryModelTest extends DataFlow::FunctionModel { this.hasQualifiedName("github.com/nonexistent/test", "FunctionWithVarArgsParameter") and (inp.isParameter(_) and outp.isResult()) or + this.hasQualifiedName("github.com/nonexistent/test", "FunctionWithVarArgsOutParameter") and + (inp.isParameter(0) and outp.isParameter(any(int i | i >= 1))) + or this.hasQualifiedName("github.com/nonexistent/test", "FunctionWithSliceOfStructsParameter") and (inp.isParameter(0) and outp.isResult()) or diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod index ed18764ed282..cdb11f2ee6cf 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod @@ -1,5 +1,5 @@ module semmle.go.Packages -go 1.17 +go 1.23 require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000 diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go index f7248f1f6a2b..e8d53eb9b288 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go @@ -8,7 +8,7 @@ func source() string { return "untrusted data" } -func sink(string) { +func sink(any) { } func main() { @@ -27,6 +27,12 @@ func main() { randomFunctionWithMoreThanOneParameter(1, 2, 3, 4, 5) // This is needed to make the next line pass, because we need to have seen a call to a function with at least 2 parameters for ParameterInput to exist with index 1. sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ hasValueFlow="call to FunctionWithVarArgsParameter" + var out1 *string + var out2 *string + test.FunctionWithVarArgsOutParameter(source(), out1, out2) + sink(out1) // $ hasValueFlow="out1" + sink(out2) // $ hasValueFlow="out2" + sliceOfStructs := []test.A{{Field: source()}} sink(sliceOfStructs[0].Field) // $ hasValueFlow="selection of Field" diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go index 66f3da7d6591..b3e407fcaa7c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go @@ -15,6 +15,8 @@ func FunctionWithSliceParameter(s []string) string { func FunctionWithVarArgsParameter(s ...string) string { return "" } +func FunctionWithVarArgsOutParameter(in string, out ...*string) { +} func FunctionWithSliceOfStructsParameter(s []A) string { return "" From 8cc4cd58c6e8e68bebb283146d6a723cc89b468f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 13:41:10 +0000 Subject: [PATCH 109/213] Add failing test for flow out of varargs param with models-as-data --- .../VarArgsWithExternalFlow/Flows.expected | 2 + .../VarArgsWithExternalFlow/Flows.ext.yml | 21 ++++++++ .../dataflow/VarArgsWithExternalFlow/Flows.ql | 22 ++++++++ .../dataflow/VarArgsWithExternalFlow/go.mod | 5 ++ .../dataflow/VarArgsWithExternalFlow/main.go | 51 +++++++++++++++++++ .../github.com/nonexistent/test/stub.go | 31 +++++++++++ .../vendor/modules.txt | 3 ++ 7 files changed, 135 insertions(+) create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected new file mode 100644 index 000000000000..55e9aed2e93c --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected @@ -0,0 +1,2 @@ +testFailures +invalidModelRow diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml new file mode 100644 index 000000000000..ca3f9559536a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml @@ -0,0 +1,21 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "", False, "FunctionWithParameter", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithSliceParameter", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithVarArgsParameter", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithVarArgsOutParameter", "", "", "Argument[0]", "Argument[1].ArrayElement", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithSliceOfStructsParameter", "", "", "Argument[0].ArrayElement.Field[github.com/nonexistent/test.A.Field]", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithVarArgsOfStructsParameter", "", "", "Argument[0].ArrayElement.Field[github.com/nonexistent/test.A.Field]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "", False, "VariadicSource", "", "", "Argument[0]", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "", False, "VariadicSink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql new file mode 100644 index 000000000000..0f0b9dbe22de --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql @@ -0,0 +1,22 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import TestUtilities.InlineFlowTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + sourceNode(source, "qltest") + or + exists(Function fn | fn.hasQualifiedName(_, ["source", "taint"]) | + source = fn.getACall().getResult() + ) + } + + predicate isSink(DataFlow::Node sink) { + sinkNode(sink, "qltest") + or + exists(Function fn | fn.hasQualifiedName(_, "sink") | sink = fn.getACall().getAnArgument()) + } +} + +import FlowTest diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod new file mode 100644 index 000000000000..cdb11f2ee6cf --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod @@ -0,0 +1,5 @@ +module semmle.go.Packages + +go 1.23 + +require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000 diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go new file mode 100644 index 000000000000..324864edd229 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "github.com/nonexistent/test" +) + +func source() string { + return "untrusted data" +} + +func sink(any) { +} + +func main() { + s := source() + sink(test.FunctionWithParameter(s)) // $ hasValueFlow="call to FunctionWithParameter" + + stringSlice := []string{source()} + sink(stringSlice[0]) // $ hasValueFlow="index expression" + + s0 := "" + s1 := source() + sSlice := []string{s0, s1} + sink(test.FunctionWithParameter(sSlice[1])) // $ hasValueFlow="call to FunctionWithParameter" + sink(test.FunctionWithSliceParameter(sSlice)) // $ hasValueFlow="call to FunctionWithSliceParameter" + sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ hasValueFlow="call to FunctionWithVarArgsParameter" + sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ hasValueFlow="call to FunctionWithVarArgsParameter" + + var out1 *string + var out2 *string + test.FunctionWithVarArgsOutParameter(source(), out1, out2) + sink(out1) // $ MISSING: hasValueFlow="out1" + sink(out2) // $ MISSING: hasValueFlow="out2" + + sliceOfStructs := []test.A{{Field: source()}} + sink(sliceOfStructs[0].Field) // $ hasValueFlow="selection of Field" + + a0 := test.A{Field: ""} + a1 := test.A{Field: source()} + aSlice := []test.A{a0, a1} + sink(test.FunctionWithSliceOfStructsParameter(aSlice)) // $ hasValueFlow="call to FunctionWithSliceOfStructsParameter" + sink(test.FunctionWithVarArgsOfStructsParameter(aSlice...)) // $ hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" + sink(test.FunctionWithVarArgsOfStructsParameter(a0, a1)) // $ hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" + + var variadicSource string + test.VariadicSource(&variadicSource) + sink(variadicSource) // $ MISSING: hasTaintFlow="variadicSource" + + test.VariadicSink(source()) // $ hasTaintFlow="[]type{args}" + +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go new file mode 100644 index 000000000000..f23bc1d04814 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go @@ -0,0 +1,31 @@ +package test + +type A struct { + Field string +} + +func FunctionWithParameter(s string) string { + return "" +} + +func FunctionWithSliceParameter(s []string) string { + return "" +} + +func FunctionWithVarArgsParameter(s ...string) string { + return "" +} +func FunctionWithVarArgsOutParameter(in string, out ...*string) { +} + +func FunctionWithSliceOfStructsParameter(s []A) string { + return "" +} + +func FunctionWithVarArgsOfStructsParameter(s ...A) string { + return "" +} + +func VariadicSource(s ...*string) {} + +func VariadicSink(s ...string) {} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt new file mode 100644 index 000000000000..b62dbf8819b5 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt @@ -0,0 +1,3 @@ +# github.com/nonexistent/test v0.0.0-20200203000000-0000000000000 +## explicit +github.com/nonexistent/test From 67572712ea53c27657abf0f5b34176a901910489 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 14:54:23 +0000 Subject: [PATCH 110/213] Fix flow out of varargs param with models-as-data This still doesn't allow for a variadic out parameter to be defined as a source using MaD. This is due to the lack of an implicit store step at sources, to match implicit read steps at sinks. --- go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll | 5 +++++ go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll | 3 +++ .../semmle/go/dataflow/VarArgsWithExternalFlow/main.go | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll b/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll index 9f07693b7ea2..bbef53935ad9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll @@ -66,6 +66,11 @@ predicate containerReadStep(Node node1, Node node2, Content c) { ( node2.(Read).readsElement(node1, _) or + exists(ImplicitVarargsSlice ivs | + node1.(PostUpdateNode).getPreUpdateNode() = ivs and + node2.(PostUpdateNode).getPreUpdateNode() = ivs.getCallNode().getAnImplicitVarargsArgument() + ) + or node2.(RangeElementNode).getBase() = node1 or // To model data flow from array elements of the base of a `SliceNode` to diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index cc353ab64df5..05283454cff0 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -845,6 +845,9 @@ module Public { or preupd = getAWrittenNode() or + preupd instanceof ImplicitVarargsSlice and + mutableType(preupd.(ImplicitVarargsSlice).getType().(SliceType).getElementType()) + or preupd = any(ArgumentNode arg).getACorrespondingSyntacticArgument() and mutableType(preupd.getType()) ) and diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go index 324864edd229..f90f429b12a4 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go @@ -29,8 +29,8 @@ func main() { var out1 *string var out2 *string test.FunctionWithVarArgsOutParameter(source(), out1, out2) - sink(out1) // $ MISSING: hasValueFlow="out1" - sink(out2) // $ MISSING: hasValueFlow="out2" + sink(out1) // $ hasValueFlow="out1" + sink(out2) // $ hasValueFlow="out2" sliceOfStructs := []test.A{{Field: source()}} sink(sliceOfStructs[0].Field) // $ hasValueFlow="selection of Field" From 75331ea2689b34a3965a1c63ca65a8b47be0488d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 15:03:34 +0000 Subject: [PATCH 111/213] Add change note --- .../2024-12-06-improve-flow-out-of-variadic-parameter.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2024-12-06-improve-flow-out-of-variadic-parameter.md diff --git a/go/ql/lib/change-notes/2024-12-06-improve-flow-out-of-variadic-parameter.md b/go/ql/lib/change-notes/2024-12-06-improve-flow-out-of-variadic-parameter.md new file mode 100644 index 000000000000..8244ba069943 --- /dev/null +++ b/go/ql/lib/change-notes/2024-12-06-improve-flow-out-of-variadic-parameter.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Data flow out of variadic parameters now works in more situations. Summary models defined using models-as-data work. Source models defined using models-as-data do not work yet. From c51153203b42d679f86f3472dd374c9b681ce7d8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 13:48:47 +0000 Subject: [PATCH 112/213] C++: Fix two bad joins that happen in 'UnboundedWrite' on #18207. --- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 29 +++++++++++++------ .../cpp/ir/dataflow/internal/SsaInternals.qll | 1 + 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index d0935bb76d2e..32dec1355ea9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -2275,6 +2275,12 @@ private predicate guardControlsPhiInput( */ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch); +bindingset[g, n] +pragma[inline_late] +private predicate controls(IRGuardCondition g, Node n, boolean edge) { + g.controls(n.getBasicBlock(), edge) +} + /** * Provides a set of barrier nodes for a guard that validates an expression. * @@ -2318,15 +2324,17 @@ module BarrierGuard { exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge | e = value.getAnInstruction().getConvertedResultExpression() and result.asConvertedExpr() = e and - guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and - g.controls(result.getBasicBlock(), edge) + guardChecks(g, + pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and + controls(g, result, edge) ) or exists( IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi | guardChecks(g, def.getARead().asOperand().getDef().getConvertedResultExpression(), branch) and - guardControlsPhiInput(g, branch, def, input, phi) and + guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input), + pragma[only_bind_into](phi)) and result = TSsaPhiInputNode(phi, input) ) } @@ -2404,8 +2412,9 @@ module BarrierGuard { exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge | e = value.getAnInstruction().getConvertedResultExpression() and result.asIndirectConvertedExpr(indirectionIndex) = e and - guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and - g.controls(result.getBasicBlock(), edge) + guardChecks(g, + pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and + controls(g, result, edge) ) or exists( @@ -2414,7 +2423,8 @@ module BarrierGuard { guardChecks(g, def.getARead().asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(), branch) and - guardControlsPhiInput(g, branch, def, input, phi) and + guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input), + pragma[only_bind_into](phi)) and result = TSsaPhiInputNode(phi, input) ) } @@ -2443,17 +2453,18 @@ module InstructionBarrierGuard Date: Fri, 6 Dec 2024 15:18:03 +0000 Subject: [PATCH 113/213] C#: Accept test changes. --- .../test/library-tests/dataflow/library/FlowSummaries.expected | 2 +- .../dataflow/library/FlowSummariesFiltered.expected | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 25e4a9317ebd..a7c87af0bfe0 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -1513,7 +1513,7 @@ summary | Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | | Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | | Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | -| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];taint;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(System.Object,System.Type,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[4];Argument[4].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,System.Func);Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 4d315854b67c..1d6443748b86 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -562,7 +562,7 @@ | Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | | Microsoft.AspNetCore.Mvc;Controller;View;(System.String);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | | Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewBag];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | -| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];taint;manual | +| Microsoft.AspNetCore.Mvc;Controller;View;(System.String,System.Object);Argument[this].Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];ReturnValue.Property[Microsoft.AspNetCore.Mvc.Controller.ViewData].Element.Property[System.Collections.Generic.KeyValuePair`2.Value];value;manual | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(System.Object,System.Type,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[4];Argument[4].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider,System.Func);Argument[3];Argument[3].Parameter[delegate-self];value;hq-generated | | Microsoft.AspNetCore.Mvc;ControllerBase;TryUpdateModelAsync;(TModel,System.String,System.Func);Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated | From d0bf3b84e4c263789324ae4f8cb33ca70fedb009 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 15:27:17 +0000 Subject: [PATCH 114/213] C++: Add missing MaD row for move constructor. --- cpp/ql/lib/ext/CComBSTR.model.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/lib/ext/CComBSTR.model.yml b/cpp/ql/lib/ext/CComBSTR.model.yml index b578956edec2..0cbf021a8a9f 100644 --- a/cpp/ql/lib/ext/CComBSTR.model.yml +++ b/cpp/ql/lib/ext/CComBSTR.model.yml @@ -8,6 +8,7 @@ extensions: - ["", "CComBSTR", True, "CComBSTR", "(int,LPCSTR)", "", "Argument[*1]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "CComBSTR", "(int,LPCOLESTR)", "", "Argument[*1]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "CComBSTR", "(const CComBSTR&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "CComBSTR", "(CComBSTR &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "Append", "(const CComBSTR&)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "Append", "(wchar_t)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "Append", "(char)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] From 904db38a5f3fae9580968a39fbbac3768c7f444b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 15:29:13 +0000 Subject: [PATCH 115/213] C++: Add missing space between type name and '&'. --- cpp/ql/lib/ext/CComBSTR.model.yml | 4 ++-- cpp/ql/lib/ext/CComSafeArray.model.yml | 4 ++-- cpp/ql/lib/ext/CPathT.model.yml | 4 ++-- cpp/ql/lib/ext/CRegKey.model.yml | 4 ++-- .../dataflow/external-models/flow.expected | 10 ++++----- .../external-models/validatemodels.expected | 8 +++---- .../taint-tests/test_mad-signatures.expected | 22 ++++++++++++++----- 7 files changed, 33 insertions(+), 23 deletions(-) diff --git a/cpp/ql/lib/ext/CComBSTR.model.yml b/cpp/ql/lib/ext/CComBSTR.model.yml index 0cbf021a8a9f..d281eb32dfb0 100644 --- a/cpp/ql/lib/ext/CComBSTR.model.yml +++ b/cpp/ql/lib/ext/CComBSTR.model.yml @@ -7,9 +7,9 @@ extensions: - ["", "CComBSTR", True, "CComBSTR", "(LPCOLESTR)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "CComBSTR", "(int,LPCSTR)", "", "Argument[*1]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "CComBSTR", "(int,LPCOLESTR)", "", "Argument[*1]", "Argument[-1]", "value", "manual"] - - ["", "CComBSTR", True, "CComBSTR", "(const CComBSTR&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CComBSTR", True, "CComBSTR", "(const CComBSTR &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "CComBSTR", "(CComBSTR &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - - ["", "CComBSTR", True, "Append", "(const CComBSTR&)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "Append", "(const CComBSTR &)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "Append", "(wchar_t)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "Append", "(char)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "Append", "(LPCOLESTR)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] diff --git a/cpp/ql/lib/ext/CComSafeArray.model.yml b/cpp/ql/lib/ext/CComSafeArray.model.yml index 4128ae13e177..8da350ff140a 100644 --- a/cpp/ql/lib/ext/CComSafeArray.model.yml +++ b/cpp/ql/lib/ext/CComSafeArray.model.yml @@ -21,7 +21,7 @@ extensions: - ["", "CComSafeArray", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Field[*m_psa].Field[*@pvData]", "value", "manual"] - ["", "CComSafeArray", True, "operator LPSAFEARRAY", "", "", "Argument[-1].Field[*m_psa]", "ReturnValue[*]", "value", "manual"] - ["", "CComSafeArray", True, "operator[]", "", "", "Argument[-1].Field[*m_psa].Field[*@pvData]", "ReturnValue[*@]", "value", "manual"] - - ["", "CComSafeArray", True, "operator=", "(const CComSafeArray&)", "", "Argument[*0].Field[*m_psa]", "ReturnValue[*]", "value", "manual"] - - ["", "CComSafeArray", True, "operator=", "(const CComSafeArray&)", "", "Argument[*0].Field[*m_psa]", "Argument[-1].Field[*m_psa]", "value", "manual"] + - ["", "CComSafeArray", True, "operator=", "(const CComSafeArray &)", "", "Argument[*0].Field[*m_psa]", "ReturnValue[*]", "value", "manual"] + - ["", "CComSafeArray", True, "operator=", "(const CComSafeArray &)", "", "Argument[*0].Field[*m_psa]", "Argument[-1].Field[*m_psa]", "value", "manual"] - ["", "CComSafeArray", True, "operator=", "(const SAFEARRAY *)", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] - ["", "CComSafeArray", True, "operator=", "(const SAFEARRAY *)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/lib/ext/CPathT.model.yml b/cpp/ql/lib/ext/CPathT.model.yml index 8211343d479e..870e7ac55360 100644 --- a/cpp/ql/lib/ext/CPathT.model.yml +++ b/cpp/ql/lib/ext/CPathT.model.yml @@ -15,8 +15,8 @@ extensions: - ["", "CPathT", True, "RelativePathTo", "", "", "Argument[*2]", "ReturnValue[-1]", "taint", "manual"] - ["", "CPathT", True, "RenameExtension", "", "", "Argument[*0]", "ReturnValue[-1]", "taint", "manual"] # Note: These don't work currently since we cannot use the template parameter in the name of the function - # - ["", "CPathT", True, "operator const T&", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - # - ["", "CPathT", True, "operator T&", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] + # - ["", "CPathT", True, "operator const T &", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] + # - ["", "CPathT", True, "operator T &", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - ["", "CPathT", True, "operator PCXSTR", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - ["", "CPathT", True, "operator+=", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] - ["", "CPathT", True, "operator+=", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"] diff --git a/cpp/ql/lib/ext/CRegKey.model.yml b/cpp/ql/lib/ext/CRegKey.model.yml index 52b742029ac5..45114347ee0d 100644 --- a/cpp/ql/lib/ext/CRegKey.model.yml +++ b/cpp/ql/lib/ext/CRegKey.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/cpp-all extensible: summaryModel data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance - - ["", "CRegKey", True, "CRegKey", "(CRegKey&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["", "CRegKey", True, "CRegKey", "(CRegKey &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CRegKey", True, "CRegKey", "(HKEY)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CRegKey", True, "Attach", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CRegKey", True, "QueryBinaryValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] @@ -12,7 +12,7 @@ extensions: - ["", "CRegKey", True, "QueryQWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"] - - ["", "CRegKey", True, "QueryValue", "(DWORD&,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] + - ["", "CRegKey", True, "QueryValue", "(DWORD &,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[**0]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "operator HKEY", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] 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 81a9c605f005..137642d522a4 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:800 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:798 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:799 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:801 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:799 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:800 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:799 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:800 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:800 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:801 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index 39dade253254..7b089db8a6d2 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -11,14 +11,14 @@ | Dubious member name "operator=" in summary model. | | Dubious member name "operator[]" in summary model. | | Dubious signature "(CAtlFile &)" in summary model. | -| Dubious signature "(CRegKey&)" in summary model. | -| Dubious signature "(DWORD&,LPCTSTR)" in summary model. | +| Dubious signature "(CComBSTR &&)" in summary model. | +| Dubious signature "(CRegKey &)" in summary model. | +| Dubious signature "(DWORD &,LPCTSTR)" in summary model. | | Dubious signature "(InputIterator,InputIterator,const Allocator &)" in summary model. | | Dubious signature "(LPCTSTR,DWORD *,void *,ULONG *)" in summary model. | | Dubious signature "(LPTSTR,LPCTSTR,DWORD *)" in summary model. | -| Dubious signature "(const CComBSTR&)" in summary model. | +| Dubious signature "(const CComBSTR &)" in summary model. | | Dubious signature "(const CComSafeArray &)" in summary model. | -| Dubious signature "(const CComSafeArray&)" in summary model. | | Dubious signature "(const SAFEARRAY &)" in summary model. | | Dubious signature "(const SAFEARRAY *)" in summary model. | | Dubious signature "(const SAFEARRAYBOUND *,UINT)" in summary model. | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 9284dc759eb1..f1e4b841d870 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -6,6 +6,10 @@ signatureMatches | atl.cpp:257:3:257:10 | CAtlList | (UINT) | CComBSTR | LoadString | 0 | | atl.cpp:257:3:257:10 | CAtlList | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | | atl.cpp:257:3:257:10 | CAtlList | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:407:8:407:8 | operator= | (const CComBSTR &) | CComBSTR | Append | 0 | +| atl.cpp:407:8:407:8 | operator= | (const CComBSTR &) | CComBSTR | CComBSTR | 0 | +| atl.cpp:409:3:409:10 | CComBSTR | (const CComBSTR &) | CComBSTR | Append | 0 | +| atl.cpp:409:3:409:10 | CComBSTR | (const CComBSTR &) | CComBSTR | CComBSTR | 0 | | atl.cpp:411:3:411:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 0 | | atl.cpp:411:3:411:10 | CComBSTR | (int,LPCOLESTR) | CComBSTR | CComBSTR | 1 | | atl.cpp:412:3:412:10 | CComBSTR | (int,LPCSTR) | CComBSTR | CComBSTR | 0 | @@ -14,6 +18,9 @@ signatureMatches | atl.cpp:413:3:413:10 | CComBSTR | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | | atl.cpp:414:3:414:10 | CComBSTR | (LPCSTR) | CComBSTR | Append | 0 | | atl.cpp:414:3:414:10 | CComBSTR | (LPCSTR) | CComBSTR | CComBSTR | 0 | +| atl.cpp:415:3:415:10 | CComBSTR | (CComBSTR &&) | CComBSTR | CComBSTR | 0 | +| atl.cpp:418:11:418:16 | Append | (const CComBSTR &) | CComBSTR | Append | 0 | +| atl.cpp:418:11:418:16 | Append | (const CComBSTR &) | CComBSTR | CComBSTR | 0 | | atl.cpp:419:11:419:16 | Append | (wchar_t) | CComBSTR | Append | 0 | | atl.cpp:420:11:420:16 | Append | (char) | CComBSTR | Append | 0 | | atl.cpp:421:11:421:16 | Append | (LPCOLESTR) | CComBSTR | Append | 0 | @@ -31,6 +38,8 @@ signatureMatches | atl.cpp:438:8:438:17 | LoadString | (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 1 | | atl.cpp:439:8:439:17 | LoadString | (UINT) | CComBSTR | LoadString | 0 | | atl.cpp:439:8:439:17 | LoadString | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | +| atl.cpp:447:13:447:22 | operator+= | (const CComBSTR &) | CComBSTR | Append | 0 | +| atl.cpp:447:13:447:22 | operator+= | (const CComBSTR &) | CComBSTR | CComBSTR | 0 | | atl.cpp:448:13:448:22 | operator+= | (LPCOLESTR) | CComBSTR | Append | 0 | | atl.cpp:448:13:448:22 | operator+= | (LPCOLESTR) | CComBSTR | CComBSTR | 0 | | atl.cpp:538:3:538:15 | CComSafeArray | (const SAFEARRAY *) | CComSafeArray | Add | 0 | @@ -357,9 +366,10 @@ signatureMatches | vector.cpp:333:6:333:35 | vector_iterator_assign_wrapper | (LPCOLESTR,int) | CComBSTR | Append | 1 | getSignatureParameterName | (CAtlFile &) | CAtlFile | CAtlFile | 0 | CAtlFile & | -| (CRegKey&) | CRegKey | CRegKey | 0 | CRegKey& | -| (DWORD&,LPCTSTR) | CRegKey | QueryValue | 0 | DWORD& | -| (DWORD&,LPCTSTR) | CRegKey | QueryValue | 1 | LPCTSTR | +| (CComBSTR &&) | CComBSTR | CComBSTR | 0 | CComBSTR && | +| (CRegKey &) | CRegKey | CRegKey | 0 | CRegKey & | +| (DWORD &,LPCTSTR) | CRegKey | QueryValue | 0 | DWORD & | +| (DWORD &,LPCTSTR) | CRegKey | QueryValue | 1 | LPCTSTR | | (HANDLE) | CAtlFile | CAtlFile | 0 | HANDLE | | (HINSTANCE,UINT) | CComBSTR | LoadString | 0 | HINSTANCE | | (HINSTANCE,UINT) | CComBSTR | LoadString | 1 | UINT | @@ -401,10 +411,10 @@ getSignatureParameterName | (UINT) | CComBSTR | LoadString | 0 | UINT | | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | UINT | | (char) | CComBSTR | Append | 0 | char | -| (const CComBSTR&) | CComBSTR | Append | 0 | const CComBSTR& | -| (const CComBSTR&) | CComBSTR | CComBSTR | 0 | const CComBSTR& | +| (const CComBSTR &) | CComBSTR | Append | 0 | const CComBSTR & | +| (const CComBSTR &) | CComBSTR | CComBSTR | 0 | const CComBSTR & | | (const CComSafeArray &) | CComSafeArray | CComSafeArray | 0 | const CComSafeArray & | -| (const CComSafeArray&) | CComSafeArray | operator= | 0 | const CComSafeArray& | +| (const CComSafeArray &) | CComSafeArray | operator= | 0 | const CComSafeArray & | | (const SAFEARRAY &) | CComSafeArray | CComSafeArray | 0 | const SAFEARRAY & | | (const SAFEARRAY *) | CComSafeArray | Add | 0 | const SAFEARRAY * | | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | const SAFEARRAY * | From 4024968e46a1a0d55ccdd64cda036ab66a73abf2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:30:02 +0000 Subject: [PATCH 116/213] Rust: Accept integration test changes. --- rust/ql/integration-tests/hello-project/summary.expected | 1 + rust/ql/integration-tests/hello-workspace/summary.cargo.expected | 1 + .../hello-workspace/summary.rust-project.expected | 1 + 3 files changed, 3 insertions(+) diff --git a/rust/ql/integration-tests/hello-project/summary.expected b/rust/ql/integration-tests/hello-project/summary.expected index 44c14e790fe3..6912eb2c52d8 100644 --- a/rust/ql/integration-tests/hello-project/summary.expected +++ b/rust/ql/integration-tests/hello-project/summary.expected @@ -5,6 +5,7 @@ | Files extracted - total | 5 | | Files extracted - with errors | 1 | | Files extracted - without errors | 4 | +| Files extracted - without errors % | 100 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 0 | diff --git a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected index ec1abea6252b..27545551f123 100644 --- a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected @@ -5,6 +5,7 @@ | Files extracted - total | 4 | | Files extracted - with errors | 0 | | Files extracted - without errors | 4 | +| Files extracted - without errors % | 100 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 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 index 5ca38e5a90ce..40992231f2bd 100644 --- a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected @@ -5,6 +5,7 @@ | Files extracted - total | 4 | | Files extracted - with errors | 0 | | Files extracted - without errors | 4 | +| Files extracted - without errors % | 100 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 0 | From f7b55e05ebcc1163e7a725043b6d7aa6e29100fc Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 15:30:34 +0000 Subject: [PATCH 117/213] C++: 'Attach' is value-preserving. --- cpp/ql/lib/ext/CComBSTR.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/ext/CComBSTR.model.yml b/cpp/ql/lib/ext/CComBSTR.model.yml index d281eb32dfb0..7ee43290ba31 100644 --- a/cpp/ql/lib/ext/CComBSTR.model.yml +++ b/cpp/ql/lib/ext/CComBSTR.model.yml @@ -19,7 +19,7 @@ extensions: - ["", "CComBSTR", True, "AppendBSTR", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "ArrayToBSTR", "", "", "Argument[*0].Field[*pvData]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "AssignBSTR", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - - ["", "CComBSTR", True, "Attach", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] + - ["", "CComBSTR", True, "Attach", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "BSTRToArray", "", "", "Argument[-1]", "Argument[*0].Field[*pvData]", "value", "manual"] - ["", "CComBSTR", True, "Copy", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - ["", "CComBSTR", True, "CopyTo", "", "", "Argument[-1]", "Argument[*0]", "value", "manual"] From 6388a9af95051c49f484be6f296f8ad3b9c0a248 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 15:31:33 +0000 Subject: [PATCH 118/213] C++: Delete duplicated MaD row. --- cpp/ql/lib/ext/CComBSTR.model.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/ql/lib/ext/CComBSTR.model.yml b/cpp/ql/lib/ext/CComBSTR.model.yml index 7ee43290ba31..cd3cd7b50756 100644 --- a/cpp/ql/lib/ext/CComBSTR.model.yml +++ b/cpp/ql/lib/ext/CComBSTR.model.yml @@ -26,7 +26,6 @@ extensions: - ["", "CComBSTR", True, "LoadString", "(HINSTANCE,UINT)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "LoadString", "(UINT)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "ReadFromStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - - ["", "CComBSTR", True, "ReadFromStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "WriteToStream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"] - ["", "CComBSTR", True, "operator BSTR", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] - ["", "CComBSTR", True, "operator&", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] From 66de42c576d64425456db4b7c7b1d45c085f18f8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 15:33:29 +0000 Subject: [PATCH 119/213] C++: Fix MaD row for 'operator&' on 'CComBSTR's. --- cpp/ql/lib/ext/CComBSTR.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/ext/CComBSTR.model.yml b/cpp/ql/lib/ext/CComBSTR.model.yml index cd3cd7b50756..1865a244ef30 100644 --- a/cpp/ql/lib/ext/CComBSTR.model.yml +++ b/cpp/ql/lib/ext/CComBSTR.model.yml @@ -28,6 +28,6 @@ extensions: - ["", "CComBSTR", True, "ReadFromStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] - ["", "CComBSTR", True, "WriteToStream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"] - ["", "CComBSTR", True, "operator BSTR", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"] - - ["", "CComBSTR", True, "operator&", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CComBSTR", True, "operator&", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - ["", "CComBSTR", True, "operator+=", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"] - ["", "CComBSTR", True, "operator+=", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"] \ No newline at end of file From 5aa604b42ce687ff2e0aacf9a800acd6b5c1382a Mon Sep 17 00:00:00 2001 From: Calum Grant <42069085+calumgrant@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:34:57 +0000 Subject: [PATCH 120/213] Update cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md b/cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md index df9e13c07046..1bf77d55a618 100644 --- a/cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md +++ b/cpp/ql/src/change-notes/2024-12-05-wrong-type-format-args.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The "Wrong type of arguments to formatting function" query (`cpp/wrong-type-format-argument`) query no longer produces results when a string type has an extraction error. +* The "Wrong type of arguments to formatting function" query (`cpp/wrong-type-format-argument`) no longer produces results when an argument type has an extraction error. From e98129c402b2250b0cd0dfa0a08ab8124655a67c Mon Sep 17 00:00:00 2001 From: Calum Grant <42069085+calumgrant@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:36:24 +0000 Subject: [PATCH 121/213] Update cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md b/cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md index 2004cd08248e..c7ddd104ad0e 100644 --- a/cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md +++ b/cpp/ql/src/change-notes/2024-12-05-badly-bounded-write.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The "Badly bounded write" query (`cpp/badly-bounded-write`) query no longer produces results if there is an extraction error in the type of the output buffer. +* The "Badly bounded write" query (`cpp/badly-bounded-write`) no longer produces results if there is an extraction error in the type of the output buffer. From 7e5e634bc7504b663b5fb33a7953ff1ed4e1a2e6 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 6 Dec 2024 15:41:28 +0000 Subject: [PATCH 122/213] Update .expected files (no new results) --- .../go/frameworks/BeegoOrm/StoredXss.expected | 6 +++ .../Security/CWE-078/StoredCommand.expected | 3 ++ .../Security/CWE-079/ReflectedXss.expected | 39 ++++++++++++++ .../Security/CWE-079/StoredXss.expected | 7 +++ .../Security/CWE-089/SqlInjection.expected | 9 ++++ .../Security/CWE-089/StringBreak.expected | 8 +++ .../CWE-209/StackTraceExposure.expected | 8 +++ .../CWE-312/CleartextLogging.expected | 53 +++++++++++++++++++ .../Security/CWE-640/EmailInjection.expected | 36 +++++++++++++ 9 files changed, 169 insertions(+) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected index 861e3e97ed14..7524dd0f4108 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.expected @@ -24,7 +24,11 @@ edges | test.go:148:16:148:23 | &... | test.go:149:13:149:39 | type conversion | provenance | | | test.go:152:15:152:24 | &... | test.go:153:13:153:47 | type conversion | provenance | | | test.go:156:18:156:30 | &... | test.go:157:13:157:38 | type conversion | provenance | | +| test.go:160:2:160:23 | []type{args} [array] | test.go:160:14:160:22 | &... | provenance | | +| test.go:160:14:160:22 | &... | test.go:160:2:160:23 | []type{args} [array] | provenance | | | test.go:160:14:160:22 | &... | test.go:161:13:161:28 | type conversion | provenance | | +| test.go:164:2:164:25 | []type{args} [array] | test.go:164:15:164:24 | &... | provenance | | +| test.go:164:15:164:24 | &... | test.go:164:2:164:25 | []type{args} [array] | provenance | | | test.go:164:15:164:24 | &... | test.go:165:13:165:32 | type conversion | provenance | | nodes | test.go:80:13:80:16 | &... | semmle.label | &... | @@ -76,8 +80,10 @@ nodes | test.go:153:13:153:47 | type conversion | semmle.label | type conversion | | test.go:156:18:156:30 | &... | semmle.label | &... | | test.go:157:13:157:38 | type conversion | semmle.label | type conversion | +| test.go:160:2:160:23 | []type{args} [array] | semmle.label | []type{args} [array] | | test.go:160:14:160:22 | &... | semmle.label | &... | | test.go:161:13:161:28 | type conversion | semmle.label | type conversion | +| test.go:164:2:164:25 | []type{args} [array] | semmle.label | []type{args} [array] | | test.go:164:15:164:24 | &... | semmle.label | &... | | test.go:165:13:165:32 | type conversion | semmle.label | type conversion | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected index 12be518a98b9..a0b34cd05b47 100644 --- a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected +++ b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected @@ -3,12 +3,15 @@ edges | StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:13:2:13:5 | rows | provenance | | | StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:12:13:19 | &... | provenance | FunctionModel | +| StoredCommand.go:13:2:13:20 | []type{args} [array] | StoredCommand.go:13:12:13:19 | &... | provenance | | +| StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:13:2:13:20 | []type{args} [array] | provenance | | | StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:14:22:14:28 | cmdName | provenance | Sink:MaD:1 | models | 1 | Sink: os/exec; ; false; Command; ; ; Argument[0]; command-injection; manual | nodes | StoredCommand.go:11:2:11:27 | ... := ...[0] | semmle.label | ... := ...[0] | | StoredCommand.go:13:2:13:5 | rows | semmle.label | rows | +| StoredCommand.go:13:2:13:20 | []type{args} [array] | semmle.label | []type{args} [array] | | StoredCommand.go:13:12:13:19 | &... | semmle.label | &... | | StoredCommand.go:14:22:14:28 | cmdName | semmle.label | cmdName | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 647113f3c6b5..321b1740c23b 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -32,8 +32,10 @@ edges | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | provenance | Src:MaD:8 | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:32:34:32:37 | file | provenance | Src:MaD:7 | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:46:34:60 | selection of Filename | provenance | Src:MaD:7 | +| reflectedxsstest.go:32:2:32:8 | definition of content | reflectedxsstest.go:33:49:33:55 | content | provenance | | | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | reflectedxsstest.go:33:49:33:55 | content | provenance | | | reflectedxsstest.go:32:34:32:37 | file | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | provenance | MaD:13 | +| reflectedxsstest.go:33:17:33:56 | []type{args} [array] | reflectedxsstest.go:32:2:32:8 | definition of content | provenance | | | reflectedxsstest.go:33:17:33:56 | []type{args} [array] | reflectedxsstest.go:33:17:33:56 | call to Sprintf | provenance | MaD:12 | | reflectedxsstest.go:33:17:33:56 | call to Sprintf | reflectedxsstest.go:33:10:33:57 | type conversion | provenance | | | reflectedxsstest.go:33:49:33:55 | content | reflectedxsstest.go:33:17:33:56 | []type{args} [array] | provenance | | @@ -63,11 +65,33 @@ edges | tst.go:48:14:48:19 | selection of Form | tst.go:48:14:48:34 | call to Get | provenance | Src:MaD:6 MaD:18 | | tst.go:48:14:48:34 | call to Get | tst.go:53:12:53:26 | type conversion | provenance | | | websocketXss.go:30:7:30:10 | definition of xnet | websocketXss.go:32:24:32:27 | xnet | provenance | Src:MaD:5 | +| websocketXss.go:30:7:30:10 | definition of xnet | websocketXss.go:32:24:32:27 | xnet | provenance | Src:MaD:5 | +| websocketXss.go:32:3:32:28 | []type{args} [array] | websocketXss.go:30:7:30:10 | definition of xnet | provenance | | +| websocketXss.go:32:24:32:27 | xnet | websocketXss.go:32:3:32:28 | []type{args} [array] | provenance | | +| websocketXss.go:34:3:34:7 | definition of xnet2 | websocketXss.go:36:24:36:28 | xnet2 | provenance | Src:MaD:4 | | websocketXss.go:34:3:34:7 | definition of xnet2 | websocketXss.go:36:24:36:28 | xnet2 | provenance | Src:MaD:4 | +| websocketXss.go:36:3:36:29 | []type{args} [array] | websocketXss.go:34:3:34:7 | definition of xnet2 | provenance | | +| websocketXss.go:36:24:36:28 | xnet2 | websocketXss.go:36:3:36:29 | []type{args} [array] | provenance | | +| websocketXss.go:40:3:40:40 | ... := ...[1] | websocketXss.go:41:24:41:29 | nhooyr | provenance | Src:MaD:11 | | websocketXss.go:40:3:40:40 | ... := ...[1] | websocketXss.go:41:24:41:29 | nhooyr | provenance | Src:MaD:11 | +| websocketXss.go:40:6:40:11 | definition of nhooyr | websocketXss.go:41:24:41:29 | nhooyr | provenance | | +| websocketXss.go:40:6:40:11 | definition of nhooyr | websocketXss.go:41:24:41:29 | nhooyr | provenance | | +| websocketXss.go:41:3:41:30 | []type{args} [array] | websocketXss.go:40:6:40:11 | definition of nhooyr | provenance | | +| websocketXss.go:41:24:41:29 | nhooyr | websocketXss.go:41:3:41:30 | []type{args} [array] | provenance | | | websocketXss.go:46:7:46:16 | definition of gorillaMsg | websocketXss.go:48:24:48:33 | gorillaMsg | provenance | Src:MaD:1 | +| websocketXss.go:46:7:46:16 | definition of gorillaMsg | websocketXss.go:48:24:48:33 | gorillaMsg | provenance | Src:MaD:1 | +| websocketXss.go:48:3:48:34 | []type{args} [array] | websocketXss.go:46:7:46:16 | definition of gorillaMsg | provenance | | +| websocketXss.go:48:24:48:33 | gorillaMsg | websocketXss.go:48:3:48:34 | []type{args} [array] | provenance | | +| websocketXss.go:50:3:50:10 | definition of gorilla2 | websocketXss.go:52:24:52:31 | gorilla2 | provenance | Src:MaD:2 | | websocketXss.go:50:3:50:10 | definition of gorilla2 | websocketXss.go:52:24:52:31 | gorilla2 | provenance | Src:MaD:2 | +| websocketXss.go:52:3:52:32 | []type{args} [array] | websocketXss.go:50:3:50:10 | definition of gorilla2 | provenance | | +| websocketXss.go:52:24:52:31 | gorilla2 | websocketXss.go:52:3:52:32 | []type{args} [array] | provenance | | +| websocketXss.go:54:3:54:38 | ... := ...[1] | websocketXss.go:55:24:55:31 | gorilla3 | provenance | Src:MaD:3 | | websocketXss.go:54:3:54:38 | ... := ...[1] | websocketXss.go:55:24:55:31 | gorilla3 | provenance | Src:MaD:3 | +| websocketXss.go:54:6:54:13 | definition of gorilla3 | websocketXss.go:55:24:55:31 | gorilla3 | provenance | | +| websocketXss.go:54:6:54:13 | definition of gorilla3 | websocketXss.go:55:24:55:31 | gorilla3 | provenance | | +| websocketXss.go:55:3:55:32 | []type{args} [array] | websocketXss.go:54:6:54:13 | definition of gorilla3 | provenance | | +| websocketXss.go:55:24:55:31 | gorilla3 | websocketXss.go:55:3:55:32 | []type{args} [array] | provenance | | models | 1 | Source: github.com/gorilla/websocket; ; false; ReadJSON; ; ; Argument[1]; remote; manual | | 2 | Source: github.com/gorilla/websocket; Conn; true; ReadJSON; ; ; Argument[0]; remote; manual | @@ -108,6 +132,7 @@ nodes | contenttype.go:114:50:114:53 | data | semmle.label | data | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | semmle.label | ... := ...[1] | +| reflectedxsstest.go:32:2:32:8 | definition of content | semmle.label | definition of content | | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:32:34:32:37 | file | semmle.label | file | | reflectedxsstest.go:33:10:33:57 | type conversion | semmle.label | type conversion | @@ -142,15 +167,29 @@ nodes | tst.go:48:14:48:34 | call to Get | semmle.label | call to Get | | tst.go:53:12:53:26 | type conversion | semmle.label | type conversion | | websocketXss.go:30:7:30:10 | definition of xnet | semmle.label | definition of xnet | +| websocketXss.go:32:3:32:28 | []type{args} [array] | semmle.label | []type{args} [array] | +| websocketXss.go:32:24:32:27 | xnet | semmle.label | xnet | | websocketXss.go:32:24:32:27 | xnet | semmle.label | xnet | | websocketXss.go:34:3:34:7 | definition of xnet2 | semmle.label | definition of xnet2 | +| websocketXss.go:36:3:36:29 | []type{args} [array] | semmle.label | []type{args} [array] | +| websocketXss.go:36:24:36:28 | xnet2 | semmle.label | xnet2 | | websocketXss.go:36:24:36:28 | xnet2 | semmle.label | xnet2 | | websocketXss.go:40:3:40:40 | ... := ...[1] | semmle.label | ... := ...[1] | +| websocketXss.go:40:6:40:11 | definition of nhooyr | semmle.label | definition of nhooyr | +| websocketXss.go:41:3:41:30 | []type{args} [array] | semmle.label | []type{args} [array] | +| websocketXss.go:41:24:41:29 | nhooyr | semmle.label | nhooyr | | websocketXss.go:41:24:41:29 | nhooyr | semmle.label | nhooyr | | websocketXss.go:46:7:46:16 | definition of gorillaMsg | semmle.label | definition of gorillaMsg | +| websocketXss.go:48:3:48:34 | []type{args} [array] | semmle.label | []type{args} [array] | +| websocketXss.go:48:24:48:33 | gorillaMsg | semmle.label | gorillaMsg | | websocketXss.go:48:24:48:33 | gorillaMsg | semmle.label | gorillaMsg | | websocketXss.go:50:3:50:10 | definition of gorilla2 | semmle.label | definition of gorilla2 | +| websocketXss.go:52:3:52:32 | []type{args} [array] | semmle.label | []type{args} [array] | +| websocketXss.go:52:24:52:31 | gorilla2 | semmle.label | gorilla2 | | websocketXss.go:52:24:52:31 | gorilla2 | semmle.label | gorilla2 | | websocketXss.go:54:3:54:38 | ... := ...[1] | semmle.label | ... := ...[1] | +| websocketXss.go:54:6:54:13 | definition of gorilla3 | semmle.label | definition of gorilla3 | +| websocketXss.go:55:3:55:32 | []type{args} [array] | semmle.label | []type{args} [array] | +| websocketXss.go:55:24:55:31 | gorilla3 | semmle.label | gorilla3 | | websocketXss.go:55:24:55:31 | gorilla3 | semmle.label | gorilla3 | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected index efe98650a4e4..ebeedf3d0ef7 100644 --- a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -1,7 +1,12 @@ edges | StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | provenance | | | stored.go:18:3:18:28 | ... := ...[0] | stored.go:25:14:25:17 | rows | provenance | | +| stored.go:25:14:25:17 | rows | stored.go:25:24:25:26 | &... | provenance | FunctionModel | | stored.go:25:14:25:17 | rows | stored.go:25:29:25:33 | &... | provenance | FunctionModel | +| stored.go:25:14:25:34 | []type{args} [array] | stored.go:25:24:25:26 | &... | provenance | | +| stored.go:25:14:25:34 | []type{args} [array] | stored.go:25:29:25:33 | &... | provenance | | +| stored.go:25:24:25:26 | &... | stored.go:25:14:25:34 | []type{args} [array] | provenance | | +| stored.go:25:29:25:33 | &... | stored.go:25:14:25:34 | []type{args} [array] | provenance | | | stored.go:25:29:25:33 | &... | stored.go:30:22:30:25 | name | provenance | | | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | provenance | | nodes @@ -9,6 +14,8 @@ nodes | StoredXss.go:13:21:13:36 | ...+... | semmle.label | ...+... | | stored.go:18:3:18:28 | ... := ...[0] | semmle.label | ... := ...[0] | | stored.go:25:14:25:17 | rows | semmle.label | rows | +| stored.go:25:14:25:34 | []type{args} [array] | semmle.label | []type{args} [array] | +| stored.go:25:24:25:26 | &... | semmle.label | &... | | stored.go:25:29:25:33 | &... | semmle.label | &... | | stored.go:30:22:30:25 | name | semmle.label | name | | stored.go:59:30:59:33 | definition of path | semmle.label | definition of path | diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 1ce8c3d1dcf6..9a7084ac8369 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -26,6 +26,7 @@ | mongoDB.go:81:18:81:25 | pipeline | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:81:18:81:25 | pipeline | This query depends on a $@. | mongoDB.go:40:20:40:30 | call to Referer | user-provided value | edges | SqlInjection.go:10:7:11:30 | []type{args} [array] | SqlInjection.go:10:7:11:30 | call to Sprintf | provenance | MaD:23 | +| SqlInjection.go:10:7:11:30 | []type{args} [array] | SqlInjection.go:11:3:11:29 | index expression | provenance | | | SqlInjection.go:10:7:11:30 | call to Sprintf | SqlInjection.go:12:11:12:11 | q | provenance | Sink:MaD:1 | | SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:11:3:11:17 | call to Query | provenance | Src:MaD:21 MaD:26 | | SqlInjection.go:11:3:11:17 | call to Query | SqlInjection.go:11:3:11:29 | index expression | provenance | | @@ -36,6 +37,7 @@ edges | issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... | provenance | MaD:22 | | issue48.go:18:20:18:39 | &... | issue48.go:21:3:21:33 | index expression | provenance | | | issue48.go:20:8:21:34 | []type{args} [array] | issue48.go:20:8:21:34 | call to Sprintf | provenance | MaD:23 | +| issue48.go:20:8:21:34 | []type{args} [array] | issue48.go:21:3:21:33 | index expression | provenance | | | issue48.go:20:8:21:34 | call to Sprintf | issue48.go:22:11:22:12 | q3 | provenance | Sink:MaD:1 | | issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | []type{args} [array] | provenance | | | issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | call to Sprintf | provenance | FunctionModel | @@ -44,6 +46,7 @@ edges | issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... | provenance | MaD:22 | | issue48.go:28:21:28:41 | &... | issue48.go:31:3:31:31 | selection of Category | provenance | | | issue48.go:30:8:31:32 | []type{args} [array] | issue48.go:30:8:31:32 | call to Sprintf | provenance | MaD:23 | +| issue48.go:30:8:31:32 | []type{args} [array] | issue48.go:31:3:31:31 | selection of Category | provenance | | | issue48.go:30:8:31:32 | call to Sprintf | issue48.go:32:11:32:12 | q4 | provenance | Sink:MaD:1 | | issue48.go:31:3:31:31 | selection of Category | issue48.go:30:8:31:32 | []type{args} [array] | provenance | | | issue48.go:31:3:31:31 | selection of Category | issue48.go:30:8:31:32 | call to Sprintf | provenance | FunctionModel | @@ -52,11 +55,13 @@ edges | issue48.go:37:24:37:38 | call to Query | issue48.go:37:17:37:50 | type conversion | provenance | | | issue48.go:37:53:37:73 | &... | issue48.go:40:3:40:31 | selection of Category | provenance | | | issue48.go:39:8:40:32 | []type{args} [array] | issue48.go:39:8:40:32 | call to Sprintf | provenance | MaD:23 | +| issue48.go:39:8:40:32 | []type{args} [array] | issue48.go:40:3:40:31 | selection of Category | provenance | | | issue48.go:39:8:40:32 | call to Sprintf | issue48.go:41:11:41:12 | q5 | provenance | Sink:MaD:1 | | issue48.go:40:3:40:31 | selection of Category | issue48.go:39:8:40:32 | []type{args} [array] | provenance | | | issue48.go:40:3:40:31 | selection of Category | issue48.go:39:8:40:32 | call to Sprintf | provenance | FunctionModel | | main.go:11:11:11:16 | selection of Form | main.go:11:11:11:28 | index expression | provenance | Src:MaD:18 Sink:MaD:1 | | main.go:15:11:15:84 | []type{args} [array] | main.go:15:11:15:84 | call to Sprintf | provenance | MaD:23 Sink:MaD:2 | +| main.go:15:11:15:84 | []type{args} [array] | main.go:15:63:15:83 | index expression | provenance | | | main.go:15:63:15:67 | selection of URL | main.go:15:63:15:75 | call to Query | provenance | Src:MaD:21 MaD:26 | | main.go:15:63:15:75 | call to Query | main.go:15:63:15:83 | index expression | provenance | | | main.go:15:63:15:83 | index expression | main.go:15:11:15:84 | []type{args} [array] | provenance | | @@ -71,6 +76,7 @@ edges | main.go:30:13:30:27 | call to Query | main.go:30:13:30:39 | index expression | provenance | | | main.go:30:13:30:39 | index expression | main.go:28:18:31:2 | struct literal [Category] | provenance | | | main.go:33:7:34:23 | []type{args} [array] | main.go:33:7:34:23 | call to Sprintf | provenance | MaD:23 | +| main.go:33:7:34:23 | []type{args} [array] | main.go:34:3:34:22 | selection of Category | provenance | | | main.go:33:7:34:23 | call to Sprintf | main.go:35:11:35:11 | q | provenance | Sink:MaD:1 | | main.go:34:3:34:13 | RequestData [pointer, Category] | main.go:34:3:34:13 | implicit dereference [Category] | provenance | | | main.go:34:3:34:13 | implicit dereference [Category] | main.go:34:3:34:22 | selection of Category | provenance | | @@ -84,6 +90,7 @@ edges | main.go:40:25:40:39 | call to Query | main.go:40:25:40:51 | index expression | provenance | | | main.go:40:25:40:51 | index expression | main.go:40:2:40:12 | implicit dereference [Category] | provenance | | | main.go:42:7:43:23 | []type{args} [array] | main.go:42:7:43:23 | call to Sprintf | provenance | MaD:23 | +| main.go:42:7:43:23 | []type{args} [array] | main.go:43:3:43:22 | selection of Category | provenance | | | main.go:42:7:43:23 | call to Sprintf | main.go:44:11:44:11 | q | provenance | Sink:MaD:1 | | main.go:43:3:43:13 | RequestData [pointer, Category] | main.go:43:3:43:13 | implicit dereference [Category] | provenance | | | main.go:43:3:43:13 | implicit dereference [Category] | main.go:43:3:43:22 | selection of Category | provenance | | @@ -97,6 +104,7 @@ edges | main.go:49:28:49:42 | call to Query | main.go:49:28:49:54 | index expression | provenance | | | main.go:49:28:49:54 | index expression | main.go:49:3:49:14 | star expression [Category] | provenance | | | main.go:51:7:52:23 | []type{args} [array] | main.go:51:7:52:23 | call to Sprintf | provenance | MaD:23 | +| main.go:51:7:52:23 | []type{args} [array] | main.go:52:3:52:22 | selection of Category | provenance | | | main.go:51:7:52:23 | call to Sprintf | main.go:53:11:53:11 | q | provenance | Sink:MaD:1 | | main.go:52:3:52:13 | RequestData [pointer, Category] | main.go:52:3:52:13 | implicit dereference [Category] | provenance | | | main.go:52:3:52:13 | implicit dereference [Category] | main.go:52:3:52:22 | selection of Category | provenance | | @@ -110,6 +118,7 @@ edges | main.go:58:28:58:42 | call to Query | main.go:58:28:58:54 | index expression | provenance | | | main.go:58:28:58:54 | index expression | main.go:58:3:58:14 | star expression [Category] | provenance | | | main.go:60:7:61:26 | []type{args} [array] | main.go:60:7:61:26 | call to Sprintf | provenance | MaD:23 | +| main.go:60:7:61:26 | []type{args} [array] | main.go:61:3:61:25 | selection of Category | provenance | | | main.go:60:7:61:26 | call to Sprintf | main.go:62:11:62:11 | q | provenance | Sink:MaD:1 | | main.go:61:3:61:25 | selection of Category | main.go:60:7:61:26 | []type{args} [array] | provenance | | | main.go:61:3:61:25 | selection of Category | main.go:60:7:61:26 | call to Sprintf | provenance | FunctionModel | diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected index 5deab249337e..a3d0c59798f5 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected @@ -3,7 +3,12 @@ | StringBreakMismatched.go:17:26:17:32 | escaped | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | StringBreakMismatched.go:17:26:17:32 | escaped | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | JSON value | | StringBreakMismatched.go:29:27:29:33 | escaped | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | StringBreakMismatched.go:29:27:29:33 | escaped | If this $@ contains a double quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | JSON value | edges +| StringBreak.go:10:2:10:12 | definition of versionJSON | StringBreak.go:14:47:14:57 | versionJSON | provenance | | +| StringBreak.go:10:2:10:12 | definition of versionJSON | StringBreak.go:14:47:14:57 | versionJSON | provenance | | | StringBreak.go:10:2:10:40 | ... := ...[0] | StringBreak.go:14:47:14:57 | versionJSON | provenance | | +| StringBreak.go:10:2:10:40 | ... := ...[0] | StringBreak.go:14:47:14:57 | versionJSON | provenance | | +| StringBreak.go:14:22:14:58 | []type{args} [array] | StringBreak.go:10:2:10:12 | definition of versionJSON | provenance | | +| StringBreak.go:14:47:14:57 | versionJSON | StringBreak.go:14:22:14:58 | []type{args} [array] | provenance | | | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | StringBreakMismatched.go:13:29:13:47 | type conversion | provenance | | | StringBreakMismatched.go:13:13:13:62 | call to Replace | StringBreakMismatched.go:17:26:17:32 | escaped | provenance | | | StringBreakMismatched.go:13:29:13:47 | type conversion | StringBreakMismatched.go:13:13:13:62 | call to Replace | provenance | MaD:1 | @@ -13,7 +18,10 @@ edges models | 1 | Summary: strings; ; false; Replace; ; ; Argument[0]; ReturnValue; taint; manual | nodes +| StringBreak.go:10:2:10:12 | definition of versionJSON | semmle.label | definition of versionJSON | | StringBreak.go:10:2:10:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreak.go:14:22:14:58 | []type{args} [array] | semmle.label | []type{args} [array] | +| StringBreak.go:14:47:14:57 | versionJSON | semmle.label | versionJSON | | StringBreak.go:14:47:14:57 | versionJSON | semmle.label | versionJSON | | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | semmle.label | ... := ...[0] | | StringBreakMismatched.go:13:13:13:62 | call to Replace | semmle.label | call to Replace | diff --git a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index c62c6126648c..b3396e7451b5 100644 --- a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,8 +1,16 @@ edges | test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | provenance | | +| test.go:14:2:14:4 | definition of buf | test.go:20:29:20:31 | buf | provenance | | +| test.go:15:2:15:4 | definition of buf | test.go:17:10:17:12 | buf | provenance | | +| test.go:15:2:15:4 | definition of buf | test.go:20:29:20:31 | buf | provenance | | +| test.go:20:2:20:32 | []type{args} [array] | test.go:15:2:15:4 | definition of buf | provenance | | +| test.go:20:29:20:31 | buf | test.go:20:2:20:32 | []type{args} [array] | provenance | | nodes | test.go:14:2:14:4 | definition of buf | semmle.label | definition of buf | +| test.go:15:2:15:4 | definition of buf | semmle.label | definition of buf | | test.go:17:10:17:12 | buf | semmle.label | buf | +| test.go:20:2:20:32 | []type{args} [array] | semmle.label | []type{args} [array] | +| test.go:20:29:20:31 | buf | semmle.label | buf | subpaths #select | test.go:17:10:17:12 | buf | test.go:14:2:14:4 | definition of buf | test.go:17:10:17:12 | buf | HTTP response depends on $@ and may be exposed to an external user. | test.go:14:2:14:4 | definition of buf | stack trace information | diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index 3435eff77754..31f709e456f2 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -64,28 +64,61 @@ edges | passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | | | passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | | | passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | provenance | Config | +| passwords.go:36:2:36:5 | definition of obj1 | passwords.go:39:14:39:17 | obj1 | provenance | | +| passwords.go:36:2:36:5 | definition of obj1 | passwords.go:39:14:39:17 | obj1 | provenance | | +| passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | | passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | | passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal | provenance | Config | +| passwords.go:39:2:39:18 | []type{args} [array] | passwords.go:36:2:36:5 | definition of obj1 | provenance | | +| passwords.go:39:14:39:17 | obj1 | passwords.go:39:2:39:18 | []type{args} [array] | provenance | | +| passwords.go:41:2:41:5 | definition of obj2 | passwords.go:44:14:44:17 | obj2 | provenance | | +| passwords.go:41:2:41:5 | definition of obj2 | passwords.go:44:14:44:17 | obj2 | provenance | | +| passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | | passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | | passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal | provenance | Config | +| passwords.go:44:2:44:18 | []type{args} [array] | passwords.go:41:2:41:5 | definition of obj2 | provenance | | +| passwords.go:44:14:44:17 | obj2 | passwords.go:44:2:44:18 | []type{args} [array] | provenance | | +| passwords.go:46:6:46:9 | definition of obj3 | passwords.go:47:14:47:17 | obj3 | provenance | | | passwords.go:46:6:46:9 | definition of obj3 | passwords.go:47:14:47:17 | obj3 | provenance | | +| passwords.go:47:2:47:18 | []type{args} [array] | passwords.go:46:6:46:9 | definition of obj3 | provenance | | +| passwords.go:47:14:47:17 | obj3 | passwords.go:47:2:47:18 | []type{args} [array] | provenance | | | passwords.go:48:11:48:18 | password | passwords.go:46:6:46:9 | definition of obj3 | provenance | Config | +| passwords.go:85:2:85:14 | definition of utilityObject | passwords.go:88:14:88:26 | utilityObject | provenance | | +| passwords.go:85:2:85:14 | definition of utilityObject | passwords.go:88:14:88:26 | utilityObject | provenance | | +| passwords.go:85:19:87:2 | struct literal | passwords.go:88:14:88:26 | utilityObject | provenance | | | passwords.go:85:19:87:2 | struct literal | passwords.go:88:14:88:26 | utilityObject | provenance | | | passwords.go:86:16:86:36 | call to make | passwords.go:85:19:87:2 | struct literal | provenance | Config | +| passwords.go:88:2:88:27 | []type{args} [array] | passwords.go:85:2:85:14 | definition of utilityObject | provenance | | +| passwords.go:88:14:88:26 | utilityObject | passwords.go:88:2:88:27 | []type{args} [array] | provenance | | | passwords.go:90:12:90:19 | password | passwords.go:91:23:91:28 | secret | provenance | | | passwords.go:101:33:101:40 | password | passwords.go:101:15:101:40 | ...+... | provenance | Config | | passwords.go:107:34:107:41 | password | passwords.go:107:16:107:41 | ...+... | provenance | Config | | passwords.go:112:33:112:40 | password | passwords.go:112:15:112:40 | ...+... | provenance | Config | | passwords.go:116:28:116:36 | password1 | passwords.go:116:28:116:45 | call to String | provenance | Config | | passwords.go:116:28:116:45 | call to String | passwords.go:116:14:116:45 | ...+... | provenance | Config | +| passwords.go:118:2:118:7 | definition of config | passwords.go:125:14:125:19 | config | provenance | | +| passwords.go:118:2:118:7 | definition of config | passwords.go:125:14:125:19 | config | provenance | | +| passwords.go:118:2:118:7 | definition of config [x] | passwords.go:125:14:125:19 | config [x] | provenance | | +| passwords.go:118:2:118:7 | definition of config [x] | passwords.go:126:14:126:19 | config [x] | provenance | | +| passwords.go:118:2:118:7 | definition of config [y] | passwords.go:125:14:125:19 | config [y] | provenance | | +| passwords.go:118:2:118:7 | definition of config [y] | passwords.go:127:14:127:19 | config [y] | provenance | | +| passwords.go:118:12:123:2 | struct literal | passwords.go:125:14:125:19 | config | provenance | | | passwords.go:118:12:123:2 | struct literal | passwords.go:125:14:125:19 | config | provenance | | +| passwords.go:118:12:123:2 | struct literal [x] | passwords.go:125:14:125:19 | config [x] | provenance | | | passwords.go:118:12:123:2 | struct literal [x] | passwords.go:126:14:126:19 | config [x] | provenance | | +| passwords.go:118:12:123:2 | struct literal [y] | passwords.go:125:14:125:19 | config [y] | provenance | | | passwords.go:118:12:123:2 | struct literal [y] | passwords.go:127:14:127:19 | config [y] | provenance | | | passwords.go:119:13:119:13 | x | passwords.go:118:12:123:2 | struct literal | provenance | Config | | passwords.go:121:13:121:20 | password | passwords.go:118:12:123:2 | struct literal | provenance | Config | | passwords.go:121:13:121:20 | password | passwords.go:118:12:123:2 | struct literal [x] | provenance | | | passwords.go:122:13:122:25 | call to getPassword | passwords.go:118:12:123:2 | struct literal | provenance | Config | | passwords.go:122:13:122:25 | call to getPassword | passwords.go:118:12:123:2 | struct literal [y] | provenance | | +| passwords.go:125:2:125:20 | []type{args} [array, x] | passwords.go:118:2:118:7 | definition of config [x] | provenance | | +| passwords.go:125:2:125:20 | []type{args} [array, y] | passwords.go:118:2:118:7 | definition of config [y] | provenance | | +| passwords.go:125:2:125:20 | []type{args} [array] | passwords.go:118:2:118:7 | definition of config | provenance | | +| passwords.go:125:14:125:19 | config | passwords.go:125:2:125:20 | []type{args} [array] | provenance | | +| passwords.go:125:14:125:19 | config [x] | passwords.go:125:2:125:20 | []type{args} [array, x] | provenance | | +| passwords.go:125:14:125:19 | config [y] | passwords.go:125:2:125:20 | []type{args} [array, y] | provenance | | | passwords.go:126:14:126:19 | config [x] | passwords.go:126:14:126:21 | selection of x | provenance | | | passwords.go:127:14:127:19 | config [y] | passwords.go:127:14:127:21 | selection of y | provenance | | | protobuf.go:11:2:11:6 | definition of query [pointer, Description] | protobuf.go:12:2:12:6 | query [pointer, Description] | provenance | | @@ -149,18 +182,29 @@ nodes | passwords.go:32:12:32:19 | password | semmle.label | password | | passwords.go:34:14:34:35 | ...+... | semmle.label | ...+... | | passwords.go:34:28:34:35 | password | semmle.label | password | +| passwords.go:36:2:36:5 | definition of obj1 | semmle.label | definition of obj1 | | passwords.go:36:10:38:2 | struct literal | semmle.label | struct literal | | passwords.go:37:13:37:13 | x | semmle.label | x | +| passwords.go:39:2:39:18 | []type{args} [array] | semmle.label | []type{args} [array] | | passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 | +| passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 | +| passwords.go:41:2:41:5 | definition of obj2 | semmle.label | definition of obj2 | | passwords.go:41:10:43:2 | struct literal | semmle.label | struct literal | | passwords.go:42:6:42:13 | password | semmle.label | password | +| passwords.go:44:2:44:18 | []type{args} [array] | semmle.label | []type{args} [array] | +| passwords.go:44:14:44:17 | obj2 | semmle.label | obj2 | | passwords.go:44:14:44:17 | obj2 | semmle.label | obj2 | | passwords.go:46:6:46:9 | definition of obj3 | semmle.label | definition of obj3 | +| passwords.go:47:2:47:18 | []type{args} [array] | semmle.label | []type{args} [array] | +| passwords.go:47:14:47:17 | obj3 | semmle.label | obj3 | | passwords.go:47:14:47:17 | obj3 | semmle.label | obj3 | | passwords.go:48:11:48:18 | password | semmle.label | password | | passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password | +| passwords.go:85:2:85:14 | definition of utilityObject | semmle.label | definition of utilityObject | | passwords.go:85:19:87:2 | struct literal | semmle.label | struct literal | | passwords.go:86:16:86:36 | call to make | semmle.label | call to make | +| passwords.go:88:2:88:27 | []type{args} [array] | semmle.label | []type{args} [array] | +| passwords.go:88:14:88:26 | utilityObject | semmle.label | utilityObject | | passwords.go:88:14:88:26 | utilityObject | semmle.label | utilityObject | | passwords.go:90:12:90:19 | password | semmle.label | password | | passwords.go:91:23:91:28 | secret | semmle.label | secret | @@ -173,13 +217,22 @@ nodes | passwords.go:116:14:116:45 | ...+... | semmle.label | ...+... | | passwords.go:116:28:116:36 | password1 | semmle.label | password1 | | passwords.go:116:28:116:45 | call to String | semmle.label | call to String | +| passwords.go:118:2:118:7 | definition of config | semmle.label | definition of config | +| passwords.go:118:2:118:7 | definition of config [x] | semmle.label | definition of config [x] | +| passwords.go:118:2:118:7 | definition of config [y] | semmle.label | definition of config [y] | | passwords.go:118:12:123:2 | struct literal | semmle.label | struct literal | | passwords.go:118:12:123:2 | struct literal [x] | semmle.label | struct literal [x] | | passwords.go:118:12:123:2 | struct literal [y] | semmle.label | struct literal [y] | | passwords.go:119:13:119:13 | x | semmle.label | x | | passwords.go:121:13:121:20 | password | semmle.label | password | | passwords.go:122:13:122:25 | call to getPassword | semmle.label | call to getPassword | +| passwords.go:125:2:125:20 | []type{args} [array, x] | semmle.label | []type{args} [array, x] | +| passwords.go:125:2:125:20 | []type{args} [array, y] | semmle.label | []type{args} [array, y] | +| passwords.go:125:2:125:20 | []type{args} [array] | semmle.label | []type{args} [array] | +| passwords.go:125:14:125:19 | config | semmle.label | config | | passwords.go:125:14:125:19 | config | semmle.label | config | +| passwords.go:125:14:125:19 | config [x] | semmle.label | config [x] | +| passwords.go:125:14:125:19 | config [y] | semmle.label | config [y] | | passwords.go:126:14:126:19 | config [x] | semmle.label | config [x] | | passwords.go:126:14:126:21 | selection of x | semmle.label | selection of x | | passwords.go:127:14:127:19 | config [y] | semmle.label | config [y] | diff --git a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected index ac5985f110d9..b729c7baf83c 100644 --- a/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-640/EmailInjection.expected @@ -19,17 +19,41 @@ edges | main.go:46:21:46:31 | call to Referer | main.go:52:46:52:59 | untrustedInput | provenance | Src:MaD:2 | | main.go:46:21:46:31 | call to Referer | main.go:53:52:53:65 | untrustedInput | provenance | Src:MaD:2 | | main.go:58:21:58:31 | call to Referer | main.go:60:47:60:60 | untrustedInput | provenance | Src:MaD:2 | +| main.go:60:3:60:9 | definition of content | main.go:63:16:63:22 | content | provenance | | +| main.go:60:3:60:9 | definition of content | main.go:63:16:63:22 | content | provenance | | +| main.go:60:14:60:61 | call to NewContent | main.go:63:16:63:22 | content | provenance | | | main.go:60:14:60:61 | call to NewContent | main.go:63:16:63:22 | content | provenance | | | main.go:60:47:60:60 | untrustedInput | main.go:60:14:60:61 | call to NewContent | provenance | MaD:3 | +| main.go:63:3:63:23 | []type{args} [array] | main.go:60:3:60:9 | definition of content | provenance | | +| main.go:63:16:63:22 | content | main.go:63:3:63:23 | []type{args} [array] | provenance | | | main.go:68:21:68:31 | call to Referer | main.go:74:47:74:60 | untrustedInput | provenance | Src:MaD:2 | +| main.go:74:3:74:9 | definition of content | main.go:76:50:76:56 | content | provenance | | +| main.go:74:3:74:9 | definition of content | main.go:76:50:76:56 | content | provenance | | +| main.go:74:3:74:9 | definition of content | main.go:76:59:76:65 | content | provenance | | +| main.go:74:3:74:9 | definition of content | main.go:76:59:76:65 | content | provenance | | +| main.go:74:3:74:9 | definition of content | main.go:77:16:77:22 | content | provenance | | +| main.go:74:3:74:9 | definition of content | main.go:77:16:77:22 | content | provenance | | +| main.go:74:14:74:61 | call to NewContent | main.go:76:50:76:56 | content | provenance | | | main.go:74:14:74:61 | call to NewContent | main.go:76:50:76:56 | content | provenance | | | main.go:74:14:74:61 | call to NewContent | main.go:76:59:76:65 | content | provenance | | +| main.go:74:14:74:61 | call to NewContent | main.go:76:59:76:65 | content | provenance | | +| main.go:74:14:74:61 | call to NewContent | main.go:77:16:77:22 | content | provenance | | | main.go:74:14:74:61 | call to NewContent | main.go:77:16:77:22 | content | provenance | | | main.go:74:47:74:60 | untrustedInput | main.go:74:14:74:61 | call to NewContent | provenance | MaD:3 | +| main.go:76:8:76:66 | []type{args} [array] | main.go:74:3:74:9 | definition of content | provenance | | +| main.go:76:50:76:56 | content | main.go:76:8:76:66 | []type{args} [array] | provenance | | +| main.go:76:59:76:65 | content | main.go:76:8:76:66 | []type{args} [array] | provenance | | +| main.go:77:3:77:23 | []type{args} [array] | main.go:74:3:74:9 | definition of content | provenance | | +| main.go:77:16:77:22 | content | main.go:77:3:77:23 | []type{args} [array] | provenance | | | main.go:82:21:82:31 | call to Referer | main.go:89:37:89:50 | untrustedInput | provenance | Src:MaD:2 | | main.go:82:21:82:31 | call to Referer | main.go:91:48:91:61 | untrustedInput | provenance | Src:MaD:2 | +| main.go:91:3:91:10 | definition of content2 | main.go:93:16:93:23 | content2 | provenance | | +| main.go:91:3:91:10 | definition of content2 | main.go:93:16:93:23 | content2 | provenance | | +| main.go:91:15:91:62 | call to NewContent | main.go:93:16:93:23 | content2 | provenance | | | main.go:91:15:91:62 | call to NewContent | main.go:93:16:93:23 | content2 | provenance | | | main.go:91:48:91:61 | untrustedInput | main.go:91:15:91:62 | call to NewContent | provenance | MaD:3 | +| main.go:93:3:93:24 | []type{args} [array] | main.go:91:3:91:10 | definition of content2 | provenance | | +| main.go:93:16:93:23 | content2 | main.go:93:3:93:24 | []type{args} [array] | provenance | | models | 1 | Source: net/http; Request; true; Header; ; ; ; remote; manual | | 2 | Source: net/http; Request; true; Referer; ; ; ReturnValue; remote; manual | @@ -49,18 +73,30 @@ nodes | main.go:52:46:52:59 | untrustedInput | semmle.label | untrustedInput | | main.go:53:52:53:65 | untrustedInput | semmle.label | untrustedInput | | main.go:58:21:58:31 | call to Referer | semmle.label | call to Referer | +| main.go:60:3:60:9 | definition of content | semmle.label | definition of content | | main.go:60:14:60:61 | call to NewContent | semmle.label | call to NewContent | | main.go:60:47:60:60 | untrustedInput | semmle.label | untrustedInput | +| main.go:63:3:63:23 | []type{args} [array] | semmle.label | []type{args} [array] | +| main.go:63:16:63:22 | content | semmle.label | content | | main.go:63:16:63:22 | content | semmle.label | content | | main.go:68:21:68:31 | call to Referer | semmle.label | call to Referer | +| main.go:74:3:74:9 | definition of content | semmle.label | definition of content | | main.go:74:14:74:61 | call to NewContent | semmle.label | call to NewContent | | main.go:74:47:74:60 | untrustedInput | semmle.label | untrustedInput | +| main.go:76:8:76:66 | []type{args} [array] | semmle.label | []type{args} [array] | +| main.go:76:50:76:56 | content | semmle.label | content | | main.go:76:50:76:56 | content | semmle.label | content | | main.go:76:59:76:65 | content | semmle.label | content | +| main.go:76:59:76:65 | content | semmle.label | content | +| main.go:77:3:77:23 | []type{args} [array] | semmle.label | []type{args} [array] | +| main.go:77:16:77:22 | content | semmle.label | content | | main.go:77:16:77:22 | content | semmle.label | content | | main.go:82:21:82:31 | call to Referer | semmle.label | call to Referer | | main.go:89:37:89:50 | untrustedInput | semmle.label | untrustedInput | +| main.go:91:3:91:10 | definition of content2 | semmle.label | definition of content2 | | main.go:91:15:91:62 | call to NewContent | semmle.label | call to NewContent | | main.go:91:48:91:61 | untrustedInput | semmle.label | untrustedInput | +| main.go:93:3:93:24 | []type{args} [array] | semmle.label | []type{args} [array] | +| main.go:93:16:93:23 | content2 | semmle.label | content2 | | main.go:93:16:93:23 | content2 | semmle.label | content2 | subpaths From 3d0a2057f61d9564e7741f638214d650ac646a67 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 15:46:14 +0000 Subject: [PATCH 123/213] C++: Fix 'BSTRToArray' stub and MaD model. --- cpp/ql/lib/ext/CComBSTR.model.yml | 2 +- .../dataflow/external-models/flow.expected | 10 +++++----- cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp | 6 +++--- .../dataflow/taint-tests/localTaint.expected | 4 ++-- .../dataflow/taint-tests/test_mad-signatures.expected | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cpp/ql/lib/ext/CComBSTR.model.yml b/cpp/ql/lib/ext/CComBSTR.model.yml index 1865a244ef30..d31f3e36a512 100644 --- a/cpp/ql/lib/ext/CComBSTR.model.yml +++ b/cpp/ql/lib/ext/CComBSTR.model.yml @@ -20,7 +20,7 @@ extensions: - ["", "CComBSTR", True, "ArrayToBSTR", "", "", "Argument[*0].Field[*pvData]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "AssignBSTR", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CComBSTR", True, "Attach", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - - ["", "CComBSTR", True, "BSTRToArray", "", "", "Argument[-1]", "Argument[*0].Field[*pvData]", "value", "manual"] + - ["", "CComBSTR", True, "BSTRToArray", "", "", "Argument[-1]", "Argument[**0].Field[*pvData]", "value", "manual"] - ["", "CComBSTR", True, "Copy", "", "", "Argument[-1]", "ReturnValue[*]", "value", "manual"] - ["", "CComBSTR", True, "CopyTo", "", "", "Argument[-1]", "Argument[*0]", "value", "manual"] - ["", "CComBSTR", True, "LoadString", "(HINSTANCE,UINT)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] 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 137642d522a4..81a9c605f005 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:801 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:799 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:800 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:800 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:798 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:799 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:800 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:799 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:801 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:800 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 05d14c06c362..9a57fd604a5e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -426,7 +426,7 @@ struct CComBSTR { HRESULT ArrayToBSTR(const SAFEARRAY* pSrc) throw(); HRESULT AssignBSTR(const BSTR bstrSrc) throw(); void Attach(BSTR src) throw(); - HRESULT BSTRToArray(LPSAFEARRAY ppArray) throw(); + HRESULT BSTRToArray(LPSAFEARRAY* ppArray) throw(); unsigned int ByteLength() const throw(); BSTR Copy() const throw(); HRESULT CopyTo(BSTR* pbstr) throw(); @@ -504,10 +504,10 @@ void test_CComBSTR() { sink(b8.m_str); // $ ir CComBSTR b9; - SAFEARRAY safe; + LPSAFEARRAY safe; b9.Append(source()); b9.BSTRToArray(&safe); - sink(safe.pvData); // $ ir + sink(safe->pvData); // $ ir sink(b9.Copy()); // $ ir } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index a35e1c53d1c5..d3ee7b7c0895 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -606,8 +606,8 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | atl.cpp:506:14:506:15 | call to CComBSTR | atl.cpp:509:5:509:6 | b9 | | | atl.cpp:506:14:506:15 | call to CComBSTR | atl.cpp:512:10:512:11 | b9 | | | atl.cpp:506:14:506:15 | call to CComBSTR | atl.cpp:513:3:513:3 | b9 | | -| atl.cpp:507:15:507:18 | safe | atl.cpp:509:21:509:24 | safe | | -| atl.cpp:507:15:507:18 | safe | atl.cpp:510:10:510:13 | safe | | +| atl.cpp:507:17:507:20 | safe | atl.cpp:509:21:509:24 | safe | | +| atl.cpp:507:17:507:20 | safe | atl.cpp:510:10:510:13 | safe | | | atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:509:5:509:6 | b9 | | | atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:512:10:512:11 | b9 | | | atl.cpp:508:5:508:6 | ref arg b9 | atl.cpp:513:3:513:3 | b9 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index f1e4b841d870..6627139ae6e2 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -613,7 +613,7 @@ getParameterTypeName | atl.cpp:426:11:426:21 | ArrayToBSTR | 0 | const SAFEARRAY * | | atl.cpp:427:11:427:20 | AssignBSTR | 0 | const BSTR | | atl.cpp:428:8:428:13 | Attach | 0 | BSTR | -| atl.cpp:429:11:429:21 | BSTRToArray | 0 | LPSAFEARRAY | +| atl.cpp:429:11:429:21 | BSTRToArray | 0 | LPSAFEARRAY * | | atl.cpp:432:11:432:16 | CopyTo | 0 | BSTR * | | atl.cpp:434:11:434:16 | CopyTo | 0 | VARIANT * | | atl.cpp:438:8:438:17 | LoadString | 0 | HINSTANCE | From 1ceee769199a6a8d0572c816a8b63d0f415ff2d9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:52:08 +0000 Subject: [PATCH 124/213] Rust: Get the .expected values right this time. --- rust/ql/integration-tests/hello-project/summary.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/integration-tests/hello-project/summary.expected b/rust/ql/integration-tests/hello-project/summary.expected index 6912eb2c52d8..5972bf15827e 100644 --- a/rust/ql/integration-tests/hello-project/summary.expected +++ b/rust/ql/integration-tests/hello-project/summary.expected @@ -5,7 +5,7 @@ | Files extracted - total | 5 | | Files extracted - with errors | 1 | | Files extracted - without errors | 4 | -| Files extracted - without errors % | 100 | +| Files extracted - without errors % | 80 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 0 | From 59f4b3c0db3d12177b34950c0070af798f8fa7e2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 6 Dec 2024 15:58:07 +0000 Subject: [PATCH 125/213] C++: Get rid of the model for 'Create'. --- cpp/ql/lib/ext/CComSafeArray.model.yml | 1 - .../dataflow/external-models/flow.expected | 10 +++++----- .../dataflow/external-models/validatemodels.expected | 1 - .../dataflow/taint-tests/test_mad-signatures.expected | 3 --- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/cpp/ql/lib/ext/CComSafeArray.model.yml b/cpp/ql/lib/ext/CComSafeArray.model.yml index 8da350ff140a..61aec61e7d2b 100644 --- a/cpp/ql/lib/ext/CComSafeArray.model.yml +++ b/cpp/ql/lib/ext/CComSafeArray.model.yml @@ -11,7 +11,6 @@ extensions: - ["", "CComSafeArray", True, "Attach", "", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] - ["", "CComSafeArray", True, "CopyFrom", "", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] - ["", "CComSafeArray", True, "CopyTo", "", "", "Argument[-1].Field[*m_psa]", "Argument[*0]", "value", "manual"] - - ["", "CComSafeArray", True, "Create", "(const SAFEARRAYBOUND *,UINT)", "", "Argument[*0]", "Argument[-1].Field[*m_psa]", "value", "manual"] - ["", "CComSafeArray", True, "GetAt", "", "", "Argument[-1].Field[*m_psa].Field[*@pvData]", "ReturnValue[*@]", "value", "manual"] - ["", "CComSafeArray", True, "GetLowerBound", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CComSafeArray", True, "GetSafeArrayPtr", "", "", "Argument[-1].Field[*m_psa]", "ReturnValue[*]", "value", "manual"] 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 81a9c605f005..8930cadb8d8a 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:800 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:798 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:799 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:799 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:797 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:798 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:799 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:798 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:800 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:799 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index 7b089db8a6d2..423e238ecd7e 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -21,7 +21,6 @@ | Dubious signature "(const CComSafeArray &)" in summary model. | | Dubious signature "(const SAFEARRAY &)" in summary model. | | Dubious signature "(const SAFEARRAY *)" in summary model. | -| Dubious signature "(const SAFEARRAYBOUND *,UINT)" in summary model. | | Dubious signature "(const T &,BOOL)" in summary model. | | Dubious signature "(const deque &)" in summary model. | | Dubious signature "(const deque &,const Allocator &)" in summary model. | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 6627139ae6e2..2d69f088fef3 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -35,7 +35,6 @@ signatureMatches | atl.cpp:426:11:426:21 | ArrayToBSTR | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | | atl.cpp:438:8:438:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 0 | | atl.cpp:438:8:438:17 | LoadString | (HINSTANCE,UINT) | CComBSTR | LoadString | 1 | -| atl.cpp:438:8:438:17 | LoadString | (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 1 | | atl.cpp:439:8:439:17 | LoadString | (UINT) | CComBSTR | LoadString | 0 | | atl.cpp:439:8:439:17 | LoadString | (UINT) | _U_STRINGorID | _U_STRINGorID | 0 | | atl.cpp:447:13:447:22 | operator+= | (const CComBSTR &) | CComBSTR | Append | 0 | @@ -419,8 +418,6 @@ getSignatureParameterName | (const SAFEARRAY *) | CComSafeArray | Add | 0 | const SAFEARRAY * | | (const SAFEARRAY *) | CComSafeArray | CComSafeArray | 0 | const SAFEARRAY * | | (const SAFEARRAY *) | CComSafeArray | operator= | 0 | const SAFEARRAY * | -| (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 0 | const SAFEARRAYBOUND * | -| (const SAFEARRAYBOUND *,UINT) | CComSafeArray | Create | 1 | UINT | | (const T &,BOOL) | CComSafeArray | Add | 0 | const class:0 & | | (const T &,BOOL) | CComSafeArray | Add | 1 | BOOL | | (const deque &) | deque | deque | 0 | const deque & | From a0cb9c19faf555e96b60866fbeb4133467218ebe Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 11 Nov 2024 10:44:23 +0000 Subject: [PATCH 126/213] C#: Add `CODEQL_PROXY_*` environment variable names --- .../EnvironmentVariableNames.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs index 345cb43453fc..d825e5daeb03 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs @@ -74,5 +74,20 @@ internal static class EnvironmentVariableNames /// Specifies the location of the diagnostic directory. /// public const string DiagnosticDir = "CODEQL_EXTRACTOR_CSHARP_DIAGNOSTIC_DIR"; + + ///

+ /// Specifies the hostname of the Dependabot proxy. + /// + public const string ProxyHost = "CODEQL_PROXY_HOST"; + + /// + /// Specifies the hostname of the Dependabot proxy. + /// + public const string ProxyPort = "CODEQL_PROXY_PORT"; + + /// + /// Contains the certificate used by the Dependabot proxy. + /// + public const string ProxyCertificate = "CODEQL_PROXY_CA_CERTIFICATE"; } } From 459b76ac3f45ac321c24c1e6686a6e95e1a592a5 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 11 Nov 2024 11:25:13 +0000 Subject: [PATCH 127/213] C#: Add `DependabotProxy` class --- .../DependabotProxy.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs new file mode 100644 index 000000000000..5b47189c7454 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using Semmle.Util; + +namespace Semmle.Extraction.CSharp.DependencyFetching +{ + internal class DependabotProxy + { + private readonly string? host; + private readonly string? port; + private readonly FileInfo? certFile; + + /// + /// The full address of the Dependabot proxy, if available. + /// + internal readonly string? Address; + + /// + /// Gets a value indicating whether a Dependabot proxy is configured. + /// + internal bool IsConfigured => !string.IsNullOrEmpty(this.Address); + + internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) + { + // Obtain and store the address of the Dependabot proxy, if available. + this.host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); + this.port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); + + if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port)) + { + return; + } + + this.Address = $"http://{this.host}:{this.port}"; + + // Obtain and store the proxy's certificate, if available. + var cert = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyCertificate); + + if (string.IsNullOrWhiteSpace(cert)) + { + return; + } + + var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); + Directory.CreateDirectory(certDirPath.FullName); + + this.certFile = new FileInfo(Path.Join(certDirPath.FullName, "proxy.crt")); + + using var writer = this.certFile.CreateText(); + writer.Write(cert); + } + } +} From c6f089585a15d29c4596b9d80418ba6dfd763fa9 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 19 Nov 2024 12:26:54 +0000 Subject: [PATCH 128/213] C#: Initialise `DependabotProxy` in `DotNetCliInvoker` --- .../DotNet.cs | 2 +- .../DotNetCliInvoker.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index edfea049a81b..439f00754dda 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -27,7 +27,7 @@ private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDire Info(); } - private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet")), logger, tempWorkingDirectory) { } + private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), tempWorkingDirectory), logger, tempWorkingDirectory) { } internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 4295cce67167..b81b393e42a0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -12,12 +12,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching internal sealed class DotNetCliInvoker : IDotNetCliInvoker { private readonly ILogger logger; + private readonly DependabotProxy proxy; public string Exec { get; } - public DotNetCliInvoker(ILogger logger, string exec) + public DotNetCliInvoker(ILogger logger, string exec, TemporaryDirectory tempWorkingDirectory) { this.logger = logger; + this.proxy = new DependabotProxy(tempWorkingDirectory); this.Exec = exec; logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } @@ -38,6 +40,14 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = "en"; startInfo.EnvironmentVariables["MSBUILDDISABLENODEREUSE"] = "1"; startInfo.EnvironmentVariables["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true"; + + // Configure the proxy settings, if applicable. + this.proxy.ApplyProxy(this.logger, startInfo); + + this.logger.LogInfo(startInfo.EnvironmentVariables["HTTP_PROXY"] ?? ""); + this.logger.LogInfo(startInfo.EnvironmentVariables["HTTPS_PROXY"] ?? ""); + this.logger.LogInfo(startInfo.EnvironmentVariables["SSL_CERT_FILE"] ?? ""); + return startInfo; } From d6fda1ae72a9be12be61ff864eb3e31e69da1d0e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 19 Nov 2024 13:23:05 +0000 Subject: [PATCH 129/213] C#: Set environment variables for proxy for calls to `dotnet` --- .../DependabotProxy.cs | 14 ++++++++++++++ .../DotNetCliInvoker.cs | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 5b47189c7454..96ba3452cefe 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics; using System.IO; using Semmle.Util; +using Semmle.Util.Logging; namespace Semmle.Extraction.CSharp.DependencyFetching { @@ -49,5 +51,17 @@ internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) using var writer = this.certFile.CreateText(); writer.Write(cert); } + + internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) + { + // If the proxy isn't configured, we have nothing to do. + if (!this.IsConfigured) return; + + logger.LogInfo($"Setting up Dependabot proxy at {this.Address}"); + + startInfo.EnvironmentVariables["HTTP_PROXY"] = this.Address; + startInfo.EnvironmentVariables["HTTPS_PROXY"] = this.Address; + startInfo.EnvironmentVariables["SSL_CERT_FILE"] = this.certFile?.FullName; + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index b81b393e42a0..522d3e9ffd45 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -44,10 +44,6 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto // Configure the proxy settings, if applicable. this.proxy.ApplyProxy(this.logger, startInfo); - this.logger.LogInfo(startInfo.EnvironmentVariables["HTTP_PROXY"] ?? ""); - this.logger.LogInfo(startInfo.EnvironmentVariables["HTTPS_PROXY"] ?? ""); - this.logger.LogInfo(startInfo.EnvironmentVariables["SSL_CERT_FILE"] ?? ""); - return startInfo; } From 84d3532a0521055cfe3ecb5fd4a5bacd98257e71 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 29 Nov 2024 13:18:58 +0000 Subject: [PATCH 130/213] C#: Add more logging to `DependabotProxy` --- .../DependabotProxy.cs | 10 ++++++++-- .../DotNetCliInvoker.cs | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 96ba3452cefe..c1db0b99017a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -22,7 +22,7 @@ internal class DependabotProxy /// internal bool IsConfigured => !string.IsNullOrEmpty(this.Address); - internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) + internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) { // Obtain and store the address of the Dependabot proxy, if available. this.host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); @@ -30,26 +30,32 @@ internal DependabotProxy(TemporaryDirectory tempWorkingDirectory) if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port)) { + logger.LogInfo("No Dependabot proxy credentials are configured."); return; } this.Address = $"http://{this.host}:{this.port}"; + logger.LogInfo($"Dependabot proxy configured at {this.Address}"); // Obtain and store the proxy's certificate, if available. var cert = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyCertificate); if (string.IsNullOrWhiteSpace(cert)) { + logger.LogInfo("No certificate configured for Dependabot proxy."); return; } var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); Directory.CreateDirectory(certDirPath.FullName); - this.certFile = new FileInfo(Path.Join(certDirPath.FullName, "proxy.crt")); + var certFilePath = Path.Join(certDirPath.FullName, "proxy.crt"); + this.certFile = new FileInfo(certFilePath); using var writer = this.certFile.CreateText(); writer.Write(cert); + + logger.LogInfo($"Stored Dependabot proxy certificate at {certFilePath}"); } internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 522d3e9ffd45..597acc58259a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -19,7 +19,7 @@ internal sealed class DotNetCliInvoker : IDotNetCliInvoker public DotNetCliInvoker(ILogger logger, string exec, TemporaryDirectory tempWorkingDirectory) { this.logger = logger; - this.proxy = new DependabotProxy(tempWorkingDirectory); + this.proxy = new DependabotProxy(logger, tempWorkingDirectory); this.Exec = exec; logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } From 4a7413cf11b0511b4ad808af28c6cb52f97055cc Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 13:40:37 +0000 Subject: [PATCH 131/213] C#: Use `Add` for environment variables --- .../DependabotProxy.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index c1db0b99017a..462cde58c87b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -65,9 +65,9 @@ internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) logger.LogInfo($"Setting up Dependabot proxy at {this.Address}"); - startInfo.EnvironmentVariables["HTTP_PROXY"] = this.Address; - startInfo.EnvironmentVariables["HTTPS_PROXY"] = this.Address; - startInfo.EnvironmentVariables["SSL_CERT_FILE"] = this.certFile?.FullName; + startInfo.EnvironmentVariables.Add("HTTP_PROXY", this.Address); + startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.Address); + startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.certFile?.FullName); } } } From 8b5050e427a57240451f05afd0eb62c51048b91c Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 14:17:06 +0000 Subject: [PATCH 132/213] C# Expose `CertificatePath` from `DependabotProxy` --- .../DependabotProxy.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 462cde58c87b..56bf08de9cc8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -16,6 +16,10 @@ internal class DependabotProxy /// The full address of the Dependabot proxy, if available. /// internal readonly string? Address; + /// + /// The path to the temporary file where the certificate is stored. + /// + internal readonly string? CertificatePath; /// /// Gets a value indicating whether a Dependabot proxy is configured. @@ -49,13 +53,13 @@ internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); Directory.CreateDirectory(certDirPath.FullName); - var certFilePath = Path.Join(certDirPath.FullName, "proxy.crt"); - this.certFile = new FileInfo(certFilePath); + this.CertificatePath = Path.Join(certDirPath.FullName, "proxy.crt"); + this.certFile = new FileInfo(this.CertificatePath); using var writer = this.certFile.CreateText(); writer.Write(cert); - logger.LogInfo($"Stored Dependabot proxy certificate at {certFilePath}"); + logger.LogInfo($"Stored Dependabot proxy certificate at {this.CertificatePath}"); } internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) From 4d5c55e5339fc349c5f91193f1f0b8139677e27f Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 14:18:24 +0000 Subject: [PATCH 133/213] C#: Propagate `DependabotProxy` instance down from `DependencyManager` --- .../DependabotProxy.cs | 2 +- .../DependencyManager.cs | 7 +++++-- .../Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs | 4 ++-- .../DotNetCliInvoker.cs | 4 ++-- .../NugetPackageRestorer.cs | 3 +++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 56bf08de9cc8..207d19777cc8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -6,7 +6,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching { - internal class DependabotProxy + public class DependabotProxy { private readonly string? host; private readonly string? port; diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index 4866df1260e2..de9308675982 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -27,6 +27,7 @@ public sealed partial class DependencyManager : IDisposable, ICompilationInfoCon private readonly ILogger logger; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly NugetPackageRestorer nugetPackageRestorer; + private readonly DependabotProxy dependabotProxy; private readonly IDotNet dotnet; private readonly FileContent fileContent; private readonly FileProvider fileProvider; @@ -106,9 +107,11 @@ void exitCallback(int ret, string msg, bool silent) return BuildScript.Success; }).Run(SystemBuildActions.Instance, startCallback, exitCallback); + dependabotProxy = new DependabotProxy(logger, tempWorkingDirectory); + try { - this.dotnet = DotNet.Make(logger, dotnetPath, tempWorkingDirectory); + this.dotnet = DotNet.Make(logger, dotnetPath, tempWorkingDirectory, dependabotProxy); runtimeLazy = new Lazy(() => new Runtime(dotnet)); } catch @@ -117,7 +120,7 @@ void exitCallback(int ret, string msg, bool silent) throw; } - nugetPackageRestorer = new NugetPackageRestorer(fileProvider, fileContent, dotnet, diagnosticsWriter, logger, this); + nugetPackageRestorer = new NugetPackageRestorer(fileProvider, fileContent, dotnet, dependabotProxy, diagnosticsWriter, logger, this); var dllLocations = fileProvider.Dlls.Select(x => new AssemblyLookupLocation(x)).ToHashSet(); dllLocations.UnionWith(nugetPackageRestorer.Restore()); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index 439f00754dda..a82a0a47f415 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -27,11 +27,11 @@ private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDire Info(); } - private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), tempWorkingDirectory), logger, tempWorkingDirectory) { } + private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { } internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger); - public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory) => new DotNet(logger, dotNetPath, tempWorkingDirectory); + public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); private void Info() { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 597acc58259a..cdadfe1f5b8e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -16,10 +16,10 @@ internal sealed class DotNetCliInvoker : IDotNetCliInvoker public string Exec { get; } - public DotNetCliInvoker(ILogger logger, string exec, TemporaryDirectory tempWorkingDirectory) + public DotNetCliInvoker(ILogger logger, string exec, DependabotProxy dependabotProxy) { this.logger = logger; - this.proxy = new DependabotProxy(logger, tempWorkingDirectory); + this.proxy = dependabotProxy; this.Exec = exec; logger.LogInfo($"Using .NET CLI executable: '{Exec}'"); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 3895db3e4d40..fcb0ca747ef6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -21,6 +21,7 @@ internal sealed partial class NugetPackageRestorer : IDisposable private readonly FileProvider fileProvider; private readonly FileContent fileContent; private readonly IDotNet dotnet; + private readonly DependabotProxy dependabotProxy; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly TemporaryDirectory legacyPackageDirectory; private readonly TemporaryDirectory missingPackageDirectory; @@ -33,6 +34,7 @@ public NugetPackageRestorer( FileProvider fileProvider, FileContent fileContent, IDotNet dotnet, + DependabotProxy dependabotProxy, IDiagnosticsWriter diagnosticsWriter, ILogger logger, ICompilationInfoContainer compilationInfoContainer) @@ -40,6 +42,7 @@ public NugetPackageRestorer( this.fileProvider = fileProvider; this.fileContent = fileContent; this.dotnet = dotnet; + this.dependabotProxy = dependabotProxy; this.diagnosticsWriter = diagnosticsWriter; this.logger = logger; this.compilationInfoContainer = compilationInfoContainer; From 8886292eec1ce703d240ea52d377282b78ef215e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Dec 2024 14:20:11 +0000 Subject: [PATCH 134/213] C#: Set up proxy for `IsFeedReachable`, if configured --- .../NugetPackageRestorer.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index fcb0ca747ef6..3663265f5b92 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Net.Http; -using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -592,7 +593,26 @@ private static async Task ExecuteGetRequest(string address, HttpClient httpClien private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, bool allowExceptions = true) { logger.LogInfo($"Checking if Nuget feed '{feed}' is reachable..."); - using HttpClient client = new(); + + // Configure the HttpClient to be aware of the Dependabot Proxy, if used. + HttpClientHandler httpClientHandler = new(); + if (this.dependabotProxy.IsConfigured) + { + httpClientHandler.Proxy = new WebProxy(this.dependabotProxy.Address); + + if (!String.IsNullOrEmpty(this.dependabotProxy.CertificatePath)) + { + X509Certificate2 proxyCert = new X509Certificate2(this.dependabotProxy.CertificatePath); + httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) => + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(proxyCert); + return chain.Build(cert); + }; + } + } + + using HttpClient client = new(httpClientHandler); for (var i = 0; i < tryCount; i++) { From 174cb7c0e2a538abbbeb49c100d5b52f31fe1362 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 3 Dec 2024 18:47:47 +0000 Subject: [PATCH 135/213] C#: Load Dependabot Proxy certificate in `DependabotProxy`, and implement `IDisposable` --- .../DependabotProxy.cs | 17 ++++++++++++++++- .../DependencyManager.cs | 1 + .../NugetPackageRestorer.cs | 5 ++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 207d19777cc8..7d0f21d65b1a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -1,12 +1,13 @@ using System; using System.Diagnostics; using System.IO; +using System.Security.Cryptography.X509Certificates; using Semmle.Util; using Semmle.Util.Logging; namespace Semmle.Extraction.CSharp.DependencyFetching { - public class DependabotProxy + public class DependabotProxy : IDisposable { private readonly string? host; private readonly string? port; @@ -20,6 +21,10 @@ public class DependabotProxy /// The path to the temporary file where the certificate is stored. /// internal readonly string? CertificatePath; + /// + /// The certificate used for the Dependabot proxy. + /// + internal readonly X509Certificate2? Certificate; /// /// Gets a value indicating whether a Dependabot proxy is configured. @@ -60,6 +65,8 @@ internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory writer.Write(cert); logger.LogInfo($"Stored Dependabot proxy certificate at {this.CertificatePath}"); + + this.Certificate = new X509Certificate2(this.CertificatePath); } internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) @@ -73,5 +80,13 @@ internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.Address); startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.certFile?.FullName); } + + public void Dispose() + { + if (this.Certificate != null) + { + this.Certificate.Dispose(); + } + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index de9308675982..bbd5ecbd127a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -545,6 +545,7 @@ private void AnalyseProject(FileInfo project) public void Dispose() { nugetPackageRestorer?.Dispose(); + dependabotProxy.Dispose(); if (cleanupTempWorkingDirectory) { tempWorkingDirectory?.Dispose(); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 3663265f5b92..8ea25c72f369 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -600,13 +600,12 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, { httpClientHandler.Proxy = new WebProxy(this.dependabotProxy.Address); - if (!String.IsNullOrEmpty(this.dependabotProxy.CertificatePath)) + if (this.dependabotProxy.Certificate != null) { - X509Certificate2 proxyCert = new X509Certificate2(this.dependabotProxy.CertificatePath); httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) => { chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; - chain.ChainPolicy.CustomTrustStore.Add(proxyCert); + chain.ChainPolicy.CustomTrustStore.Add(this.dependabotProxy.Certificate); return chain.Build(cert); }; } From 2bb59e2850e9423ee4b807f1ee522ea43d260bfa Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 5 Dec 2024 12:13:29 +0000 Subject: [PATCH 136/213] C#: Apply suggestions from code review for `DependabotProxy` --- .../DependabotProxy.cs | 69 ++++++++----------- .../DependencyManager.cs | 4 +- .../DotNet.cs | 4 +- .../DotNetCliInvoker.cs | 13 +++- .../NugetPackageRestorer.cs | 6 +- 5 files changed, 45 insertions(+), 51 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 7d0f21d65b1a..d1a5df4dbc5e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -9,84 +9,71 @@ namespace Semmle.Extraction.CSharp.DependencyFetching { public class DependabotProxy : IDisposable { - private readonly string? host; - private readonly string? port; - private readonly FileInfo? certFile; + private readonly string host; + private readonly string port; /// /// The full address of the Dependabot proxy, if available. /// - internal readonly string? Address; + internal string Address { get; } /// /// The path to the temporary file where the certificate is stored. /// - internal readonly string? CertificatePath; + internal string? CertificatePath { get; private set; } /// /// The certificate used for the Dependabot proxy. /// - internal readonly X509Certificate2? Certificate; + internal X509Certificate2? Certificate { get; private set; } - /// - /// Gets a value indicating whether a Dependabot proxy is configured. - /// - internal bool IsConfigured => !string.IsNullOrEmpty(this.Address); - - internal DependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) + internal static DependabotProxy? GetDependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) { // Obtain and store the address of the Dependabot proxy, if available. - this.host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); - this.port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); + var host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); + var port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port)) { logger.LogInfo("No Dependabot proxy credentials are configured."); - return; + return null; } - this.Address = $"http://{this.host}:{this.port}"; - logger.LogInfo($"Dependabot proxy configured at {this.Address}"); + var result = new DependabotProxy(host, port); + logger.LogInfo($"Dependabot proxy configured at {result.Address}"); // Obtain and store the proxy's certificate, if available. var cert = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyCertificate); - if (string.IsNullOrWhiteSpace(cert)) + if (!string.IsNullOrWhiteSpace(cert)) { logger.LogInfo("No certificate configured for Dependabot proxy."); - return; - } - var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); - Directory.CreateDirectory(certDirPath.FullName); + var certDirPath = new DirectoryInfo(Path.Join(tempWorkingDirectory.DirInfo.FullName, ".dependabot-proxy")); + Directory.CreateDirectory(certDirPath.FullName); + + result.CertificatePath = Path.Join(certDirPath.FullName, "proxy.crt"); + var certFile = new FileInfo(result.CertificatePath); - this.CertificatePath = Path.Join(certDirPath.FullName, "proxy.crt"); - this.certFile = new FileInfo(this.CertificatePath); + using var writer = certFile.CreateText(); + writer.Write(cert); - using var writer = this.certFile.CreateText(); - writer.Write(cert); + logger.LogInfo($"Stored Dependabot proxy certificate at {result.CertificatePath}"); - logger.LogInfo($"Stored Dependabot proxy certificate at {this.CertificatePath}"); + result.Certificate = new X509Certificate2(result.CertificatePath); + } - this.Certificate = new X509Certificate2(this.CertificatePath); + return result; } - internal void ApplyProxy(ILogger logger, ProcessStartInfo startInfo) + private DependabotProxy(string host, string port) { - // If the proxy isn't configured, we have nothing to do. - if (!this.IsConfigured) return; - - logger.LogInfo($"Setting up Dependabot proxy at {this.Address}"); - - startInfo.EnvironmentVariables.Add("HTTP_PROXY", this.Address); - startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.Address); - startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.certFile?.FullName); + this.host = host; + this.port = port; + this.Address = $"http://{this.host}:{this.port}"; } public void Dispose() { - if (this.Certificate != null) - { - this.Certificate.Dispose(); - } + this.Certificate?.Dispose(); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index bbd5ecbd127a..cf4c6d73bd65 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -27,7 +27,7 @@ public sealed partial class DependencyManager : IDisposable, ICompilationInfoCon private readonly ILogger logger; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly NugetPackageRestorer nugetPackageRestorer; - private readonly DependabotProxy dependabotProxy; + private readonly DependabotProxy? dependabotProxy; private readonly IDotNet dotnet; private readonly FileContent fileContent; private readonly FileProvider fileProvider; @@ -107,7 +107,7 @@ void exitCallback(int ret, string msg, bool silent) return BuildScript.Success; }).Run(SystemBuildActions.Instance, startCallback, exitCallback); - dependabotProxy = new DependabotProxy(logger, tempWorkingDirectory); + dependabotProxy = DependabotProxy.GetDependabotProxy(logger, tempWorkingDirectory); try { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index a82a0a47f415..c1fdcc06e91b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -27,11 +27,11 @@ private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDire Info(); } - private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { } + private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { } internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger); - public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); + public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); private void Info() { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index cdadfe1f5b8e..19f0f3dbe0d9 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -12,11 +12,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching internal sealed class DotNetCliInvoker : IDotNetCliInvoker { private readonly ILogger logger; - private readonly DependabotProxy proxy; + private readonly DependabotProxy? proxy; public string Exec { get; } - public DotNetCliInvoker(ILogger logger, string exec, DependabotProxy dependabotProxy) + public DotNetCliInvoker(ILogger logger, string exec, DependabotProxy? dependabotProxy) { this.logger = logger; this.proxy = dependabotProxy; @@ -42,7 +42,14 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto startInfo.EnvironmentVariables["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true"; // Configure the proxy settings, if applicable. - this.proxy.ApplyProxy(this.logger, startInfo); + if (this.proxy != null) + { + logger.LogInfo($"Setting up Dependabot proxy at {this.proxy.Address}"); + + startInfo.EnvironmentVariables.Add("HTTP_PROXY", this.proxy.Address); + startInfo.EnvironmentVariables.Add("HTTPS_PROXY", this.proxy.Address); + startInfo.EnvironmentVariables.Add("SSL_CERT_FILE", this.proxy.CertificatePath); + } return startInfo; } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 8ea25c72f369..1c90d3b7d89e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -22,7 +22,7 @@ internal sealed partial class NugetPackageRestorer : IDisposable private readonly FileProvider fileProvider; private readonly FileContent fileContent; private readonly IDotNet dotnet; - private readonly DependabotProxy dependabotProxy; + private readonly DependabotProxy? dependabotProxy; private readonly IDiagnosticsWriter diagnosticsWriter; private readonly TemporaryDirectory legacyPackageDirectory; private readonly TemporaryDirectory missingPackageDirectory; @@ -35,7 +35,7 @@ public NugetPackageRestorer( FileProvider fileProvider, FileContent fileContent, IDotNet dotnet, - DependabotProxy dependabotProxy, + DependabotProxy? dependabotProxy, IDiagnosticsWriter diagnosticsWriter, ILogger logger, ICompilationInfoContainer compilationInfoContainer) @@ -596,7 +596,7 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, // Configure the HttpClient to be aware of the Dependabot Proxy, if used. HttpClientHandler httpClientHandler = new(); - if (this.dependabotProxy.IsConfigured) + if (this.dependabotProxy != null) { httpClientHandler.Proxy = new WebProxy(this.dependabotProxy.Address); From 1569621605b9eb2ff089eb39b554af12e54ac672 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 5 Dec 2024 12:25:45 +0000 Subject: [PATCH 137/213] C#: Don't initialise `DependabotProxy` on Windows or macOS --- .../DependabotProxy.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index d1a5df4dbc5e..09f5a15a21d6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -27,6 +27,13 @@ public class DependabotProxy : IDisposable internal static DependabotProxy? GetDependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory) { + // Setting HTTP(S)_PROXY and SSL_CERT_FILE have no effect on Windows or macOS, + // but we would still end up using the Dependabot proxy to check for feed reachability. + // This would result in us discovering that the feeds are reachable, but `dotnet` would + // fail to connect to them. To prevent this from happening, we do not initialise an + // instance of `DependabotProxy` on those platforms. + if (SystemBuildActions.Instance.IsWindows() || SystemBuildActions.Instance.IsMacOs()) return null; + // Obtain and store the address of the Dependabot proxy, if available. var host = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyHost); var port = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyPort); From 671e61f3b36547a9a584c431f9c0022cc989f3c6 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 5 Dec 2024 12:32:55 +0000 Subject: [PATCH 138/213] C#: Fix possible null dereference --- .../DependencyManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index cf4c6d73bd65..b8773f0ae4a6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -545,7 +545,7 @@ private void AnalyseProject(FileInfo project) public void Dispose() { nugetPackageRestorer?.Dispose(); - dependabotProxy.Dispose(); + dependabotProxy?.Dispose(); if (cleanupTempWorkingDirectory) { tempWorkingDirectory?.Dispose(); From 0d206bd0bb25c5c344e9aa23b1f9ec3080125c00 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 6 Dec 2024 13:13:15 +0000 Subject: [PATCH 139/213] C#: Explicitly close writer in `DependabotProxy` --- .../DependabotProxy.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index 09f5a15a21d6..f3d92b38f0c8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -62,6 +62,7 @@ public class DependabotProxy : IDisposable using var writer = certFile.CreateText(); writer.Write(cert); + writer.Close(); logger.LogInfo($"Stored Dependabot proxy certificate at {result.CertificatePath}"); From 32d757f65c9527e9d03714d3d2e2f82b5f1d05e4 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 6 Dec 2024 13:13:41 +0000 Subject: [PATCH 140/213] C#: Create certificate from string, rather than file --- .../DependabotProxy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs index f3d92b38f0c8..895bd313ac30 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs @@ -66,7 +66,7 @@ public class DependabotProxy : IDisposable logger.LogInfo($"Stored Dependabot proxy certificate at {result.CertificatePath}"); - result.Certificate = new X509Certificate2(result.CertificatePath); + result.Certificate = X509Certificate2.CreateFromPem(cert); } return result; From 9b34615a645f420e7d2a6f4dabbdf77baf248d67 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 6 Dec 2024 19:05:53 +0100 Subject: [PATCH 141/213] Rust: Update test assertions to match results --- rust/ql/test/library-tests/variables/variables.expected | 4 ---- rust/ql/test/library-tests/variables/variables.rs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index d0141b2e1e80..1e3fc90633ce 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,8 +1,4 @@ testFailures -| variables.rs:493:13:493:16 | self | Unexpected result: read_access=self | -| variables.rs:493:25:493:25 | n | Unexpected result: read_access=n | -| variables.rs:495:9:495:9 | f | Unexpected result: read_access=f | -| variables.rs:496:9:496:9 | f | Unexpected result: read_access=f | variable | variables.rs:3:14:3:14 | s | | variables.rs:7:14:7:14 | i | diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index 73d350f24966..155ebaa8584a 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -490,10 +490,10 @@ impl MyStruct { fn my_method(&mut self) { let mut f = |n| { // Capture of `self` - self.val += n; + self.val += n; // $ read_access=self read_access=n }; - f(3); - f(4); + f(3); // $ read_access=f + f(4); // $ read_access=f } } From 3a3eb001e39523c19365df1706c5d7131b4642e2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 6 Dec 2024 19:53:06 +0100 Subject: [PATCH 142/213] C++: Fix word duplication in change note --- .../change-notes/2024-12-05-wrong-number-format-arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/change-notes/2024-12-05-wrong-number-format-arguments.md b/cpp/ql/src/change-notes/2024-12-05-wrong-number-format-arguments.md index abae2dfaa3db..6b41378f5569 100644 --- a/cpp/ql/src/change-notes/2024-12-05-wrong-number-format-arguments.md +++ b/cpp/ql/src/change-notes/2024-12-05-wrong-number-format-arguments.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The "Too few arguments to formatting function" query (`cpp/wrong-number-format-arguments`) query no longer produces results if an argument has an extraction error. +* The "Too few arguments to formatting function" query (`cpp/wrong-number-format-arguments`) no longer produces results if an argument has an extraction error. From a6a4ad6400accfaca6e4505d88208f8768d999c1 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Fri, 6 Dec 2024 19:00:27 +0000 Subject: [PATCH 143/213] Revert "Release preparation for version 2.20.0" --- cpp/ql/lib/CHANGELOG.md | 10 --------- .../2024-11-18-throwing-functions.md | 4 ++++ ...-12-03-remove-dataflow-config-class-api.md | 7 +++---- cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 10 --------- .../1.3.0.md => 2014-11-26-guarded-free.md} | 11 +++------- .../2024-11-22-too-few-arguments.md | 4 ++++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ---- .../lib/change-notes/released/1.7.30.md | 3 --- .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ---- .../src/change-notes/released/1.7.30.md | 3 --- .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 17 --------------- ...26-model-microsoft.jsinterop.ijsruntime.md | 5 +++++ ...onmanager.uri-and-uri-parsing-utilities.md | 8 +++++++ .../2024-12-03-dynamic-field-flow.md | 4 ++++ .../2024-12-03-public-protected-reference.md | 4 ++++ ...-12-03-remove-dataflow-config-class-api.md | 7 +++---- csharp/ql/lib/change-notes/released/4.0.0.md | 16 -------------- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 6 ------ ... 2024-11-28-db-quality-property-access.md} | 7 +++---- csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.13.md | 3 --- .../codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 14 ------------- ...-promoted-fields-and-methods-name-clash.md | 4 ++++ .../2024-11-20-heuristic-logging-sinks.md | 4 ++++ ...-12-03-remove-dataflow-config-class-api.md | 11 +++------- go/ql/lib/change-notes/released/3.0.0.md | 13 ------------ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 6 ------ ....md => 2024-11-26-model-slices-package.md} | 7 +++---- go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 10 --------- .../2024-11-04-list-of-constants-sanitizer.md | 4 ++++ ...-12-03-remove-dataflow-config-class-api.md | 11 +++------- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 8 ------- ...1.10.md => 2024-10-29-weak-crypto-hash.md} | 9 +++----- java/ql/src/change-notes/2024-11-22-sha3.md | 4 ++++ java/ql/src/change-notes/2024-11-24-sha2.md | 4 ++++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 21 +++---------------- .../2024-11-18-ES2022-find-functions.md | 5 +++++ ...-20-ES2023-string-protytpe-toWellFormed.md | 4 ++++ .../2024-11-20-ES2024-group-functions.md | 4 ++++ ....md => 2024-11-28-regexp-unknown-flags.md} | 14 +++---------- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ---- .../ql/src/change-notes/released/1.2.5.md | 3 --- javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.13.md | 3 --- misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 10 --------- .../2024-11-26-fix-match-cfg-pruning.md | 5 +++++ ...-12-03-remove-dataflow-config-class-api.md | 4 ++++ python/ql/lib/change-notes/released/3.0.0.md | 9 -------- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ---- python/ql/src/change-notes/released/1.3.4.md | 3 --- python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 6 ------ ...-12-03-remove-dataflow-config-class-api.md | 4 ++++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ---- ruby/ql/src/change-notes/released/1.1.8.md | 3 --- ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.13.md | 3 --- shared/controlflow/codeql-pack.release.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/CHANGELOG.md | 4 ---- .../dataflow/change-notes/released/1.1.7.md | 3 --- shared/dataflow/codeql-pack.release.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/CHANGELOG.md | 4 ---- shared/mad/change-notes/released/1.0.13.md | 3 --- shared/mad/codeql-pack.release.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.13.md | 3 --- shared/rangeanalysis/codeql-pack.release.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ---- shared/regex/change-notes/released/1.0.13.md | 3 --- shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ---- shared/ssa/change-notes/released/1.0.13.md | 3 --- shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.13.md | 3 --- shared/threat-models/codeql-pack.release.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ---- .../tutorial/change-notes/released/1.0.13.md | 3 --- shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/CHANGELOG.md | 4 ---- .../typeflow/change-notes/released/1.0.13.md | 3 --- shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.13.md | 3 --- shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ---- shared/typos/change-notes/released/1.0.13.md | 3 --- shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 6 ------ ...prected-inline-expecation-test-classes.md} | 7 +++---- shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/CHANGELOG.md | 4 ---- shared/xml/change-notes/released/1.0.13.md | 3 --- shared/xml/codeql-pack.release.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ---- shared/yaml/change-notes/released/1.0.13.md | 3 --- shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 6 ------ ...-12-03-remove-dataflow-config-class-api.md | 4 ++++ swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ---- swift/ql/src/change-notes/released/1.0.13.md | 3 --- swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 154 files changed, 180 insertions(+), 441 deletions(-) create mode 100644 cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md rename swift/ql/lib/change-notes/released/3.0.0.md => cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md (88%) rename cpp/ql/src/change-notes/{released/1.3.0.md => 2014-11-26-guarded-free.md} (52%) create mode 100644 cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md delete mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md delete mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md create mode 100644 csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md create mode 100644 csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md create mode 100644 csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md create mode 100644 csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md rename ruby/ql/lib/change-notes/released/3.0.0.md => csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md (88%) delete mode 100644 csharp/ql/lib/change-notes/released/4.0.0.md rename csharp/ql/src/change-notes/{released/1.0.13.md => 2024-11-28-db-quality-property-access.md} (85%) delete mode 100644 go/ql/consistency-queries/change-notes/released/1.0.13.md create mode 100644 go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md create mode 100644 go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md rename java/ql/lib/change-notes/released/5.0.0.md => go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md (56%) delete mode 100644 go/ql/lib/change-notes/released/3.0.0.md rename go/ql/src/change-notes/{released/1.1.4.md => 2024-11-26-model-slices-package.md} (70%) create mode 100644 java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md rename cpp/ql/lib/change-notes/released/3.0.0.md => java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md (55%) rename java/ql/src/change-notes/{released/1.1.10.md => 2024-10-29-weak-crypto-hash.md} (50%) create mode 100644 java/ql/src/change-notes/2024-11-22-sha3.md create mode 100644 java/ql/src/change-notes/2024-11-24-sha2.md create mode 100644 javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md create mode 100644 javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md create mode 100644 javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md rename javascript/ql/lib/change-notes/{released/2.2.0.md => 2024-11-28-regexp-unknown-flags.md} (52%) delete mode 100644 javascript/ql/src/change-notes/released/1.2.5.md delete mode 100644 misc/suite-helpers/change-notes/released/1.0.13.md create mode 100644 python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md create mode 100644 python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md delete mode 100644 python/ql/lib/change-notes/released/3.0.0.md delete mode 100644 python/ql/src/change-notes/released/1.3.4.md create mode 100644 ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md delete mode 100644 ruby/ql/src/change-notes/released/1.1.8.md delete mode 100644 shared/controlflow/change-notes/released/1.0.13.md delete mode 100644 shared/dataflow/change-notes/released/1.1.7.md delete mode 100644 shared/mad/change-notes/released/1.0.13.md delete mode 100644 shared/rangeanalysis/change-notes/released/1.0.13.md delete mode 100644 shared/regex/change-notes/released/1.0.13.md delete mode 100644 shared/ssa/change-notes/released/1.0.13.md delete mode 100644 shared/threat-models/change-notes/released/1.0.13.md delete mode 100644 shared/tutorial/change-notes/released/1.0.13.md delete mode 100644 shared/typeflow/change-notes/released/1.0.13.md delete mode 100644 shared/typetracking/change-notes/released/1.0.13.md delete mode 100644 shared/typos/change-notes/released/1.0.13.md rename shared/util/change-notes/{released/2.0.0.md => 2024-12-03-remove-deprected-inline-expecation-test-classes.md} (77%) delete mode 100644 shared/xml/change-notes/released/1.0.13.md delete mode 100644 shared/yaml/change-notes/released/1.0.13.md create mode 100644 swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md delete mode 100644 swift/ql/src/change-notes/released/1.0.13.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 4091ef97e4d7..d84fe585fca5 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,13 +1,3 @@ -## 3.0.0 - -### Breaking Changes - -* 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. - -### Deprecated APIs - -* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. - ## 2.1.1 No user-facing changes. 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 000000000000..73b358a0e1fc --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. \ No newline at end of file diff --git a/swift/ql/lib/change-notes/released/3.0.0.md b/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md similarity index 88% rename from swift/ql/lib/change-notes/released/3.0.0.md rename to cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md index 82b5c467407b..d09ec528c99e 100644 --- a/swift/ql/lib/change-notes/released/3.0.0.md +++ b/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -1,5 +1,4 @@ -## 3.0.0 - -### Breaking Changes - +--- +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/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 33d3a2cd1139..576c2ea18d68 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 3.0.0 +lastReleaseVersion: 2.1.1 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 723a2c3544e6..001028daae11 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 3.0.0 +version: 2.1.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 74781fe0f872..5bb266bdd649 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,13 +1,3 @@ -## 1.3.0 - -### New Queries - -* Added a new high-precision quality query, `cpp/guarded-free`, which detects useless NULL pointer checks before calls to `free`. A variation of this query was originally contributed as an [experimental query by @mario-campos](https://github.com/github/codeql/pull/16331). - -### Minor Analysis Improvements - -* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared. - ## 1.2.7 No user-facing changes. diff --git a/cpp/ql/src/change-notes/released/1.3.0.md b/cpp/ql/src/change-notes/2014-11-26-guarded-free.md similarity index 52% rename from cpp/ql/src/change-notes/released/1.3.0.md rename to cpp/ql/src/change-notes/2014-11-26-guarded-free.md index 1443206add85..4280025a04f6 100644 --- a/cpp/ql/src/change-notes/released/1.3.0.md +++ b/cpp/ql/src/change-notes/2014-11-26-guarded-free.md @@ -1,9 +1,4 @@ -## 1.3.0 - -### New Queries - +--- +category: newQuery +--- * Added a new high-precision quality query, `cpp/guarded-free`, which detects useless NULL pointer checks before calls to `free`. A variation of this query was originally contributed as an [experimental query by @mario-campos](https://github.com/github/codeql/pull/16331). - -### Minor Analysis Improvements - -* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared. diff --git a/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md b/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md new file mode 100644 index 000000000000..116df08838a1 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index ec16350ed6fd..950e0645d4a7 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.0 +lastReleaseVersion: 1.2.7 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 824ee1459aa4..2fcf45807da9 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.3.0 +version: 1.2.8-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index a71f93aacd46..93e737ae669d 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.7.30 - -No user-facing changes. - ## 1.7.29 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md deleted file mode 100644 index 8fb79827401a..000000000000 --- a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.7.30 - -No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index c0346e526b94..34100d3ad646 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.30 +lastReleaseVersion: 1.7.29 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index daac6be2fbb1..0c8db9920eb2 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.30 +version: 1.7.30-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index a71f93aacd46..93e737ae669d 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.7.30 - -No user-facing changes. - ## 1.7.29 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md deleted file mode 100644 index 8fb79827401a..000000000000 --- a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.7.30 - -No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index c0346e526b94..34100d3ad646 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.30 +lastReleaseVersion: 1.7.29 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 1b3b911c6f11..3a4343780e4d 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.30 +version: 1.7.30-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 86f279365f09..c76569e4ab30 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,20 +1,3 @@ -## 4.0.0 - -### Breaking Changes - -* 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. - -### Minor Analysis Improvements - -* Added support for data-flow through member accesses of objects with `dynamic` types. -* Only extract *public* and *protected* members from reference assemblies. This yields an approximate average speed-up of around 10% for extraction and query execution. Custom MaD rows using `Field`-based summaries may need to be changed to `SyntheticField`-based flows if they reference private fields. -* Added `Microsoft.AspNetCore.Components.NagivationManager::Uri` as a remote flow source, since this value may contain user-specified values. -* Added the following URI-parsing methods as summaries, as they may be tainted with user-specified values: - - `System.Web.HttpUtility::ParseQueryString` - - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseQuery` - - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseNullableQuery` -* Added `js-interop` sinks for the `InvokeAsync` and `InvokeVoidAsync` methods of `Microsoft.JSInterop.IJSRuntime`, which can run arbitrary JavaScript. - ## 3.1.1 ### Minor Analysis Improvements diff --git a/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md b/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md new file mode 100644 index 000000000000..a99f9c8e0fd3 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added `js-interop` sinks for the `InvokeAsync` and `InvokeVoidAsync` methods of `Microsoft.JSInterop.IJSRuntime`, which can run arbitrary JavaScript. + diff --git a/csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md b/csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md new file mode 100644 index 000000000000..2d9866c2e158 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md @@ -0,0 +1,8 @@ +--- +category: minorAnalysis +--- +* Added `Microsoft.AspNetCore.Components.NagivationManager::Uri` as a remote flow source, since this value may contain user-specified values. +* Added the following URI-parsing methods as summaries, as they may be tainted with user-specified values: + - `System.Web.HttpUtility::ParseQueryString` + - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseQuery` + - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseNullableQuery` diff --git a/csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md b/csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md new file mode 100644 index 000000000000..4d5f8f9258e1 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added support for data-flow through member accesses of objects with `dynamic` types. diff --git a/csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md b/csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md new file mode 100644 index 000000000000..7b284df36526 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Only extract *public* and *protected* members from reference assemblies. This yields an approximate average speed-up of around 10% for extraction and query execution. Custom MaD rows using `Field`-based summaries may need to be changed to `SyntheticField`-based flows if they reference private fields. diff --git a/ruby/ql/lib/change-notes/released/3.0.0.md b/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md similarity index 88% rename from ruby/ql/lib/change-notes/released/3.0.0.md rename to csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md index 82b5c467407b..d09ec528c99e 100644 --- a/ruby/ql/lib/change-notes/released/3.0.0.md +++ b/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -1,5 +1,4 @@ -## 3.0.0 - -### Breaking Changes - +--- +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/released/4.0.0.md b/csharp/ql/lib/change-notes/released/4.0.0.md deleted file mode 100644 index 2a64ac002329..000000000000 --- a/csharp/ql/lib/change-notes/released/4.0.0.md +++ /dev/null @@ -1,16 +0,0 @@ -## 4.0.0 - -### Breaking Changes - -* 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. - -### Minor Analysis Improvements - -* Added support for data-flow through member accesses of objects with `dynamic` types. -* Only extract *public* and *protected* members from reference assemblies. This yields an approximate average speed-up of around 10% for extraction and query execution. Custom MaD rows using `Field`-based summaries may need to be changed to `SyntheticField`-based flows if they reference private fields. -* Added `Microsoft.AspNetCore.Components.NagivationManager::Uri` as a remote flow source, since this value may contain user-specified values. -* Added the following URI-parsing methods as summaries, as they may be tainted with user-specified values: - - `System.Web.HttpUtility::ParseQueryString` - - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseQuery` - - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseNullableQuery` -* Added `js-interop` sinks for the `InvokeAsync` and `InvokeVoidAsync` methods of `Microsoft.JSInterop.IJSRuntime`, which can run arbitrary JavaScript. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 49fe3eef6973..c06beda86a3a 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 4.0.0 +lastReleaseVersion: 3.1.1 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index d985d58b1128..efc82eedc906 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 4.0.0 +version: 3.1.2-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 370a9cf4a6a2..99528b54e9ea 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,9 +1,3 @@ -## 1.0.13 - -### Minor Analysis Improvements - -* `csharp/diagnostic/database-quality` has been changed to exclude various property access expressions from database quality evaluation. The excluded property access expressions are expected to have no target callables even in manual or autobuilt databases. - ## 1.0.12 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/1.0.13.md b/csharp/ql/src/change-notes/2024-11-28-db-quality-property-access.md similarity index 85% rename from csharp/ql/src/change-notes/released/1.0.13.md rename to csharp/ql/src/change-notes/2024-11-28-db-quality-property-access.md index cfce05a87336..212c01f24bbe 100644 --- a/csharp/ql/src/change-notes/released/1.0.13.md +++ b/csharp/ql/src/change-notes/2024-11-28-db-quality-property-access.md @@ -1,5 +1,4 @@ -## 1.0.13 - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * `csharp/diagnostic/database-quality` has been changed to exclude various property access expressions from database quality evaluation. The excluded property access expressions are expected to have no target callables even in manual or autobuilt databases. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index f838d279d87b..569b69021d1d 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.0.13 +version: 1.0.13-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index 3c6fa155a322..eeb6b0a262a3 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/1.0.13.md b/go/ql/consistency-queries/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/go/ql/consistency-queries/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 72aeab276d7c..60d11115c14c 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.13 +version: 1.0.13-dev groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 83052b3a1d9b..b2eb3cbb2392 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,17 +1,3 @@ -## 3.0.0 - -### Breaking Changes - -* 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. - -### Minor Analysis Improvements - -* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn" or "With" defined on an interface whose name ends in "logger" or "Logger" is now considered a LoggerCall. In particular, it is a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. - -### Bug Fixes - -* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. - ## 2.1.3 ### Minor Analysis Improvements diff --git a/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md b/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md new file mode 100644 index 000000000000..8b1ee9b60b23 --- /dev/null +++ b/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. diff --git a/go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md b/go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md new file mode 100644 index 000000000000..46f5988b3798 --- /dev/null +++ b/go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn" or "With" defined on an interface whose name ends in "logger" or "Logger" is now considered a LoggerCall. In particular, it is a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. diff --git a/java/ql/lib/change-notes/released/5.0.0.md b/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md similarity index 56% rename from java/ql/lib/change-notes/released/5.0.0.md rename to go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md index 9d9e2bc61b54..d09ec528c99e 100644 --- a/java/ql/lib/change-notes/released/5.0.0.md +++ b/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -1,9 +1,4 @@ -## 5.0.0 - -### Breaking Changes - +--- +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. - -### Minor Analysis Improvements - -* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. diff --git a/go/ql/lib/change-notes/released/3.0.0.md b/go/ql/lib/change-notes/released/3.0.0.md deleted file mode 100644 index 5aafa0c29d14..000000000000 --- a/go/ql/lib/change-notes/released/3.0.0.md +++ /dev/null @@ -1,13 +0,0 @@ -## 3.0.0 - -### Breaking Changes - -* 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. - -### Minor Analysis Improvements - -* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn" or "With" defined on an interface whose name ends in "logger" or "Logger" is now considered a LoggerCall. In particular, it is a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. - -### Bug Fixes - -* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 33d3a2cd1139..345fb0c73a44 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 3.0.0 +lastReleaseVersion: 2.1.3 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index df0d0e9d5fce..98e81430897c 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 3.0.0 +version: 2.1.4-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index c9044e55cdcb..c529cbffb328 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,9 +1,3 @@ -## 1.1.4 - -### Minor Analysis Improvements - -* Added value flow models for functions in the `slices` package which do not involve the `iter` package. - ## 1.1.3 No user-facing changes. diff --git a/go/ql/src/change-notes/released/1.1.4.md b/go/ql/src/change-notes/2024-11-26-model-slices-package.md similarity index 70% rename from go/ql/src/change-notes/released/1.1.4.md rename to go/ql/src/change-notes/2024-11-26-model-slices-package.md index 0437ebd2bd68..5a3141c8075a 100644 --- a/go/ql/src/change-notes/released/1.1.4.md +++ b/go/ql/src/change-notes/2024-11-26-model-slices-package.md @@ -1,5 +1,4 @@ -## 1.1.4 - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * Added value flow models for functions in the `slices` package which do not involve the `iter` package. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 26cbcd3f123b..35e710ab1bf0 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.4 +lastReleaseVersion: 1.1.3 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index ecd9cbb13f0e..866a09357130 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.1.4 +version: 1.1.4-dev groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 09ee80087e8b..990fea9ddd7c 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,13 +1,3 @@ -## 5.0.0 - -### Breaking Changes - -* 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. - -### Minor Analysis Improvements - -* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. - ## 4.2.1 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md b/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md new file mode 100644 index 000000000000..dea1e7ff81e1 --- /dev/null +++ b/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. diff --git a/cpp/ql/lib/change-notes/released/3.0.0.md b/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md similarity index 55% rename from cpp/ql/lib/change-notes/released/3.0.0.md rename to java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md index 5945c94c566d..d09ec528c99e 100644 --- a/cpp/ql/lib/change-notes/released/3.0.0.md +++ b/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -1,9 +1,4 @@ -## 3.0.0 - -### Breaking Changes - +--- +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. - -### Deprecated APIs - -* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index c9e54136ca5c..38ea9976fccd 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.0.0 +lastReleaseVersion: 4.2.1 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 54f56a246062..a8c1ee2de2b1 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 5.0.0 +version: 4.2.2-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 0bb38874b82f..f212b4a8d3d7 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,11 +1,3 @@ -## 1.1.10 - -### Minor Analysis Improvements - -* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384. -* Added SHA3 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA3. -* The `java/weak-cryptographic-algorithm` query has been updated to no longer report uses of hash functions such as `MD5` and `SHA1` even if they are known to be weak. These hash algorithms are used very often in non-sensitive contexts, making the query too imprecise in practice. The `java/potentially-weak-cryptographic-algorithm` query has been updated to report these uses instead. - ## 1.1.9 No user-facing changes. diff --git a/java/ql/src/change-notes/released/1.1.10.md b/java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md similarity index 50% rename from java/ql/src/change-notes/released/1.1.10.md rename to java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md index fef22bdedf57..b4ac88bcdc6a 100644 --- a/java/ql/src/change-notes/released/1.1.10.md +++ b/java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md @@ -1,7 +1,4 @@ -## 1.1.10 - -### Minor Analysis Improvements - -* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384. -* Added SHA3 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA3. +--- +category: minorAnalysis +--- * The `java/weak-cryptographic-algorithm` query has been updated to no longer report uses of hash functions such as `MD5` and `SHA1` even if they are known to be weak. These hash algorithms are used very often in non-sensitive contexts, making the query too imprecise in practice. The `java/potentially-weak-cryptographic-algorithm` query has been updated to report these uses instead. diff --git a/java/ql/src/change-notes/2024-11-22-sha3.md b/java/ql/src/change-notes/2024-11-22-sha3.md new file mode 100644 index 000000000000..61dbc35162e1 --- /dev/null +++ b/java/ql/src/change-notes/2024-11-22-sha3.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added SHA3 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA3. diff --git a/java/ql/src/change-notes/2024-11-24-sha2.md b/java/ql/src/change-notes/2024-11-24-sha2.md new file mode 100644 index 000000000000..395ea04b782e --- /dev/null +++ b/java/ql/src/change-notes/2024-11-24-sha2.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 4c01918d4144..6f4795f3ea0b 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.10 +lastReleaseVersion: 1.1.9 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index eb757401a840..44740683f142 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.1.10 +version: 1.1.10-dev groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index ebe424935eb9..7d8f8dcfc8bf 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,27 +1,12 @@ -## 2.2.0 - -### Major Analysis Improvements - -* The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals. -* Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases. -* Regular expression related queries now account for unknown flags. - -### Minor Analysis Improvements - -* Added taint-steps for `String.prototype.toWellFormed`. -* Added taint-steps for `Map.groupBy` and `Object.groupBy`. -* Added taint-steps for `Array.prototype.findLast`. -* Added taint-steps for `Array.prototype.findLastIndex`. - ## 2.1.1 ### Minor Analysis Improvements -* Added taint-steps for `Array.prototype.with`. -* Added taint-steps for `Array.prototype.toSpliced` +Added taint-steps for `Array.prototype.with`. +Added taint-steps for `Array.prototype.toSpliced` * Added taint-steps for `Array.prototype.toReversed`. * Added taint-steps for `Array.prototype.toSorted`. -* Added support for `String.prototype.matchAll`. +Added support for `String.prototype.matchAll`. * Added taint-steps for `Array.prototype.reverse` ## 2.1.0 diff --git a/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md b/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md new file mode 100644 index 000000000000..e3fe3b6aef25 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added taint-steps for `Array.prototype.findLast` +* Added taint-steps for `Array.prototype.findLastIndex` diff --git a/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md b/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md new file mode 100644 index 000000000000..dda4d8787605 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added taint-steps for `String.prototype.toWellFormed`. diff --git a/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md b/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md new file mode 100644 index 000000000000..8511727f8e77 --- /dev/null +++ b/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added taint-steps for `Map.groupBy` and `Object.groupBy`. diff --git a/javascript/ql/lib/change-notes/released/2.2.0.md b/javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md similarity index 52% rename from javascript/ql/lib/change-notes/released/2.2.0.md rename to javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md index f8c194f73f8a..e1db79e5c86d 100644 --- a/javascript/ql/lib/change-notes/released/2.2.0.md +++ b/javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md @@ -1,14 +1,6 @@ -## 2.2.0 - -### Major Analysis Improvements - +--- +category: majorAnalysis +--- * The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals. * Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases. * Regular expression related queries now account for unknown flags. - -### Minor Analysis Improvements - -* Added taint-steps for `String.prototype.toWellFormed`. -* Added taint-steps for `Map.groupBy` and `Object.groupBy`. -* Added taint-steps for `Array.prototype.findLast`. -* Added taint-steps for `Array.prototype.findLastIndex`. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 2f3083541950..576c2ea18d68 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.2.0 +lastReleaseVersion: 2.1.1 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 4245aa6e5d35..9726d407e1af 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.2.0 +version: 2.1.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 195298ec89f1..403de6b33237 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.2.5 - -No user-facing changes. - ## 1.2.4 No user-facing changes. diff --git a/javascript/ql/src/change-notes/released/1.2.5.md b/javascript/ql/src/change-notes/released/1.2.5.md deleted file mode 100644 index c805dc2cd4c3..000000000000 --- a/javascript/ql/src/change-notes/released/1.2.5.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.2.5 - -No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 40355f0807f9..172090f46b6d 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.2.5 +lastReleaseVersion: 1.2.4 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index ba7c502b29fa..a1efe30e69d1 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 1.2.5 +version: 1.2.5-dev groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 5d46c57bf4e2..969419cb7b7e 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/1.0.13.md b/misc/suite-helpers/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/misc/suite-helpers/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 834362022be8..e2cbd7f3f9d4 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.13 +version: 1.0.13-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 81c7659c4edd..34dc5f1b060b 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,13 +1,3 @@ -## 3.0.0 - -### Breaking Changes - -* 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. - -### Bug Fixes - -- Fixed a problem with the control-flow graph construction, where writing `case True:` or `case False:` would cause parts of the graph to be pruned by mistake. - ## 2.2.0 ### Major Analysis Improvements diff --git a/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md b/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md new file mode 100644 index 000000000000..3ee1094c13b7 --- /dev/null +++ b/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md @@ -0,0 +1,5 @@ +--- +category: fix +--- + +- Fixed a problem with the control-flow graph construction, where writing `case True:` or `case False:` would cause parts of the graph to be pruned by mistake. 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 000000000000..d09ec528c99e --- /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/python/ql/lib/change-notes/released/3.0.0.md b/python/ql/lib/change-notes/released/3.0.0.md deleted file mode 100644 index d57189465d86..000000000000 --- a/python/ql/lib/change-notes/released/3.0.0.md +++ /dev/null @@ -1,9 +0,0 @@ -## 3.0.0 - -### Breaking Changes - -* 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. - -### Bug Fixes - -- Fixed a problem with the control-flow graph construction, where writing `case True:` or `case False:` would cause parts of the graph to be pruned by mistake. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 33d3a2cd1139..2f3083541950 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 3.0.0 +lastReleaseVersion: 2.2.0 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 978dfd96a834..290189efa132 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 3.0.0 +version: 2.2.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index c247e217acf3..5fea597a7a39 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.3.4 - -No user-facing changes. - ## 1.3.3 No user-facing changes. diff --git a/python/ql/src/change-notes/released/1.3.4.md b/python/ql/src/change-notes/released/1.3.4.md deleted file mode 100644 index 5073aca7222c..000000000000 --- a/python/ql/src/change-notes/released/1.3.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.3.4 - -No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 8263ddf2c8b8..eb1f7dabc842 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.4 +lastReleaseVersion: 1.3.3 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index bff5afdf8177..d84402123dc8 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.3.4 +version: 1.3.4-dev groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 737903a3232f..37248cf49600 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,9 +1,3 @@ -## 3.0.0 - -### Breaking Changes - -* 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. - ## 2.0.4 No user-facing changes. 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 000000000000..d09ec528c99e --- /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/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 33d3a2cd1139..0f306f8bd3bd 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 3.0.0 +lastReleaseVersion: 2.0.4 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 41b72629a67b..97259f5dd36d 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 3.0.0 +version: 2.0.5-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 5fe04780136b..e159e9fda368 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.1.8 - -No user-facing changes. - ## 1.1.7 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/1.1.8.md b/ruby/ql/src/change-notes/released/1.1.8.md deleted file mode 100644 index f4fe325b3350..000000000000 --- a/ruby/ql/src/change-notes/released/1.1.8.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.1.8 - -No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 64972659c426..759105565166 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.8 +lastReleaseVersion: 1.1.7 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 7f337d89d6a4..26ac8866ae02 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.1.8 +version: 1.1.8-dev groups: - ruby - queries diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index 285b39a43598..b6de6379e774 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/1.0.13.md b/shared/controlflow/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/controlflow/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index 5401179ac965..da4368217d3a 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index df038524d2d2..7eec34670dc0 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.1.7 - -No user-facing changes. - ## 1.1.6 No user-facing changes. diff --git a/shared/dataflow/change-notes/released/1.1.7.md b/shared/dataflow/change-notes/released/1.1.7.md deleted file mode 100644 index 81505c0507a2..000000000000 --- a/shared/dataflow/change-notes/released/1.1.7.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.1.7 - -No user-facing changes. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 759105565166..9e712a00a21d 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.7 +lastReleaseVersion: 1.1.6 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 55eb216cc54d..15f77aa0a3a2 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 1.1.7 +version: 1.1.7-dev groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 93a528a4f3c8..8eb5e03400a4 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/mad/change-notes/released/1.0.13.md b/shared/mad/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/mad/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 5c37e6090299..8ce60ad0cc9f 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index 6b25d16e0f73..cedd38e3e303 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/1.0.13.md b/shared/rangeanalysis/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/rangeanalysis/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index bd33c35fe53a..ee5954cae0b1 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 54c3ed2b3070..3e8a99103fe1 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/regex/change-notes/released/1.0.13.md b/shared/regex/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/regex/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 07d9f87eb8ce..34aa1065398c 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 01c19388c92f..b98345f361cc 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/ssa/change-notes/released/1.0.13.md b/shared/ssa/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/ssa/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 9a2027d0706d..145cd9e2192e 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index 3c6fa155a322..eeb6b0a262a3 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/1.0.13.md b/shared/threat-models/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/threat-models/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index d29bd36dd83b..16ca1fe3a887 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.13 +version: 1.0.13-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index 1f4e7ad4ed3d..da467b3de30c 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/1.0.13.md b/shared/tutorial/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/tutorial/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index e618abb068b5..14cbbbdc0675 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index dd8fb7a60b2a..cae361ea7e70 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/typeflow/change-notes/released/1.0.13.md b/shared/typeflow/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/typeflow/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index e9d46c074e81..5a659a4559d2 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index 0ab05873af4d..96110cb10a25 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/1.0.13.md b/shared/typetracking/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/typetracking/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 9e4717670a7e..216cc8696d91 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index c0c3cea39485..83fb2dfb4cc7 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/typos/change-notes/released/1.0.13.md b/shared/typos/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/typos/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b3ed91c0926e..8c1a93efe5e8 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index e03d990b7471..15c3b8c6225e 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,9 +1,3 @@ -## 2.0.0 - -### Breaking Changes - -* Deleted the old deprecated inline expectation test API that was based on the `InlineExpectationsTest` class. - ## 1.0.12 No user-facing changes. diff --git a/shared/util/change-notes/released/2.0.0.md b/shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md similarity index 77% rename from shared/util/change-notes/released/2.0.0.md rename to shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md index 513290e952ba..6126e37b619e 100644 --- a/shared/util/change-notes/released/2.0.0.md +++ b/shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md @@ -1,5 +1,4 @@ -## 2.0.0 - -### Breaking Changes - +--- +category: breaking +--- * Deleted the old deprecated inline expectation test API that was based on the `InlineExpectationsTest` class. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index 0abe6ccede0f..2036690b201f 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.0 +lastReleaseVersion: 1.0.12 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 4b66bd8ad928..83284f19cc32 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.0 +version: 1.0.13-dev groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index c3ebc31994b2..c8213742dc9f 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/xml/change-notes/released/1.0.13.md b/shared/xml/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/xml/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 8d8b1b8ee54e..f48f41ef3ffe 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 28fcbceec8ef..2cc2ec620572 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/shared/yaml/change-notes/released/1.0.13.md b/shared/yaml/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/shared/yaml/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 998a94f4bbfb..54880a8cf2fd 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.13 +version: 1.0.13-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index ba76b51c80e3..898a3282bb5a 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,9 +1,3 @@ -## 3.0.0 - -### Breaking Changes - -* 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. - ## 2.0.4 No user-facing changes. 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 000000000000..d09ec528c99e --- /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. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 33d3a2cd1139..0f306f8bd3bd 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 3.0.0 +lastReleaseVersion: 2.0.4 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 66fd8af358e9..2e855546d50c 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 3.0.0 +version: 2.0.5-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 73ac6bef86d7..76de7db13480 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.13 - -No user-facing changes. - ## 1.0.12 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/1.0.13.md b/swift/ql/src/change-notes/released/1.0.13.md deleted file mode 100644 index 378f97eeb1bd..000000000000 --- a/swift/ql/src/change-notes/released/1.0.13.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.13 - -No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index c3be7eb77163..2036690b201f 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.13 +lastReleaseVersion: 1.0.12 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index ee53e55fe41b..1d9f7154cdae 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.0.13 +version: 1.0.13-dev groups: - swift - queries From 8c64648520e312b5d201ead28bdd4e567b8a1b23 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Dec 2024 19:10:28 +0000 Subject: [PATCH 144/213] Release preparation for version 2.20.0 --- cpp/ql/lib/CHANGELOG.md | 10 +++++++++ .../2024-11-18-throwing-functions.md | 4 ---- .../ql/lib/change-notes/released/3.0.0.md | 11 +++++++--- cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 10 +++++++++ .../2024-11-22-too-few-arguments.md | 4 ---- .../1.3.0.md} | 11 +++++++--- cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../lib/change-notes/released/1.7.30.md | 3 +++ .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../src/change-notes/released/1.7.30.md | 3 +++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 17 +++++++++++++++ ...26-model-microsoft.jsinterop.ijsruntime.md | 5 ----- ...onmanager.uri-and-uri-parsing-utilities.md | 8 ------- .../2024-12-03-dynamic-field-flow.md | 4 ---- .../2024-12-03-public-protected-reference.md | 4 ---- csharp/ql/lib/change-notes/released/4.0.0.md | 16 ++++++++++++++ csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 6 ++++++ .../1.0.13.md} | 7 ++++--- csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.13.md | 3 +++ .../codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 14 +++++++++++++ ...-promoted-fields-and-methods-name-clash.md | 4 ---- .../2024-11-20-heuristic-logging-sinks.md | 4 ---- go/ql/lib/change-notes/released/3.0.0.md | 13 ++++++++++++ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 6 ++++++ .../1.1.4.md} | 7 ++++--- go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 10 +++++++++ .../2024-11-04-list-of-constants-sanitizer.md | 4 ---- .../ql/lib/change-notes/released/5.0.0.md | 11 +++++++--- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 8 +++++++ java/ql/src/change-notes/2024-11-22-sha3.md | 4 ---- java/ql/src/change-notes/2024-11-24-sha2.md | 4 ---- .../1.1.10.md} | 9 +++++--- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 21 ++++++++++++++++--- .../2024-11-18-ES2022-find-functions.md | 5 ----- ...-20-ES2023-string-protytpe-toWellFormed.md | 4 ---- .../2024-11-20-ES2024-group-functions.md | 4 ---- .../2.2.0.md} | 14 ++++++++++--- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ++++ .../ql/src/change-notes/released/1.2.5.md | 3 +++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.13.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 10 +++++++++ .../2024-11-26-fix-match-cfg-pruning.md | 5 ----- ...-12-03-remove-dataflow-config-class-api.md | 4 ---- python/ql/lib/change-notes/released/3.0.0.md | 9 ++++++++ python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/1.3.4.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 6 ++++++ ...-12-03-remove-dataflow-config-class-api.md | 4 ---- .../ql/lib/change-notes/released/3.0.0.md | 7 ++++--- ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++++ ruby/ql/src/change-notes/released/1.1.8.md | 3 +++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.13.md | 3 +++ shared/controlflow/codeql-pack.release.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/CHANGELOG.md | 4 ++++ .../dataflow/change-notes/released/1.1.7.md | 3 +++ shared/dataflow/codeql-pack.release.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/CHANGELOG.md | 4 ++++ shared/mad/change-notes/released/1.0.13.md | 3 +++ shared/mad/codeql-pack.release.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.13.md | 3 +++ shared/rangeanalysis/codeql-pack.release.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++++ shared/regex/change-notes/released/1.0.13.md | 3 +++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/1.0.13.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.13.md | 3 +++ shared/threat-models/codeql-pack.release.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++++ .../tutorial/change-notes/released/1.0.13.md | 3 +++ shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/CHANGELOG.md | 4 ++++ .../typeflow/change-notes/released/1.0.13.md | 3 +++ shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.13.md | 3 +++ shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/1.0.13.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 6 ++++++ .../2.0.0.md} | 7 ++++--- shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/CHANGELOG.md | 4 ++++ shared/xml/change-notes/released/1.0.13.md | 3 +++ shared/xml/codeql-pack.release.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++++ shared/yaml/change-notes/released/1.0.13.md | 3 +++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 6 ++++++ ...-12-03-remove-dataflow-config-class-api.md | 4 ---- .../ql/lib/change-notes/released/3.0.0.md | 7 ++++--- swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ++++ swift/ql/src/change-notes/released/1.0.13.md | 3 +++ swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 154 files changed, 441 insertions(+), 180 deletions(-) delete mode 100644 cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md rename go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md => cpp/ql/lib/change-notes/released/3.0.0.md (55%) delete mode 100644 cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md rename cpp/ql/src/change-notes/{2014-11-26-guarded-free.md => released/1.3.0.md} (52%) create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md delete mode 100644 csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md delete mode 100644 csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md delete mode 100644 csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md delete mode 100644 csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md create mode 100644 csharp/ql/lib/change-notes/released/4.0.0.md rename csharp/ql/src/change-notes/{2024-11-28-db-quality-property-access.md => released/1.0.13.md} (85%) create mode 100644 go/ql/consistency-queries/change-notes/released/1.0.13.md delete mode 100644 go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md delete mode 100644 go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md create mode 100644 go/ql/lib/change-notes/released/3.0.0.md rename go/ql/src/change-notes/{2024-11-26-model-slices-package.md => released/1.1.4.md} (70%) delete mode 100644 java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md rename csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md => java/ql/lib/change-notes/released/5.0.0.md (56%) delete mode 100644 java/ql/src/change-notes/2024-11-22-sha3.md delete mode 100644 java/ql/src/change-notes/2024-11-24-sha2.md rename java/ql/src/change-notes/{2024-10-29-weak-crypto-hash.md => released/1.1.10.md} (50%) delete mode 100644 javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md delete mode 100644 javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md delete mode 100644 javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md rename javascript/ql/lib/change-notes/{2024-11-28-regexp-unknown-flags.md => released/2.2.0.md} (52%) create mode 100644 javascript/ql/src/change-notes/released/1.2.5.md create mode 100644 misc/suite-helpers/change-notes/released/1.0.13.md delete mode 100644 python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md delete mode 100644 python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md create mode 100644 python/ql/lib/change-notes/released/3.0.0.md create mode 100644 python/ql/src/change-notes/released/1.3.4.md delete mode 100644 ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md rename java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md => ruby/ql/lib/change-notes/released/3.0.0.md (88%) create mode 100644 ruby/ql/src/change-notes/released/1.1.8.md create mode 100644 shared/controlflow/change-notes/released/1.0.13.md create mode 100644 shared/dataflow/change-notes/released/1.1.7.md create mode 100644 shared/mad/change-notes/released/1.0.13.md create mode 100644 shared/rangeanalysis/change-notes/released/1.0.13.md create mode 100644 shared/regex/change-notes/released/1.0.13.md create mode 100644 shared/ssa/change-notes/released/1.0.13.md create mode 100644 shared/threat-models/change-notes/released/1.0.13.md create mode 100644 shared/tutorial/change-notes/released/1.0.13.md create mode 100644 shared/typeflow/change-notes/released/1.0.13.md create mode 100644 shared/typetracking/change-notes/released/1.0.13.md create mode 100644 shared/typos/change-notes/released/1.0.13.md rename shared/util/change-notes/{2024-12-03-remove-deprected-inline-expecation-test-classes.md => released/2.0.0.md} (77%) create mode 100644 shared/xml/change-notes/released/1.0.13.md create mode 100644 shared/yaml/change-notes/released/1.0.13.md delete mode 100644 swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md rename cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md => swift/ql/lib/change-notes/released/3.0.0.md (88%) create mode 100644 swift/ql/src/change-notes/released/1.0.13.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index d84fe585fca5..4091ef97e4d7 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 3.0.0 + +### Breaking Changes + +* 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. + +### Deprecated APIs + +* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. + ## 2.1.1 No user-facing changes. 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 deleted file mode 100644 index 73b358a0e1fc..000000000000 --- a/cpp/ql/lib/change-notes/2024-11-18-throwing-functions.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: deprecated ---- -* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. \ No newline at end of file diff --git a/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/cpp/ql/lib/change-notes/released/3.0.0.md similarity index 55% rename from go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md rename to cpp/ql/lib/change-notes/released/3.0.0.md index d09ec528c99e..5945c94c566d 100644 --- a/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md +++ b/cpp/ql/lib/change-notes/released/3.0.0.md @@ -1,4 +1,9 @@ ---- -category: breaking ---- +## 3.0.0 + +### Breaking Changes + * 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. + +### Deprecated APIs + +* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 576c2ea18d68..33d3a2cd1139 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.1 +lastReleaseVersion: 3.0.0 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 001028daae11..723a2c3544e6 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 2.1.2-dev +version: 3.0.0 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 5bb266bdd649..74781fe0f872 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.3.0 + +### New Queries + +* Added a new high-precision quality query, `cpp/guarded-free`, which detects useless NULL pointer checks before calls to `free`. A variation of this query was originally contributed as an [experimental query by @mario-campos](https://github.com/github/codeql/pull/16331). + +### Minor Analysis Improvements + +* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared. + ## 1.2.7 No user-facing changes. diff --git a/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md b/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md deleted file mode 100644 index 116df08838a1..000000000000 --- a/cpp/ql/src/change-notes/2024-11-22-too-few-arguments.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared. diff --git a/cpp/ql/src/change-notes/2014-11-26-guarded-free.md b/cpp/ql/src/change-notes/released/1.3.0.md similarity index 52% rename from cpp/ql/src/change-notes/2014-11-26-guarded-free.md rename to cpp/ql/src/change-notes/released/1.3.0.md index 4280025a04f6..1443206add85 100644 --- a/cpp/ql/src/change-notes/2014-11-26-guarded-free.md +++ b/cpp/ql/src/change-notes/released/1.3.0.md @@ -1,4 +1,9 @@ ---- -category: newQuery ---- +## 1.3.0 + +### New Queries + * Added a new high-precision quality query, `cpp/guarded-free`, which detects useless NULL pointer checks before calls to `free`. A variation of this query was originally contributed as an [experimental query by @mario-campos](https://github.com/github/codeql/pull/16331). + +### Minor Analysis Improvements + +* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 950e0645d4a7..ec16350ed6fd 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.2.7 +lastReleaseVersion: 1.3.0 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 2fcf45807da9..824ee1459aa4 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.2.8-dev +version: 1.3.0 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 93e737ae669d..a71f93aacd46 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.30 + +No user-facing changes. + ## 1.7.29 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md new file mode 100644 index 000000000000..8fb79827401a --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.30.md @@ -0,0 +1,3 @@ +## 1.7.30 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 34100d3ad646..c0346e526b94 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.29 +lastReleaseVersion: 1.7.30 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 0c8db9920eb2..daac6be2fbb1 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.30-dev +version: 1.7.30 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 93e737ae669d..a71f93aacd46 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.30 + +No user-facing changes. + ## 1.7.29 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md new file mode 100644 index 000000000000..8fb79827401a --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.30.md @@ -0,0 +1,3 @@ +## 1.7.30 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 34100d3ad646..c0346e526b94 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.29 +lastReleaseVersion: 1.7.30 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 3a4343780e4d..1b3b911c6f11 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.30-dev +version: 1.7.30 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index c76569e4ab30..86f279365f09 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,20 @@ +## 4.0.0 + +### Breaking Changes + +* 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. + +### Minor Analysis Improvements + +* Added support for data-flow through member accesses of objects with `dynamic` types. +* Only extract *public* and *protected* members from reference assemblies. This yields an approximate average speed-up of around 10% for extraction and query execution. Custom MaD rows using `Field`-based summaries may need to be changed to `SyntheticField`-based flows if they reference private fields. +* Added `Microsoft.AspNetCore.Components.NagivationManager::Uri` as a remote flow source, since this value may contain user-specified values. +* Added the following URI-parsing methods as summaries, as they may be tainted with user-specified values: + - `System.Web.HttpUtility::ParseQueryString` + - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseQuery` + - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseNullableQuery` +* Added `js-interop` sinks for the `InvokeAsync` and `InvokeVoidAsync` methods of `Microsoft.JSInterop.IJSRuntime`, which can run arbitrary JavaScript. + ## 3.1.1 ### Minor Analysis Improvements diff --git a/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md b/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md deleted file mode 100644 index a99f9c8e0fd3..000000000000 --- a/csharp/ql/lib/change-notes/2024-11-26-model-microsoft.jsinterop.ijsruntime.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Added `js-interop` sinks for the `InvokeAsync` and `InvokeVoidAsync` methods of `Microsoft.JSInterop.IJSRuntime`, which can run arbitrary JavaScript. - diff --git a/csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md b/csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md deleted file mode 100644 index 2d9866c2e158..000000000000 --- a/csharp/ql/lib/change-notes/2024-11-27-navigationmanager.uri-and-uri-parsing-utilities.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -category: minorAnalysis ---- -* Added `Microsoft.AspNetCore.Components.NagivationManager::Uri` as a remote flow source, since this value may contain user-specified values. -* Added the following URI-parsing methods as summaries, as they may be tainted with user-specified values: - - `System.Web.HttpUtility::ParseQueryString` - - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseQuery` - - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseNullableQuery` diff --git a/csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md b/csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md deleted file mode 100644 index 4d5f8f9258e1..000000000000 --- a/csharp/ql/lib/change-notes/2024-12-03-dynamic-field-flow.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added support for data-flow through member accesses of objects with `dynamic` types. diff --git a/csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md b/csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md deleted file mode 100644 index 7b284df36526..000000000000 --- a/csharp/ql/lib/change-notes/2024-12-03-public-protected-reference.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Only extract *public* and *protected* members from reference assemblies. This yields an approximate average speed-up of around 10% for extraction and query execution. Custom MaD rows using `Field`-based summaries may need to be changed to `SyntheticField`-based flows if they reference private fields. diff --git a/csharp/ql/lib/change-notes/released/4.0.0.md b/csharp/ql/lib/change-notes/released/4.0.0.md new file mode 100644 index 000000000000..2a64ac002329 --- /dev/null +++ b/csharp/ql/lib/change-notes/released/4.0.0.md @@ -0,0 +1,16 @@ +## 4.0.0 + +### Breaking Changes + +* 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. + +### Minor Analysis Improvements + +* Added support for data-flow through member accesses of objects with `dynamic` types. +* Only extract *public* and *protected* members from reference assemblies. This yields an approximate average speed-up of around 10% for extraction and query execution. Custom MaD rows using `Field`-based summaries may need to be changed to `SyntheticField`-based flows if they reference private fields. +* Added `Microsoft.AspNetCore.Components.NagivationManager::Uri` as a remote flow source, since this value may contain user-specified values. +* Added the following URI-parsing methods as summaries, as they may be tainted with user-specified values: + - `System.Web.HttpUtility::ParseQueryString` + - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseQuery` + - `Microsoft.AspNetCore.WebUtilities.QueryHelpers::ParseNullableQuery` +* Added `js-interop` sinks for the `InvokeAsync` and `InvokeVoidAsync` methods of `Microsoft.JSInterop.IJSRuntime`, which can run arbitrary JavaScript. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index c06beda86a3a..49fe3eef6973 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 3.1.1 +lastReleaseVersion: 4.0.0 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index efc82eedc906..d985d58b1128 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 3.1.2-dev +version: 4.0.0 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 99528b54e9ea..370a9cf4a6a2 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.13 + +### Minor Analysis Improvements + +* `csharp/diagnostic/database-quality` has been changed to exclude various property access expressions from database quality evaluation. The excluded property access expressions are expected to have no target callables even in manual or autobuilt databases. + ## 1.0.12 No user-facing changes. diff --git a/csharp/ql/src/change-notes/2024-11-28-db-quality-property-access.md b/csharp/ql/src/change-notes/released/1.0.13.md similarity index 85% rename from csharp/ql/src/change-notes/2024-11-28-db-quality-property-access.md rename to csharp/ql/src/change-notes/released/1.0.13.md index 212c01f24bbe..cfce05a87336 100644 --- a/csharp/ql/src/change-notes/2024-11-28-db-quality-property-access.md +++ b/csharp/ql/src/change-notes/released/1.0.13.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 1.0.13 + +### Minor Analysis Improvements + * `csharp/diagnostic/database-quality` has been changed to exclude various property access expressions from database quality evaluation. The excluded property access expressions are expected to have no target callables even in manual or autobuilt databases. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 569b69021d1d..f838d279d87b 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.0.13-dev +version: 1.0.13 groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index eeb6b0a262a3..3c6fa155a322 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/1.0.13.md b/go/ql/consistency-queries/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/go/ql/consistency-queries/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 60d11115c14c..72aeab276d7c 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.13-dev +version: 1.0.13 groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index b2eb3cbb2392..83052b3a1d9b 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,17 @@ +## 3.0.0 + +### Breaking Changes + +* 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. + +### Minor Analysis Improvements + +* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn" or "With" defined on an interface whose name ends in "logger" or "Logger" is now considered a LoggerCall. In particular, it is a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. + +### Bug Fixes + +* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. + ## 2.1.3 ### Minor Analysis Improvements diff --git a/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md b/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md deleted file mode 100644 index 8b1ee9b60b23..000000000000 --- a/go/ql/lib/change-notes/2024-11-17-fix-missing-promoted-fields-and-methods-name-clash.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: fix ---- -* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. diff --git a/go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md b/go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md deleted file mode 100644 index 46f5988b3798..000000000000 --- a/go/ql/lib/change-notes/2024-11-20-heuristic-logging-sinks.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn" or "With" defined on an interface whose name ends in "logger" or "Logger" is now considered a LoggerCall. In particular, it is a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. diff --git a/go/ql/lib/change-notes/released/3.0.0.md b/go/ql/lib/change-notes/released/3.0.0.md new file mode 100644 index 000000000000..5aafa0c29d14 --- /dev/null +++ b/go/ql/lib/change-notes/released/3.0.0.md @@ -0,0 +1,13 @@ +## 3.0.0 + +### Breaking Changes + +* 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. + +### Minor Analysis Improvements + +* A call to a method whose name starts with "Debug", "Error", "Fatal", "Info", "Log", "Output", "Panic", "Print", "Trace", "Warn" or "With" defined on an interface whose name ends in "logger" or "Logger" is now considered a LoggerCall. In particular, it is a sink for `go/clear-text-logging` and `go/log-injection`. This may lead to some more alerts in those queries. + +### Bug Fixes + +* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 345fb0c73a44..33d3a2cd1139 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.3 +lastReleaseVersion: 3.0.0 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 98e81430897c..df0d0e9d5fce 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 2.1.4-dev +version: 3.0.0 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index c529cbffb328..c9044e55cdcb 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.1.4 + +### Minor Analysis Improvements + +* Added value flow models for functions in the `slices` package which do not involve the `iter` package. + ## 1.1.3 No user-facing changes. diff --git a/go/ql/src/change-notes/2024-11-26-model-slices-package.md b/go/ql/src/change-notes/released/1.1.4.md similarity index 70% rename from go/ql/src/change-notes/2024-11-26-model-slices-package.md rename to go/ql/src/change-notes/released/1.1.4.md index 5a3141c8075a..0437ebd2bd68 100644 --- a/go/ql/src/change-notes/2024-11-26-model-slices-package.md +++ b/go/ql/src/change-notes/released/1.1.4.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 1.1.4 + +### Minor Analysis Improvements + * Added value flow models for functions in the `slices` package which do not involve the `iter` package. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 35e710ab1bf0..26cbcd3f123b 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.3 +lastReleaseVersion: 1.1.4 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 866a09357130..ecd9cbb13f0e 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.1.4-dev +version: 1.1.4 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 990fea9ddd7c..09ee80087e8b 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 5.0.0 + +### Breaking Changes + +* 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. + +### Minor Analysis Improvements + +* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. + ## 4.2.1 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md b/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md deleted file mode 100644 index dea1e7ff81e1..000000000000 --- a/java/ql/lib/change-notes/2024-11-04-list-of-constants-sanitizer.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. diff --git a/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/java/ql/lib/change-notes/released/5.0.0.md similarity index 56% rename from csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md rename to java/ql/lib/change-notes/released/5.0.0.md index d09ec528c99e..9d9e2bc61b54 100644 --- a/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md +++ b/java/ql/lib/change-notes/released/5.0.0.md @@ -1,4 +1,9 @@ ---- -category: breaking ---- +## 5.0.0 + +### Breaking Changes + * 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. + +### Minor Analysis Improvements + +* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 38ea9976fccd..c9e54136ca5c 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 4.2.1 +lastReleaseVersion: 5.0.0 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index a8c1ee2de2b1..54f56a246062 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 4.2.2-dev +version: 5.0.0 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index f212b4a8d3d7..0bb38874b82f 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.1.10 + +### Minor Analysis Improvements + +* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384. +* Added SHA3 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA3. +* The `java/weak-cryptographic-algorithm` query has been updated to no longer report uses of hash functions such as `MD5` and `SHA1` even if they are known to be weak. These hash algorithms are used very often in non-sensitive contexts, making the query too imprecise in practice. The `java/potentially-weak-cryptographic-algorithm` query has been updated to report these uses instead. + ## 1.1.9 No user-facing changes. diff --git a/java/ql/src/change-notes/2024-11-22-sha3.md b/java/ql/src/change-notes/2024-11-22-sha3.md deleted file mode 100644 index 61dbc35162e1..000000000000 --- a/java/ql/src/change-notes/2024-11-22-sha3.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added SHA3 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA3. diff --git a/java/ql/src/change-notes/2024-11-24-sha2.md b/java/ql/src/change-notes/2024-11-24-sha2.md deleted file mode 100644 index 395ea04b782e..000000000000 --- a/java/ql/src/change-notes/2024-11-24-sha2.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384. diff --git a/java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md b/java/ql/src/change-notes/released/1.1.10.md similarity index 50% rename from java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md rename to java/ql/src/change-notes/released/1.1.10.md index b4ac88bcdc6a..fef22bdedf57 100644 --- a/java/ql/src/change-notes/2024-10-29-weak-crypto-hash.md +++ b/java/ql/src/change-notes/released/1.1.10.md @@ -1,4 +1,7 @@ ---- -category: minorAnalysis ---- +## 1.1.10 + +### Minor Analysis Improvements + +* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384. +* Added SHA3 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA3. * The `java/weak-cryptographic-algorithm` query has been updated to no longer report uses of hash functions such as `MD5` and `SHA1` even if they are known to be weak. These hash algorithms are used very often in non-sensitive contexts, making the query too imprecise in practice. The `java/potentially-weak-cryptographic-algorithm` query has been updated to report these uses instead. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 6f4795f3ea0b..4c01918d4144 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.9 +lastReleaseVersion: 1.1.10 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 44740683f142..eb757401a840 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.1.10-dev +version: 1.1.10 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 7d8f8dcfc8bf..df83ccd9c4dc 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,12 +1,27 @@ +## 2.2.0 + +### Major Analysis Improvements + +* The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals. +* Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases. +* Regular expression related queries now account for unknown flags. + +### Minor Analysis Improvements + +* Added taint-steps for `String.prototype.toWellFormed`. +* Added taint-steps for `Map.groupBy` and `Object.groupBy`. +* Added taint-steps for `Array.prototype.findLast` +* Added taint-steps for `Array.prototype.findLastIndex` + ## 2.1.1 ### Minor Analysis Improvements -Added taint-steps for `Array.prototype.with`. -Added taint-steps for `Array.prototype.toSpliced` +* Added taint-steps for `Array.prototype.with`. +* Added taint-steps for `Array.prototype.toSpliced` * Added taint-steps for `Array.prototype.toReversed`. * Added taint-steps for `Array.prototype.toSorted`. -Added support for `String.prototype.matchAll`. +* Added support for `String.prototype.matchAll`. * Added taint-steps for `Array.prototype.reverse` ## 2.1.0 diff --git a/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md b/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md deleted file mode 100644 index e3fe3b6aef25..000000000000 --- a/javascript/ql/lib/change-notes/2024-11-18-ES2022-find-functions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Added taint-steps for `Array.prototype.findLast` -* Added taint-steps for `Array.prototype.findLastIndex` diff --git a/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md b/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md deleted file mode 100644 index dda4d8787605..000000000000 --- a/javascript/ql/lib/change-notes/2024-11-20-ES2023-string-protytpe-toWellFormed.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added taint-steps for `String.prototype.toWellFormed`. diff --git a/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md b/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md deleted file mode 100644 index 8511727f8e77..000000000000 --- a/javascript/ql/lib/change-notes/2024-11-20-ES2024-group-functions.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added taint-steps for `Map.groupBy` and `Object.groupBy`. diff --git a/javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md b/javascript/ql/lib/change-notes/released/2.2.0.md similarity index 52% rename from javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md rename to javascript/ql/lib/change-notes/released/2.2.0.md index e1db79e5c86d..535acb6ffc1d 100644 --- a/javascript/ql/lib/change-notes/2024-11-28-regexp-unknown-flags.md +++ b/javascript/ql/lib/change-notes/released/2.2.0.md @@ -1,6 +1,14 @@ ---- -category: majorAnalysis ---- +## 2.2.0 + +### Major Analysis Improvements + * The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals. * Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases. * Regular expression related queries now account for unknown flags. + +### Minor Analysis Improvements + +* Added taint-steps for `String.prototype.toWellFormed`. +* Added taint-steps for `Map.groupBy` and `Object.groupBy`. +* Added taint-steps for `Array.prototype.findLast` +* Added taint-steps for `Array.prototype.findLastIndex` diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 576c2ea18d68..2f3083541950 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.1 +lastReleaseVersion: 2.2.0 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 9726d407e1af..4245aa6e5d35 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.1.2-dev +version: 2.2.0 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 403de6b33237..195298ec89f1 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.5 + +No user-facing changes. + ## 1.2.4 No user-facing changes. diff --git a/javascript/ql/src/change-notes/released/1.2.5.md b/javascript/ql/src/change-notes/released/1.2.5.md new file mode 100644 index 000000000000..c805dc2cd4c3 --- /dev/null +++ b/javascript/ql/src/change-notes/released/1.2.5.md @@ -0,0 +1,3 @@ +## 1.2.5 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 172090f46b6d..40355f0807f9 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.2.4 +lastReleaseVersion: 1.2.5 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index a1efe30e69d1..ba7c502b29fa 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 1.2.5-dev +version: 1.2.5 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 969419cb7b7e..5d46c57bf4e2 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/1.0.13.md b/misc/suite-helpers/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/misc/suite-helpers/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index e2cbd7f3f9d4..834362022be8 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.13-dev +version: 1.0.13 groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 34dc5f1b060b..81c7659c4edd 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 3.0.0 + +### Breaking Changes + +* 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. + +### Bug Fixes + +- Fixed a problem with the control-flow graph construction, where writing `case True:` or `case False:` would cause parts of the graph to be pruned by mistake. + ## 2.2.0 ### Major Analysis Improvements diff --git a/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md b/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md deleted file mode 100644 index 3ee1094c13b7..000000000000 --- a/python/ql/lib/change-notes/2024-11-26-fix-match-cfg-pruning.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: fix ---- - -- Fixed a problem with the control-flow graph construction, where writing `case True:` or `case False:` would cause parts of the graph to be pruned by mistake. 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 deleted file mode 100644 index d09ec528c99e..000000000000 --- a/python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -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/released/3.0.0.md b/python/ql/lib/change-notes/released/3.0.0.md new file mode 100644 index 000000000000..d57189465d86 --- /dev/null +++ b/python/ql/lib/change-notes/released/3.0.0.md @@ -0,0 +1,9 @@ +## 3.0.0 + +### Breaking Changes + +* 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. + +### Bug Fixes + +- Fixed a problem with the control-flow graph construction, where writing `case True:` or `case False:` would cause parts of the graph to be pruned by mistake. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 2f3083541950..33d3a2cd1139 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.2.0 +lastReleaseVersion: 3.0.0 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 290189efa132..978dfd96a834 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 2.2.1-dev +version: 3.0.0 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 5fea597a7a39..c247e217acf3 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.4 + +No user-facing changes. + ## 1.3.3 No user-facing changes. diff --git a/python/ql/src/change-notes/released/1.3.4.md b/python/ql/src/change-notes/released/1.3.4.md new file mode 100644 index 000000000000..5073aca7222c --- /dev/null +++ b/python/ql/src/change-notes/released/1.3.4.md @@ -0,0 +1,3 @@ +## 1.3.4 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index eb1f7dabc842..8263ddf2c8b8 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.3 +lastReleaseVersion: 1.3.4 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index d84402123dc8..bff5afdf8177 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.3.4-dev +version: 1.3.4 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 37248cf49600..737903a3232f 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 3.0.0 + +### Breaking Changes + +* 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. + ## 2.0.4 No user-facing changes. 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 deleted file mode 100644 index d09ec528c99e..000000000000 --- a/ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -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/ruby/ql/lib/change-notes/released/3.0.0.md similarity index 88% rename from java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md rename to ruby/ql/lib/change-notes/released/3.0.0.md index d09ec528c99e..82b5c467407b 100644 --- a/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md +++ b/ruby/ql/lib/change-notes/released/3.0.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 3.0.0 + +### Breaking Changes + * 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/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 0f306f8bd3bd..33d3a2cd1139 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.4 +lastReleaseVersion: 3.0.0 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 97259f5dd36d..41b72629a67b 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 2.0.5-dev +version: 3.0.0 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index e159e9fda368..5fe04780136b 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.8 + +No user-facing changes. + ## 1.1.7 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/1.1.8.md b/ruby/ql/src/change-notes/released/1.1.8.md new file mode 100644 index 000000000000..f4fe325b3350 --- /dev/null +++ b/ruby/ql/src/change-notes/released/1.1.8.md @@ -0,0 +1,3 @@ +## 1.1.8 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 759105565166..64972659c426 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.7 +lastReleaseVersion: 1.1.8 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 26ac8866ae02..7f337d89d6a4 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.1.8-dev +version: 1.1.8 groups: - ruby - queries diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index b6de6379e774..285b39a43598 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/1.0.13.md b/shared/controlflow/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/controlflow/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index da4368217d3a..5401179ac965 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index 7eec34670dc0..df038524d2d2 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.7 + +No user-facing changes. + ## 1.1.6 No user-facing changes. diff --git a/shared/dataflow/change-notes/released/1.1.7.md b/shared/dataflow/change-notes/released/1.1.7.md new file mode 100644 index 000000000000..81505c0507a2 --- /dev/null +++ b/shared/dataflow/change-notes/released/1.1.7.md @@ -0,0 +1,3 @@ +## 1.1.7 + +No user-facing changes. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 9e712a00a21d..759105565166 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.6 +lastReleaseVersion: 1.1.7 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 15f77aa0a3a2..55eb216cc54d 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 1.1.7-dev +version: 1.1.7 groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 8eb5e03400a4..93a528a4f3c8 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/mad/change-notes/released/1.0.13.md b/shared/mad/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/mad/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 8ce60ad0cc9f..5c37e6090299 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index cedd38e3e303..6b25d16e0f73 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/1.0.13.md b/shared/rangeanalysis/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index ee5954cae0b1..bd33c35fe53a 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 3e8a99103fe1..54c3ed2b3070 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/regex/change-notes/released/1.0.13.md b/shared/regex/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/regex/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 34aa1065398c..07d9f87eb8ce 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index b98345f361cc..01c19388c92f 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/ssa/change-notes/released/1.0.13.md b/shared/ssa/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/ssa/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 145cd9e2192e..9a2027d0706d 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index eeb6b0a262a3..3c6fa155a322 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/1.0.13.md b/shared/threat-models/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/threat-models/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 16ca1fe3a887..d29bd36dd83b 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.13-dev +version: 1.0.13 library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index da467b3de30c..1f4e7ad4ed3d 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/1.0.13.md b/shared/tutorial/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/tutorial/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 14cbbbdc0675..e618abb068b5 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index cae361ea7e70..dd8fb7a60b2a 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/typeflow/change-notes/released/1.0.13.md b/shared/typeflow/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/typeflow/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 5a659a4559d2..e9d46c074e81 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index 96110cb10a25..0ab05873af4d 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/1.0.13.md b/shared/typetracking/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/typetracking/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 216cc8696d91..9e4717670a7e 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 83fb2dfb4cc7..c0c3cea39485 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/typos/change-notes/released/1.0.13.md b/shared/typos/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/typos/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 8c1a93efe5e8..b3ed91c0926e 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index 15c3b8c6225e..e03d990b7471 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.0.0 + +### Breaking Changes + +* Deleted the old deprecated inline expectation test API that was based on the `InlineExpectationsTest` class. + ## 1.0.12 No user-facing changes. diff --git a/shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md b/shared/util/change-notes/released/2.0.0.md similarity index 77% rename from shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md rename to shared/util/change-notes/released/2.0.0.md index 6126e37b619e..513290e952ba 100644 --- a/shared/util/change-notes/2024-12-03-remove-deprected-inline-expecation-test-classes.md +++ b/shared/util/change-notes/released/2.0.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 2.0.0 + +### Breaking Changes + * Deleted the old deprecated inline expectation test API that was based on the `InlineExpectationsTest` class. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index 2036690b201f..0abe6ccede0f 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 2.0.0 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 83284f19cc32..4b66bd8ad928 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 1.0.13-dev +version: 2.0.0 groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index c8213742dc9f..c3ebc31994b2 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/xml/change-notes/released/1.0.13.md b/shared/xml/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/xml/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index f48f41ef3ffe..8d8b1b8ee54e 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 2cc2ec620572..28fcbceec8ef 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/shared/yaml/change-notes/released/1.0.13.md b/shared/yaml/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/shared/yaml/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 54880a8cf2fd..998a94f4bbfb 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.13-dev +version: 1.0.13 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 898a3282bb5a..ba76b51c80e3 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 3.0.0 + +### Breaking Changes + +* 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. + ## 2.0.4 No user-facing changes. 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 deleted file mode 100644 index d09ec528c99e..000000000000 --- a/swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -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/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/swift/ql/lib/change-notes/released/3.0.0.md similarity index 88% rename from cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md rename to swift/ql/lib/change-notes/released/3.0.0.md index d09ec528c99e..82b5c467407b 100644 --- a/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md +++ b/swift/ql/lib/change-notes/released/3.0.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 3.0.0 + +### Breaking Changes + * 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/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 0f306f8bd3bd..33d3a2cd1139 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.4 +lastReleaseVersion: 3.0.0 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 2e855546d50c..66fd8af358e9 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 2.0.5-dev +version: 3.0.0 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 76de7db13480..73ac6bef86d7 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +No user-facing changes. + ## 1.0.12 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/1.0.13.md b/swift/ql/src/change-notes/released/1.0.13.md new file mode 100644 index 000000000000..378f97eeb1bd --- /dev/null +++ b/swift/ql/src/change-notes/released/1.0.13.md @@ -0,0 +1,3 @@ +## 1.0.13 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index 2036690b201f..c3be7eb77163 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.12 +lastReleaseVersion: 1.0.13 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 1d9f7154cdae..ee53e55fe41b 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.0.13-dev +version: 1.0.13 groups: - swift - queries From 92d614dbcd0165012b39e85d4b3e1b367c977910 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Fri, 6 Dec 2024 19:13:05 +0000 Subject: [PATCH 145/213] Add periods for consistency --- javascript/ql/lib/CHANGELOG.md | 4 ++-- javascript/ql/lib/change-notes/released/2.2.0.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index df83ccd9c4dc..ebe424935eb9 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -10,8 +10,8 @@ * Added taint-steps for `String.prototype.toWellFormed`. * Added taint-steps for `Map.groupBy` and `Object.groupBy`. -* Added taint-steps for `Array.prototype.findLast` -* Added taint-steps for `Array.prototype.findLastIndex` +* Added taint-steps for `Array.prototype.findLast`. +* Added taint-steps for `Array.prototype.findLastIndex`. ## 2.1.1 diff --git a/javascript/ql/lib/change-notes/released/2.2.0.md b/javascript/ql/lib/change-notes/released/2.2.0.md index 535acb6ffc1d..f8c194f73f8a 100644 --- a/javascript/ql/lib/change-notes/released/2.2.0.md +++ b/javascript/ql/lib/change-notes/released/2.2.0.md @@ -10,5 +10,5 @@ * Added taint-steps for `String.prototype.toWellFormed`. * Added taint-steps for `Map.groupBy` and `Object.groupBy`. -* Added taint-steps for `Array.prototype.findLast` -* Added taint-steps for `Array.prototype.findLastIndex` +* Added taint-steps for `Array.prototype.findLast`. +* Added taint-steps for `Array.prototype.findLastIndex`. From dbe8f98e183b58c716a44c025dab58ec69b9d65c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Dec 2024 21:19:19 +0000 Subject: [PATCH 146/213] Post-release preparation for codeql-cli-2.20.0 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 34 files changed, 34 insertions(+), 34 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 723a2c3544e6..4bb4b04e02fd 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 3.0.0 +version: 3.0.1-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 824ee1459aa4..940c3e2a4cba 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.3.0 +version: 1.3.1-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index daac6be2fbb1..781915bf1a15 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.30 +version: 1.7.31-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 1b3b911c6f11..979d8e6c6615 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.30 +version: 1.7.31-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index d985d58b1128..81a55470a4dd 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 4.0.0 +version: 4.0.1-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index f838d279d87b..e4d9400d96d3 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.0.13 +version: 1.0.14-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 72aeab276d7c..1812705438ca 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.13 +version: 1.0.14-dev groups: - go - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index df0d0e9d5fce..4e72aa3857b5 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 3.0.0 +version: 3.0.1-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index ecd9cbb13f0e..36775d0d8620 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.1.4 +version: 1.1.5-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 54f56a246062..f892ca1c4500 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 5.0.0 +version: 5.0.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index eb757401a840..8ee211fb536f 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.1.10 +version: 1.1.11-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 4245aa6e5d35..4d568ff48132 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.2.0 +version: 2.2.1-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index ba7c502b29fa..78f0585027b5 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 1.2.5 +version: 1.2.6-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 834362022be8..eeb8f762b131 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.13 +version: 1.0.14-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 978dfd96a834..147933b96fe8 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 3.0.0 +version: 3.0.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index bff5afdf8177..d83b6433ac64 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.3.4 +version: 1.3.5-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 41b72629a67b..ddf106c95bfa 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 3.0.0 +version: 3.0.1-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 7f337d89d6a4..43bfe75f566d 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.1.8 +version: 1.1.9-dev groups: - ruby - queries diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index 5401179ac965..268f142bd1be 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 55eb216cc54d..6a8e8c3a4ae8 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 1.1.7 +version: 1.1.8-dev groups: shared library: true dependencies: diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 5c37e6090299..125bcad622d8 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index bd33c35fe53a..62c8c1e46b6f 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 07d9f87eb8ce..e2cda264dc86 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 9a2027d0706d..b146ce5bc913 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index d29bd36dd83b..6ec41bbcc04b 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.13 +version: 1.0.14-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index e618abb068b5..6677c74eed4e 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index e9d46c074e81..cd9e70bba8c4 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 9e4717670a7e..fbe63f0da01a 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b3ed91c0926e..250f729ab5f5 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 4b66bd8ad928..b327c25a3d90 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.0 +version: 2.0.1-dev groups: shared library: true dependencies: null diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 8d8b1b8ee54e..76c408c29202 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 998a94f4bbfb..0c756e1edbbe 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.13 +version: 1.0.14-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 66fd8af358e9..7752975faea0 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 3.0.0 +version: 3.0.1-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index ee53e55fe41b..ec8e2cb9932b 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.0.13 +version: 1.0.14-dev groups: - swift - queries From 214da9e9adf74cb7fc17b73b74653a95f2e7582e Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Fri, 6 Dec 2024 19:59:40 -0500 Subject: [PATCH 147/213] Java: add change note --- java/ql/lib/change-notes/2024-12-06-file-getname.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2024-12-06-file-getname.md diff --git a/java/ql/lib/change-notes/2024-12-06-file-getname.md b/java/ql/lib/change-notes/2024-12-06-file-getname.md new file mode 100644 index 000000000000..b2d1d271ab55 --- /dev/null +++ b/java/ql/lib/change-notes/2024-12-06-file-getname.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added `java.io.File.getName()` as a path injection sanitizer. From 41425b157f0e2b0176eafedf516a594eae7bbc5f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Sun, 8 Dec 2024 23:47:34 +0000 Subject: [PATCH 148/213] C++: Add test with missing flow. --- .../dataflow/dataflow-tests/dataflow-consistency.expected | 4 ++++ .../dataflow/dataflow-tests/test-source-sink.expected | 2 ++ cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp | 7 +++++++ .../dataflow/dataflow-tests/uninitialized.expected | 3 +++ 4 files changed, 16 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index 68dad62a95f0..ca62e5c92690 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -181,6 +181,10 @@ postWithInFlow | test.cpp:1108:4:1108:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:1109:3:1109:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:1109:4:1109:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1138:3:1138:13 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1138:5:1138:8 | data [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1139:3:1139:7 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1139:4:1139:7 | data [inner post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition uniqueParameterNodePosition diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index 10a8bef9a338..6a65ddf952cf 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -132,6 +132,8 @@ astFlow | test.cpp:1069:9:1069:14 | call to source | test.cpp:1074:10:1074:10 | i | | test.cpp:1069:9:1069:14 | call to source | test.cpp:1082:10:1082:10 | i | | test.cpp:1086:12:1086:12 | a | test.cpp:1088:8:1088:9 | & ... | +| test.cpp:1137:7:1137:10 | data | test.cpp:1140:8:1140:18 | * ... | +| test.cpp:1138:17:1138:22 | call to source | test.cpp:1140:8:1140:18 | * ... | | true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x | | true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x | | true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index 60baa08bb8d7..33c714a3139a 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -1131,4 +1131,11 @@ void (*dispatch_table[])(int) = { void test_dispatch_table(int i) { int x = source(); dispatch_table[i](x); +} + +void test_uncertain_array(int n1, int n2) { + int data[10]; + *(data + 1) = source(); + *data = 0; + sink(*(data + 1)); // $ ast=1138:17 ast=1137:7 MISSING: ir } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected index 16f0b799d0ac..52bbcabb1e3e 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected @@ -56,3 +56,6 @@ | test.cpp:796:12:796:12 | a | test.cpp:798:17:798:17 | a | | test.cpp:1086:12:1086:12 | a | test.cpp:1087:3:1087:3 | a | | test.cpp:1086:12:1086:12 | a | test.cpp:1088:9:1088:9 | a | +| test.cpp:1137:7:1137:10 | data | test.cpp:1138:5:1138:8 | data | +| test.cpp:1137:7:1137:10 | data | test.cpp:1139:4:1139:7 | data | +| test.cpp:1137:7:1137:10 | data | test.cpp:1140:10:1140:13 | data | From f74dcc703657a4521a67a57351c48f03090f2e5e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 9 Dec 2024 10:20:46 +0100 Subject: [PATCH 149/213] Make scripts executable --- misc/scripts/check-query-ids.py | 2 ++ misc/scripts/create-change-note.py | 0 misc/scripts/generate-code-scanning-query-list.py | 4 +++- misc/scripts/models-as-data/generate_flow_model.py | 4 ++-- misc/scripts/pre-commit | 0 misc/scripts/shared-code-metrics.py | 10 +++++----- 6 files changed, 12 insertions(+), 8 deletions(-) mode change 100644 => 100755 misc/scripts/check-query-ids.py mode change 100644 => 100755 misc/scripts/create-change-note.py mode change 100644 => 100755 misc/scripts/generate-code-scanning-query-list.py mode change 100644 => 100755 misc/scripts/models-as-data/generate_flow_model.py mode change 100644 => 100755 misc/scripts/pre-commit mode change 100644 => 100755 misc/scripts/shared-code-metrics.py diff --git a/misc/scripts/check-query-ids.py b/misc/scripts/check-query-ids.py old mode 100644 new mode 100755 index aa06ae3a6a59..4158b992ec7c --- a/misc/scripts/check-query-ids.py +++ b/misc/scripts/check-query-ids.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + from pathlib import Path import re import sys diff --git a/misc/scripts/create-change-note.py b/misc/scripts/create-change-note.py old mode 100644 new mode 100755 diff --git a/misc/scripts/generate-code-scanning-query-list.py b/misc/scripts/generate-code-scanning-query-list.py old mode 100644 new mode 100755 index 94b15a33886d..72a5d7732d00 --- a/misc/scripts/generate-code-scanning-query-list.py +++ b/misc/scripts/generate-code-scanning-query-list.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import subprocess import json import csv @@ -52,7 +54,7 @@ def __exit__(self, type, value, tb): except: self.proc.kill() - def command(self, args): + def command(self, args): data = json.dumps(args) data_bytes = data.encode('utf-8') self.proc.stdin.write(data_bytes) diff --git a/misc/scripts/models-as-data/generate_flow_model.py b/misc/scripts/models-as-data/generate_flow_model.py old mode 100644 new mode 100755 index cfd524066cbf..17db03e01e4f --- a/misc/scripts/models-as-data/generate_flow_model.py +++ b/misc/scripts/models-as-data/generate_flow_model.py @@ -140,7 +140,7 @@ def make(language): generator.setenvironment(sys.argv[1], sys.argv[2]) return generator - + def runQuery(self, query): print("########## Querying " + query + "...") @@ -224,7 +224,7 @@ def run(self): if self.dryRun: print("Models as data extensions generated, but not written to file.") sys.exit(0) - + if (self.generateSinks or self.generateSources or self.generateSummaries or diff --git a/misc/scripts/pre-commit b/misc/scripts/pre-commit old mode 100644 new mode 100755 diff --git a/misc/scripts/shared-code-metrics.py b/misc/scripts/shared-code-metrics.py old mode 100644 new mode 100755 index bfc613e5c877..23ce1fd8759a --- a/misc/scripts/shared-code-metrics.py +++ b/misc/scripts/shared-code-metrics.py @@ -1,7 +1,7 @@ #!/bin/env python3 # Generates a report on the amount of code sharing in this repo # -# The purpose of this is +# The purpose of this is # a) To be able to understand the structure and dependencies # b) To provide a metric that measures the amount of shared vs non-shared code @@ -224,7 +224,7 @@ def calculateDependencies(self, packageNameMap): if lang in language_info: info = language_info[lang] if qlfile.isOnlyInLanguage(lang): - info.addQlFile(qlfile) + info.addQlFile(qlfile) # Determine all package dependencies @@ -276,15 +276,15 @@ def print_package_dependencies(packages): nlines = package.lines + package.total_imported_lines shared_percentage = 100 * package.total_imported_lines / nlines if nlines>0 else 0 print('|', package.link(), '|', package.files, '|', package.lines, '|', package.total_imported_files, '|', package.total_imported_lines, '|', - # ','.join([p.name for p in package.all_dependencies]), + # ','.join([p.name for p in package.all_dependencies]), "%.2f" % shared_percentage, '|') print() def print_language_dependencies(packages): - print_package_dependencies([p for p in packages if p.name.endswith('-all') and p.name.count('-')==1]) + print_package_dependencies([p for p in packages if p.name.endswith('-all') and p.name.count('-')==1]) def list_shared_code_by_language(language_info): - # For each language directory, list the files that are (1) inside the directory and not shared, + # For each language directory, list the files that are (1) inside the directory and not shared, # (2) packages from outside the directory, plus identical files print('| Language | Non-shared files | Non-shared lines of code | Imported files | Imported lines of code | Shared code % |') print('| -------- | ---------------- | ------------------------ | -------------- | ---------------------- | ------------- |') From 18560cde9d492da9e4cca5f04723c9931bcaafe8 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Sun, 8 Dec 2024 12:51:40 +0100 Subject: [PATCH 150/213] C#: Shorten test target names to make Windows happy. --- csharp/BUILD.bazel | 6 +++--- .../autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel | 3 ++- csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel | 3 ++- .../Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel | 2 +- .../Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel | 2 +- csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel | 3 ++- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/csharp/BUILD.bazel b/csharp/BUILD.bazel index fbe4213ab9e1..4c8167660177 100644 --- a/csharp/BUILD.bazel +++ b/csharp/BUILD.bazel @@ -74,8 +74,8 @@ test_suite( name = "unit-tests", tags = ["csharp"], tests = [ - "//csharp/autobuilder/Semmle.Autobuild.CSharp.Tests", - "//csharp/autobuilder/Semmle.Autobuild.Cpp.Tests", - "//csharp/extractor/Semmle.Extraction.Tests", + "//csharp/autobuilder/Semmle.Autobuild.CSharp.Tests:t", + "//csharp/autobuilder/Semmle.Autobuild.Cpp.Tests:t", + "//csharp/extractor/Semmle.Extraction.Tests:t", ], ) diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel index 65371c893932..49a26bdb33bb 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel @@ -4,7 +4,8 @@ load( ) codeql_xunit_test( - name = "Semmle.Autobuild.CSharp.Tests", + # short name as we run into long path limitations on Windows + name = "t", srcs = glob([ "*.cs", ]), diff --git a/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel b/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel index 10c8c6dc96c1..1cf2480403a7 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel +++ b/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel @@ -4,7 +4,8 @@ load( ) codeql_xunit_test( - name = "Semmle.Autobuild.Cpp.Tests", + # short name as we run into long path limitations on Windows + name = "t", srcs = glob([ "*.cs", ]), diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel index 8be8aaa8408b..5a4d49c88fd5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel @@ -10,7 +10,7 @@ codeql_csharp_library( "SourceGenerators/**/*.cs", ]), allow_unsafe_blocks = True, - internals_visible_to = ["Semmle.Extraction.Tests"], + internals_visible_to = ["t"], visibility = ["//csharp:__subpackages__"], deps = [ "//csharp/extractor/Semmle.Extraction.CSharp", diff --git a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel index 563168cdf480..e3d0533a776c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel @@ -8,7 +8,7 @@ codeql_csharp_library( srcs = glob([ "*.cs", ]), - internals_visible_to = ["Semmle.Extraction.Tests"], + internals_visible_to = ["t"], visibility = ["//csharp:__subpackages__"], deps = [ "//csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching", diff --git a/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel b/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel index df9799d3f959..4671fa33bb33 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel @@ -4,7 +4,8 @@ load( ) codeql_xunit_test( - name = "Semmle.Extraction.Tests", + # short name as we run into long path limitations on Windows + name = "t", srcs = glob([ "*.cs", ]), From 526dbe5901db34cadf27f01b70121e66cc96bce1 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Mon, 9 Dec 2024 12:19:01 +0100 Subject: [PATCH 151/213] Address review, also run semmle-util tests. --- csharp/BUILD.bazel | 7 ++++--- .../autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel | 2 +- csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel | 2 +- .../BUILD.bazel | 2 +- .../Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel | 2 +- csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel | 2 +- csharp/extractor/Semmle.Util.Tests/BUILD.bazel | 3 ++- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/csharp/BUILD.bazel b/csharp/BUILD.bazel index 4c8167660177..8aaa0d492ef0 100644 --- a/csharp/BUILD.bazel +++ b/csharp/BUILD.bazel @@ -74,8 +74,9 @@ test_suite( name = "unit-tests", tags = ["csharp"], tests = [ - "//csharp/autobuilder/Semmle.Autobuild.CSharp.Tests:t", - "//csharp/autobuilder/Semmle.Autobuild.Cpp.Tests:t", - "//csharp/extractor/Semmle.Extraction.Tests:t", + "//csharp/autobuilder/Semmle.Autobuild.CSharp.Tests:acst", + "//csharp/autobuilder/Semmle.Autobuild.Cpp.Tests:acpt", + "//csharp/extractor/Semmle.Extraction.Tests:et", + "//csharp/extractor/Semmle.Util.Tests:ut", ], ) diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel index 49a26bdb33bb..67f3470712dd 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BUILD.bazel @@ -5,7 +5,7 @@ load( codeql_xunit_test( # short name as we run into long path limitations on Windows - name = "t", + name = "acst", srcs = glob([ "*.cs", ]), diff --git a/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel b/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel index 1cf2480403a7..ad8f6e3d1f1a 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel +++ b/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests/BUILD.bazel @@ -5,7 +5,7 @@ load( codeql_xunit_test( # short name as we run into long path limitations on Windows - name = "t", + name = "acpt", srcs = glob([ "*.cs", ]), diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel index 5a4d49c88fd5..96ecccc31aa0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel @@ -10,7 +10,7 @@ codeql_csharp_library( "SourceGenerators/**/*.cs", ]), allow_unsafe_blocks = True, - internals_visible_to = ["t"], + internals_visible_to = ["et"], visibility = ["//csharp:__subpackages__"], deps = [ "//csharp/extractor/Semmle.Extraction.CSharp", diff --git a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel index e3d0533a776c..a2c5a0c1c540 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/BUILD.bazel @@ -8,7 +8,7 @@ codeql_csharp_library( srcs = glob([ "*.cs", ]), - internals_visible_to = ["t"], + internals_visible_to = ["et"], visibility = ["//csharp:__subpackages__"], deps = [ "//csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching", diff --git a/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel b/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel index 4671fa33bb33..4d13f7f4fb82 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction.Tests/BUILD.bazel @@ -5,7 +5,7 @@ load( codeql_xunit_test( # short name as we run into long path limitations on Windows - name = "t", + name = "et", srcs = glob([ "*.cs", ]), diff --git a/csharp/extractor/Semmle.Util.Tests/BUILD.bazel b/csharp/extractor/Semmle.Util.Tests/BUILD.bazel index 6c3fb64e662c..5fde4efdb153 100644 --- a/csharp/extractor/Semmle.Util.Tests/BUILD.bazel +++ b/csharp/extractor/Semmle.Util.Tests/BUILD.bazel @@ -4,7 +4,8 @@ load( ) codeql_xunit_test( - name = "Semmle.Util.Tests", + # short name as we run into long path limitations on Windows + name = "ut", srcs = glob([ "*.cs", ]), From 798b86f6afc7905277e5dbaff4e8edaa15150e85 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Mon, 9 Dec 2024 12:26:15 +0100 Subject: [PATCH 152/213] Disable semmle.util.tests again. --- csharp/BUILD.bazel | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/csharp/BUILD.bazel b/csharp/BUILD.bazel index 8aaa0d492ef0..49293c27095e 100644 --- a/csharp/BUILD.bazel +++ b/csharp/BUILD.bazel @@ -77,6 +77,7 @@ test_suite( "//csharp/autobuilder/Semmle.Autobuild.CSharp.Tests:acst", "//csharp/autobuilder/Semmle.Autobuild.Cpp.Tests:acpt", "//csharp/extractor/Semmle.Extraction.Tests:et", - "//csharp/extractor/Semmle.Util.Tests:ut", + # this test suite currently fails, disable for now + # "//csharp/extractor/Semmle.Util.Tests:ut", ], ) From baa248ce652dda9d6d06d3e272bdd998fdf0ae98 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 9 Dec 2024 13:00:52 +0100 Subject: [PATCH 153/213] C#: Enable Semmle.Util.Tests. --- csharp/BUILD.bazel | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/csharp/BUILD.bazel b/csharp/BUILD.bazel index 49293c27095e..8aaa0d492ef0 100644 --- a/csharp/BUILD.bazel +++ b/csharp/BUILD.bazel @@ -77,7 +77,6 @@ test_suite( "//csharp/autobuilder/Semmle.Autobuild.CSharp.Tests:acst", "//csharp/autobuilder/Semmle.Autobuild.Cpp.Tests:acpt", "//csharp/extractor/Semmle.Extraction.Tests:et", - # this test suite currently fails, disable for now - # "//csharp/extractor/Semmle.Util.Tests:ut", + "//csharp/extractor/Semmle.Util.Tests:ut", ], ) From 2f8b04b225bcba82eaa7a2b22bcbe8b875bf5b8f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 5 Dec 2024 14:41:43 +0100 Subject: [PATCH 154/213] Rust: Models-as-data for flow summaries --- .../lib/codeql/rust/dataflow/FlowSummary.qll | 14 +- .../rust/dataflow/internal/DataFlowImpl.qll | 4 +- .../dataflow/internal/FlowSummaryImpl.qll | 16 +++ .../rust/dataflow/internal/ModelsAsData.qll | 98 +++++++++++++ .../rust/dataflow/internal/empty.model.yml | 17 +++ .../frameworks/stdlib/lang-core.model.yml | 6 + rust/ql/lib/qlpack.yml | 2 + .../dataflow/local/inline-flow.expected | 3 +- .../library-tests/dataflow/models/main.rs | 91 ++++++++++++ .../dataflow/models/models.expected | 129 ++++++++++++++++-- .../dataflow/models/models.ext.yml | 17 +++ .../library-tests/dataflow/models/models.ql | 60 -------- .../security/CWE-089/SqlInjection.qlref | 4 +- rust/ql/test/utils/InlineFlowTest.qll | 3 +- rust/ql/test/utils/PrettyPrintModels.ql | 7 + rust/ql/test/utils/ProvenancePathGraph.qll | 8 ++ 16 files changed, 392 insertions(+), 87 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll create mode 100644 rust/ql/lib/codeql/rust/dataflow/internal/empty.model.yml create mode 100644 rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml create mode 100644 rust/ql/test/library-tests/dataflow/models/models.ext.yml create mode 100644 rust/ql/test/utils/PrettyPrintModels.ql create mode 100644 rust/ql/test/utils/ProvenancePathGraph.qll diff --git a/rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll b/rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll index f0457c960ceb..d1ba69ba22d2 100644 --- a/rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll +++ b/rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll @@ -7,17 +7,7 @@ private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprB // import all instances below private module Summaries { private import codeql.rust.Frameworks - - // TODO: Use models-as-data when it's available - private class UnwrapSummary extends SummarizedCallable::Range { - UnwrapSummary() { this = "lang:core::_::::unwrap" } - - override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = "Argument[self].Variant[crate::option::Option::Some(0)]" and - output = "ReturnValue" and - preservesValue = true - } - } + private import codeql.rust.dataflow.internal.ModelsAsData } /** Provides the `Range` class used to define the extent of `LibraryCallable`. */ @@ -62,7 +52,7 @@ module SummarizedCallable { * * `preservesValue` indicates whether this is a value-preserving step or a taint-step. */ - abstract predicate propagatesFlow(string input, string output, boolean preservesValue); + predicate propagatesFlow(string input, string output, boolean preservesValue) { none() } } } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 80fb80e7dc6d..068429ce09b0 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -597,7 +597,7 @@ private class VariantFieldContent extends VariantContent, TVariantFieldContent { } /** A canonical path pointing to a struct. */ -private class StructCanonicalPath extends MkStructCanonicalPath { +class StructCanonicalPath extends MkStructCanonicalPath { CrateOriginOption crate; string path; @@ -606,6 +606,8 @@ private class StructCanonicalPath extends MkStructCanonicalPath { /** Gets the underlying struct. */ Struct getStruct() { hasExtendedCanonicalPath(result, crate, path) } + string getExtendedCanonicalPath() { result = path } + string toString() { result = this.getStruct().getName().getText() } Location getLocation() { result = this.getStruct().getLocation() } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index 3503ad073328..492764b3cf54 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -32,6 +32,22 @@ module Input implements InputSig { arg = v.getExtendedCanonicalPath() + "::" + field ) ) + or + exists(StructCanonicalPath s, string field | + result = "Struct" and + c = TStructFieldContent(s, field) and + arg = s.getExtendedCanonicalPath() + "::" + field + ) + or + result = "ArrayElement" and + c = TArrayElement() and + arg = "" + or + exists(int pos | + result = "Tuple" and + c = TTuplePositionContent(pos) and + arg = pos.toString() + ) ) } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll b/rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll new file mode 100644 index 000000000000..ebffe41a185d --- /dev/null +++ b/rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll @@ -0,0 +1,98 @@ +/** + * Defines extensible predicates for contributing library models from data extensions. + */ + +private import rust +private import codeql.rust.dataflow.FlowSummary + +/** + * Holds if in a call to the function with canonical path `path`, defined in the + * crate `crate`, the value referred to by `output` is a flow source of the given + * `kind`. + * + * `output = "ReturnValue"` simply means the result of the call itself. + * + * The following kinds are supported: + * + * - `remote`: a general remote flow source. + */ +extensible predicate sourceModel( + string crate, string path, string output, string kind, string provenance, + QlBuiltins::ExtensionId madId +); + +/** + * Holds if in a call to the function with canonical path `path`, defined in the + * crate `crate`, the value referred to by `input` is a flow sink of the given + * `kind`. + * + * For example, `input = Argument[0]` means the first argument of the call. + * + * The following kinds are supported: + * + * - `sql-injection`: a flow sink for SQL injection. + */ +extensible predicate sinkModel( + string crate, string path, string input, string kind, string provenance, + QlBuiltins::ExtensionId madId +); + +/** + * Holds if in a call to the function with canonical path `path`, defined in the + * crate `crate`, the value referred to by `input` can flow to the value referred + * to by `output`. + * + * `kind` should be either `value` or `taint`, for value-preserving or taint-preserving + * steps, respectively. + */ +extensible predicate summaryModel( + string crate, string path, string input, string output, string kind, string provenance, + QlBuiltins::ExtensionId madId +); + +/** + * Holds if the given extension tuple `madId` should pretty-print as `model`. + * + * This predicate should only be used in tests. + */ +predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) { + exists(string crate, string path, string output, string kind | + sourceModel(crate, path, kind, output, _, madId) and + model = "Source: " + crate + "; " + path + "; " + output + "; " + kind + ) + or + exists(string crate, string path, string input, string kind | + sinkModel(crate, path, kind, input, _, madId) and + model = "Sink: " + crate + "; " + path + "; " + input + "; " + kind + ) + or + exists(string type, string path, string input, string output, string kind | + summaryModel(type, path, input, output, kind, _, madId) and + model = "Summary: " + type + "; " + path + "; " + input + "; " + output + "; " + kind + ) +} + +private class SummarizedCallableFromModel extends SummarizedCallable::Range { + private string crate; + private string path; + + SummarizedCallableFromModel() { + summaryModel(crate, path, _, _, _, _, _) and + this = crate + "::_::" + path + } + + override predicate propagatesFlow( + string input, string output, boolean preservesValue, string model + ) { + exists(string kind, QlBuiltins::ExtensionId madId | + summaryModel(crate, path, input, output, kind, _, madId) and + model = "MaD:" + madId.toString() + | + kind = "value" and + preservesValue = true + or + kind = "taint" and + preservesValue = false + ) + } +} diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/empty.model.yml b/rust/ql/lib/codeql/rust/dataflow/internal/empty.model.yml new file mode 100644 index 000000000000..1a33951dfc38 --- /dev/null +++ b/rust/ql/lib/codeql/rust/dataflow/internal/empty.model.yml @@ -0,0 +1,17 @@ +extensions: + # Make sure that the extensible model predicates have at least one definition + # to avoid errors about undefined extensionals. + - addsTo: + pack: codeql/rust-all + extensible: sourceModel + data: [] + + - addsTo: + pack: codeql/rust-all + extensible: sinkModel + data: [] + + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: [] diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml new file mode 100644 index 000000000000..db61e6c70b5b --- /dev/null +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: + - ["lang:core", "::unwrap", "Argument[self].Variant[crate::option::Option::Some(0)]", "ReturnValue", "value", "manual"] diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 53ccf6dfced4..181e992287ce 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -13,4 +13,6 @@ dependencies: codeql/ssa: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} +dataExtensions: + - /**/*.model.yml warnOnImplicitThis: true 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 9ee2f23f08c6..d464f5625817 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -1,4 +1,5 @@ models +| 1 | Summary: lang:core; ::unwrap; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value | edges | main.rs:19:13:19:21 | source(...) | main.rs:20:10:20:10 | s | provenance | | | main.rs:24:13:24:21 | source(...) | main.rs:27:10:27:10 | c | provenance | | @@ -35,7 +36,7 @@ edges | main.rs:214:14:214:14 | n | main.rs:214:25:214:25 | n | provenance | | | 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 | s1.unwrap(...) | provenance | | +| main.rs:225:10:225:11 | s1 [Some] | main.rs:225:10:225:20 | s1.unwrap(...) | provenance | MaD:1 | | 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 | | diff --git a/rust/ql/test/library-tests/dataflow/models/main.rs b/rust/ql/test/library-tests/dataflow/models/main.rs index 337cec5a220e..dbff546732a5 100644 --- a/rust/ql/test/library-tests/dataflow/models/main.rs +++ b/rust/ql/test/library-tests/dataflow/models/main.rs @@ -90,11 +90,102 @@ fn test_set_var_field() { } } +struct MyStruct { + field1: i64, + field2: i64, +} + +// has a flow model +fn get_struct_field(s: MyStruct) -> i64 { + 0 +} + +fn test_get_struct_field() { + let s = source(6); + let my_struct = MyStruct { + field1: s, + field2: 0, + }; + sink(get_struct_field(my_struct)); // $ hasValueFlow=6 + let my_struct2 = MyStruct { + field1: 0, + field2: s, + }; + sink(get_struct_field(my_struct2)); +} + +// has a flow model +fn set_struct_field(i: i64) -> MyStruct { + MyStruct { + field1: 0, + field2: 1, + } +} + +fn test_set_struct_field() { + let s = source(7); + let my_struct = set_struct_field(s); + sink(my_struct.field1); + sink(my_struct.field2); // $ MISSING: hasValueFlow=7 +} + +// has a flow model +fn get_array_element(a: [i64; 1]) -> i64 { + 0 +} + +fn test_get_array_element() { + let s = source(8); + sink(get_array_element([s])); // $ hasValueFlow=8 +} + +// has a flow model +fn set_array_element(i: i64) -> [i64; 1] { + [0] +} + +fn test_set_array_element() { + let s = source(9); + let arr = set_array_element(s); + sink(arr[0]); // $ hasValueFlow=9 +} + +// has a flow model +fn get_tuple_element(a: (i64, i64)) -> i64 { + 0 +} + +fn test_get_tuple_element() { + let s = source(10); + let t = (s, 0); + sink(get_tuple_element(t)); // $ hasValueFlow=10 + let t = (0, s); + sink(get_tuple_element(t)); +} + +// has a flow model +fn set_tuple_element(i: i64) -> (i64, i64) { + (0, 1) +} + +fn test_set_tuple_element() { + let s = source(11); + let t = set_tuple_element(s); + sink(t.0); + sink(t.1); // $ hasValueFlow=11 +} + fn main() { test_identify(); test_get_var_pos(); test_set_var_pos(); test_get_var_field(); test_set_var_field(); + test_get_struct_field(); + test_set_struct_field(); + test_get_array_element(); + test_set_array_element(); + test_get_tuple_element(); + test_set_tuple_element(); let dummy = Some(0); // ensure that the the `lang:core` crate is extracted } diff --git a/rust/ql/test/library-tests/dataflow/models/models.expected b/rust/ql/test/library-tests/dataflow/models/models.expected index 6ebc72099cae..5b0d5c1588e5 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.expected +++ b/rust/ql/test/library-tests/dataflow/models/models.expected @@ -1,25 +1,36 @@ models +| 1 | Summary: repo::test; crate::coerce; Argument[0]; ReturnValue; taint | +| 2 | Summary: repo::test; crate::get_array_element; Argument[0].ArrayElement; ReturnValue; value | +| 3 | Summary: repo::test; crate::get_struct_field; Argument[0].Struct[crate::MyStruct::field1]; ReturnValue; value | +| 4 | Summary: repo::test; crate::get_tuple_element; Argument[0].Tuple[0]; ReturnValue; value | +| 5 | Summary: repo::test; crate::get_var_field; Argument[0].Variant[crate::MyFieldEnum::C::field_c]; ReturnValue; value | +| 6 | Summary: repo::test; crate::get_var_pos; Argument[0].Variant[crate::MyPosEnum::A(0)]; ReturnValue; value | +| 7 | Summary: repo::test; crate::identity; Argument[0]; ReturnValue; value | +| 8 | Summary: repo::test; crate::set_array_element; Argument[0]; ReturnValue.ArrayElement; value | +| 9 | Summary: repo::test; crate::set_tuple_element; Argument[0]; ReturnValue.Tuple[1]; value | +| 10 | Summary: repo::test; crate::set_var_field; Argument[0]; ReturnValue.Variant[crate::MyFieldEnum::D::field_d]; value | +| 11 | Summary: repo::test; crate::set_var_pos; Argument[0]; ReturnValue.Variant[crate::MyPosEnum::B(0)]; value | edges | main.rs:15:13:15:21 | source(...) | main.rs:16:19:16:19 | s | provenance | | | main.rs:15:13:15:21 | source(...) | main.rs:16:19:16:19 | s | provenance | | -| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | | -| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | | +| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | MaD:7 | +| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | MaD:7 | | main.rs:25:13:25:22 | source(...) | main.rs:26:17:26:17 | s | provenance | | -| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | | +| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | MaD:1 | | main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | | | main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | | | main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:42:22:42:23 | e1 [A] | provenance | | | main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:42:22:42:23 | e1 [A] | provenance | | | main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | | | main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | | -| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | | -| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | | +| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:6 | +| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:6 | | main.rs:53:13:53:21 | source(...) | main.rs:54:26:54:26 | s | provenance | | | main.rs:53:13:53:21 | source(...) | main.rs:54:26:54:26 | s | provenance | | | main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | | | main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | | -| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | | -| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | | +| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:11 | +| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:11 | | main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | | | main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | | | main.rs:57:22:57:22 | i | main.rs:57:33:57:33 | i | provenance | | @@ -30,18 +41,56 @@ edges | main.rs:73:14:73:42 | ...::C {...} [C] | main.rs:74:24:74:25 | e1 [C] | provenance | | | main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | | | main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | | -| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | | -| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | | +| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:5 | +| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:5 | | main.rs:85:13:85:21 | source(...) | main.rs:86:28:86:28 | s | provenance | | | main.rs:85:13:85:21 | source(...) | main.rs:86:28:86:28 | s | provenance | | | main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | | | main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | | -| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | | -| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | | +| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:10 | +| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:10 | | main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | | | main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | | | main.rs:89:35:89:35 | i | main.rs:89:47:89:47 | i | provenance | | | main.rs:89:35:89:35 | i | main.rs:89:47:89:47 | i | provenance | | +| main.rs:104:13:104:21 | source(...) | main.rs:106:17:106:17 | s | provenance | | +| main.rs:104:13:104:21 | source(...) | main.rs:106:17:106:17 | s | provenance | | +| main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | main.rs:109:27:109:35 | my_struct [MyStruct.field1] | provenance | | +| main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | main.rs:109:27:109:35 | my_struct [MyStruct.field1] | provenance | | +| main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | | +| main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:3 | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:3 | +| main.rs:138:13:138:21 | source(...) | main.rs:139:29:139:29 | s | provenance | | +| main.rs:138:13:138:21 | source(...) | main.rs:139:29:139:29 | s | provenance | | +| main.rs:139:28:139:30 | [...] [array[]] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:2 | +| main.rs:139:28:139:30 | [...] [array[]] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:2 | +| main.rs:139:29:139:29 | s | main.rs:139:28:139:30 | [...] [array[]] | provenance | | +| main.rs:139:29:139:29 | s | main.rs:139:28:139:30 | [...] [array[]] | provenance | | +| main.rs:148:13:148:21 | source(...) | main.rs:149:33:149:33 | s | provenance | | +| main.rs:148:13:148:21 | source(...) | main.rs:149:33:149:33 | s | provenance | | +| main.rs:149:15:149:34 | set_array_element(...) [array[]] | main.rs:150:10:150:12 | arr [array[]] | provenance | | +| main.rs:149:15:149:34 | set_array_element(...) [array[]] | main.rs:150:10:150:12 | arr [array[]] | provenance | | +| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [array[]] | provenance | MaD:8 | +| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [array[]] | provenance | MaD:8 | +| main.rs:150:10:150:12 | arr [array[]] | main.rs:150:10:150:15 | arr[0] | provenance | | +| main.rs:150:10:150:12 | arr [array[]] | main.rs:150:10:150:15 | arr[0] | provenance | | +| main.rs:159:13:159:22 | source(...) | main.rs:160:14:160:14 | s | provenance | | +| main.rs:159:13:159:22 | source(...) | main.rs:160:14:160:14 | s | provenance | | +| main.rs:160:13:160:18 | TupleExpr [tuple.0] | main.rs:161:28:161:28 | t [tuple.0] | provenance | | +| main.rs:160:13:160:18 | TupleExpr [tuple.0] | main.rs:161:28:161:28 | t [tuple.0] | provenance | | +| main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | | +| main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | | +| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:4 | +| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:4 | +| main.rs:172:13:172:22 | source(...) | main.rs:173:31:173:31 | s | provenance | | +| main.rs:172:13:172:22 | source(...) | main.rs:173:31:173:31 | s | provenance | | +| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:175:10:175:10 | t [tuple.1] | provenance | | +| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:175:10:175:10 | t [tuple.1] | provenance | | +| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:9 | +| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:9 | +| main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | | +| main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | | nodes | main.rs:15:13:15:21 | source(...) | semmle.label | source(...) | | main.rs:15:13:15:21 | source(...) | semmle.label | source(...) | @@ -96,6 +145,54 @@ nodes | main.rs:89:35:89:35 | i | semmle.label | i | | main.rs:89:47:89:47 | i | semmle.label | i | | main.rs:89:47:89:47 | i | semmle.label | i | +| main.rs:104:13:104:21 | source(...) | semmle.label | source(...) | +| main.rs:104:13:104:21 | source(...) | semmle.label | source(...) | +| main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | semmle.label | MyStruct {...} [MyStruct.field1] | +| main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | semmle.label | MyStruct {...} [MyStruct.field1] | +| main.rs:106:17:106:17 | s | semmle.label | s | +| main.rs:106:17:106:17 | s | semmle.label | s | +| main.rs:109:10:109:36 | get_struct_field(...) | semmle.label | get_struct_field(...) | +| main.rs:109:10:109:36 | get_struct_field(...) | semmle.label | get_struct_field(...) | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | semmle.label | my_struct [MyStruct.field1] | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | semmle.label | my_struct [MyStruct.field1] | +| main.rs:138:13:138:21 | source(...) | semmle.label | source(...) | +| main.rs:138:13:138:21 | source(...) | semmle.label | source(...) | +| main.rs:139:10:139:31 | get_array_element(...) | semmle.label | get_array_element(...) | +| main.rs:139:10:139:31 | get_array_element(...) | semmle.label | get_array_element(...) | +| main.rs:139:28:139:30 | [...] [array[]] | semmle.label | [...] [array[]] | +| main.rs:139:28:139:30 | [...] [array[]] | semmle.label | [...] [array[]] | +| main.rs:139:29:139:29 | s | semmle.label | s | +| main.rs:139:29:139:29 | s | semmle.label | s | +| main.rs:148:13:148:21 | source(...) | semmle.label | source(...) | +| main.rs:148:13:148:21 | source(...) | semmle.label | source(...) | +| main.rs:149:15:149:34 | set_array_element(...) [array[]] | semmle.label | set_array_element(...) [array[]] | +| main.rs:149:15:149:34 | set_array_element(...) [array[]] | semmle.label | set_array_element(...) [array[]] | +| main.rs:149:33:149:33 | s | semmle.label | s | +| main.rs:149:33:149:33 | s | semmle.label | s | +| main.rs:150:10:150:12 | arr [array[]] | semmle.label | arr [array[]] | +| main.rs:150:10:150:12 | arr [array[]] | semmle.label | arr [array[]] | +| main.rs:150:10:150:15 | arr[0] | semmle.label | arr[0] | +| main.rs:150:10:150:15 | arr[0] | semmle.label | arr[0] | +| main.rs:159:13:159:22 | source(...) | semmle.label | source(...) | +| main.rs:159:13:159:22 | source(...) | semmle.label | source(...) | +| main.rs:160:13:160:18 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:160:13:160:18 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:160:14:160:14 | s | semmle.label | s | +| main.rs:160:14:160:14 | s | semmle.label | s | +| main.rs:161:10:161:29 | get_tuple_element(...) | semmle.label | get_tuple_element(...) | +| main.rs:161:10:161:29 | get_tuple_element(...) | semmle.label | get_tuple_element(...) | +| main.rs:161:28:161:28 | t [tuple.0] | semmle.label | t [tuple.0] | +| main.rs:161:28:161:28 | t [tuple.0] | semmle.label | t [tuple.0] | +| main.rs:172:13:172:22 | source(...) | semmle.label | source(...) | +| main.rs:172:13:172:22 | source(...) | semmle.label | source(...) | +| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | semmle.label | set_tuple_element(...) [tuple.1] | +| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | semmle.label | set_tuple_element(...) [tuple.1] | +| main.rs:173:31:173:31 | s | semmle.label | s | +| main.rs:173:31:173:31 | s | semmle.label | s | +| main.rs:175:10:175:10 | t [tuple.1] | semmle.label | t [tuple.1] | +| main.rs:175:10:175:10 | t [tuple.1] | semmle.label | t [tuple.1] | +| main.rs:175:10:175:12 | t.1 | semmle.label | t.1 | +| main.rs:175:10:175:12 | t.1 | semmle.label | t.1 | subpaths testFailures invalidSpecComponent @@ -111,3 +208,13 @@ invalidSpecComponent | main.rs:74:10:74:26 | get_var_field(...) | main.rs:72:13:72:21 | source(...) | main.rs:74:10:74:26 | get_var_field(...) | $@ | main.rs:72:13:72:21 | source(...) | source(...) | | main.rs:89:47:89:47 | i | main.rs:85:13:85:21 | source(...) | main.rs:89:47:89:47 | i | $@ | main.rs:85:13:85:21 | source(...) | source(...) | | main.rs:89:47:89:47 | i | main.rs:85:13:85:21 | source(...) | main.rs:89:47:89:47 | i | $@ | main.rs:85:13:85:21 | source(...) | source(...) | +| main.rs:109:10:109:36 | get_struct_field(...) | main.rs:104:13:104:21 | source(...) | main.rs:109:10:109:36 | get_struct_field(...) | $@ | main.rs:104:13:104:21 | source(...) | source(...) | +| main.rs:109:10:109:36 | get_struct_field(...) | main.rs:104:13:104:21 | source(...) | main.rs:109:10:109:36 | get_struct_field(...) | $@ | main.rs:104:13:104:21 | source(...) | source(...) | +| main.rs:139:10:139:31 | get_array_element(...) | main.rs:138:13:138:21 | source(...) | main.rs:139:10:139:31 | get_array_element(...) | $@ | main.rs:138:13:138:21 | source(...) | source(...) | +| main.rs:139:10:139:31 | get_array_element(...) | main.rs:138:13:138:21 | source(...) | main.rs:139:10:139:31 | get_array_element(...) | $@ | main.rs:138:13:138:21 | source(...) | source(...) | +| main.rs:150:10:150:15 | arr[0] | main.rs:148:13:148:21 | source(...) | main.rs:150:10:150:15 | arr[0] | $@ | main.rs:148:13:148:21 | source(...) | source(...) | +| main.rs:150:10:150:15 | arr[0] | main.rs:148:13:148:21 | source(...) | main.rs:150:10:150:15 | arr[0] | $@ | main.rs:148:13:148:21 | source(...) | source(...) | +| main.rs:161:10:161:29 | get_tuple_element(...) | main.rs:159:13:159:22 | source(...) | main.rs:161:10:161:29 | get_tuple_element(...) | $@ | main.rs:159:13:159:22 | source(...) | source(...) | +| main.rs:161:10:161:29 | get_tuple_element(...) | main.rs:159:13:159:22 | source(...) | main.rs:161:10:161:29 | get_tuple_element(...) | $@ | main.rs:159:13:159:22 | source(...) | source(...) | +| main.rs:175:10:175:12 | t.1 | main.rs:172:13:172:22 | source(...) | main.rs:175:10:175:12 | t.1 | $@ | main.rs:172:13:172:22 | source(...) | source(...) | +| main.rs:175:10:175:12 | t.1 | main.rs:172:13:172:22 | source(...) | main.rs:175:10:175:12 | t.1 | $@ | main.rs:172:13:172:22 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/models/models.ext.yml b/rust/ql/test/library-tests/dataflow/models/models.ext.yml new file mode 100644 index 000000000000..80a19b3e8dac --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/models/models.ext.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: + - ["repo::test", "crate::identity", "Argument[0]", "ReturnValue", "value", "manual"] + - ["repo::test", "crate::coerce", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["repo::test", "crate::get_var_pos", "Argument[0].Variant[crate::MyPosEnum::A(0)]", "ReturnValue", "value", "manual"] + - ["repo::test", "crate::set_var_pos", "Argument[0]", "ReturnValue.Variant[crate::MyPosEnum::B(0)]", "value", "manual"] + - ["repo::test", "crate::get_var_field", "Argument[0].Variant[crate::MyFieldEnum::C::field_c]", "ReturnValue", "value", "manual"] + - ["repo::test", "crate::set_var_field", "Argument[0]", "ReturnValue.Variant[crate::MyFieldEnum::D::field_d]", "value", "manual"] + - ["repo::test", "crate::get_struct_field", "Argument[0].Struct[crate::MyStruct::field1]", "ReturnValue", "value", "manual"] + - ["repo::test", "crate::set_struct_field", "Argument[0]", "ReturnValue.Struct[crate::MyStruct::field2]", "value", "manual"] + - ["repo::test", "crate::get_array_element", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["repo::test", "crate::set_array_element", "Argument[0]", "ReturnValue.ArrayElement", "value", "manual"] + - ["repo::test", "crate::get_tuple_element", "Argument[0].Tuple[0]", "ReturnValue", "value", "manual"] + - ["repo::test", "crate::set_tuple_element", "Argument[0]", "ReturnValue.Tuple[1]", "value", "manual"] diff --git a/rust/ql/test/library-tests/dataflow/models/models.ql b/rust/ql/test/library-tests/dataflow/models/models.ql index 53c3f5de4be3..10d2f9f91b70 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.ql +++ b/rust/ql/test/library-tests/dataflow/models/models.ql @@ -15,66 +15,6 @@ query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) Private::External::invalidSpecComponent(s, c) } -private class SummarizedCallableIdentity extends SummarizedCallable::Range { - SummarizedCallableIdentity() { this = "repo::test::_::crate::identity" } - - override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = "Argument[0]" and - output = "ReturnValue" and - preservesValue = true - } -} - -private class SummarizedCallableCoerce extends SummarizedCallable::Range { - SummarizedCallableCoerce() { this = "repo::test::_::crate::coerce" } - - override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = "Argument[0]" and - output = "ReturnValue" and - preservesValue = false - } -} - -private class SummarizedCallableGetVarPos extends SummarizedCallable::Range { - SummarizedCallableGetVarPos() { this = "repo::test::_::crate::get_var_pos" } - - override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = "Argument[0].Variant[crate::MyPosEnum::A(0)]" and - output = "ReturnValue" and - preservesValue = true - } -} - -private class SummarizedCallableSetVarPos extends SummarizedCallable::Range { - SummarizedCallableSetVarPos() { this = "repo::test::_::crate::set_var_pos" } - - override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = "Argument[0]" and - output = "ReturnValue.Variant[crate::MyPosEnum::B(0)]" and - preservesValue = true - } -} - -private class SummarizedCallableGetVarField extends SummarizedCallable::Range { - SummarizedCallableGetVarField() { this = "repo::test::_::crate::get_var_field" } - - override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = "Argument[0].Variant[crate::MyFieldEnum::C::field_c]" and - output = "ReturnValue" and - preservesValue = true - } -} - -private class SummarizedCallableSetVarField extends SummarizedCallable::Range { - SummarizedCallableSetVarField() { this = "repo::test::_::crate::set_var_field" } - - override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = "Argument[0]" and - output = "ReturnValue.Variant[crate::MyFieldEnum::D::field_d]" and - preservesValue = true - } -} - module CustomConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { DefaultFlowConfig::isSource(source) } diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref index 504d27ff30cc..7aee10fcc4a5 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.qlref @@ -1,2 +1,4 @@ query: queries/security/CWE-089/SqlInjection.ql -postprocess: utils/InlineExpectationsTestQuery.ql +postprocess: + - utils/PrettyPrintModels.ql + - utils/InlineExpectationsTestQuery.ql diff --git a/rust/ql/test/utils/InlineFlowTest.qll b/rust/ql/test/utils/InlineFlowTest.qll index dcf8ad8c4459..cb5b9f72abb2 100644 --- a/rust/ql/test/utils/InlineFlowTest.qll +++ b/rust/ql/test/utils/InlineFlowTest.qll @@ -9,6 +9,7 @@ private import codeql.rust.controlflow.CfgNodes private import codeql.rust.dataflow.DataFlow private import codeql.rust.dataflow.internal.DataFlowImpl private import codeql.rust.dataflow.internal.TaintTrackingImpl +private import codeql.rust.dataflow.internal.ModelsAsData as MaD private import internal.InlineExpectationsTestImpl as InlineExpectationsTestImpl // Holds if the target expression of `call` is a path and the string representation of the path is `name`. @@ -38,7 +39,7 @@ private module FlowTestImpl implements InputSig { exists(sink) } - predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) { none() } + predicate interpretModelForTest = MaD::interpretModelForTest/2; } import InlineFlowTestMake diff --git a/rust/ql/test/utils/PrettyPrintModels.ql b/rust/ql/test/utils/PrettyPrintModels.ql new file mode 100644 index 000000000000..9740f20433fa --- /dev/null +++ b/rust/ql/test/utils/PrettyPrintModels.ql @@ -0,0 +1,7 @@ +/** + * @kind test-postprocess + */ + +import codeql.rust.dataflow.internal.ModelsAsData +import codeql.dataflow.test.ProvenancePathGraph +import codeql.dataflow.test.ProvenancePathGraph::TestPostProcessing::TranslateProvenanceResults diff --git a/rust/ql/test/utils/ProvenancePathGraph.qll b/rust/ql/test/utils/ProvenancePathGraph.qll new file mode 100644 index 000000000000..fd5b771941d5 --- /dev/null +++ b/rust/ql/test/utils/ProvenancePathGraph.qll @@ -0,0 +1,8 @@ +private import codeql.dataflow.DataFlow as DF +private import codeql.dataflow.test.ProvenancePathGraph as Graph +private import codeql.rust.dataflow.internal.ModelsAsData + +/** Transforms a `PathGraph` by printing the provenance information. */ +module ShowProvenance PathGraph> { + import Graph::ShowProvenance +} From 5624a77176db4fe7d36038d7ce6204970d2c5337 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 9 Dec 2024 13:59:01 +0100 Subject: [PATCH 155/213] C#: Use TEST_TEMPDIR when set for test files. --- csharp/extractor/Semmle.Util.Tests/LongPaths.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Util.Tests/LongPaths.cs b/csharp/extractor/Semmle.Util.Tests/LongPaths.cs index 1c0d5e2ce139..c1583e275036 100644 --- a/csharp/extractor/Semmle.Util.Tests/LongPaths.cs +++ b/csharp/extractor/Semmle.Util.Tests/LongPaths.cs @@ -12,7 +12,7 @@ namespace SemmleTests.Semmle.Util /// public sealed class LongPaths : IDisposable { - private static readonly string tmpDir = Path.GetTempPath(); + private static readonly string tmpDir = Environment.GetEnvironmentVariable("TEST_TMPDIR") ?? Path.GetTempPath(); private static readonly string shortPath = Path.Combine(tmpDir, "test.txt"); private static readonly string longPath = Path.Combine(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ccccccccccccccccccccccccccccccc", "ddddddddddddddddddddddddddddddddddddd", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "fffffffffffffffffffffffffffffffff", From d735a1433bc1b8cf363c484923e1ed8983e0afc6 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 13:23:15 +0000 Subject: [PATCH 156/213] C++: Also flow to the return value of 'operator='. --- cpp/ql/lib/ext/CSimpleArray.model.yml | 3 ++- .../dataflow/external-models/flow.expected | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/ext/CSimpleArray.model.yml b/cpp/ql/lib/ext/CSimpleArray.model.yml index 1c6337bf74c3..8daae929651e 100644 --- a/cpp/ql/lib/ext/CSimpleArray.model.yml +++ b/cpp/ql/lib/ext/CSimpleArray.model.yml @@ -8,4 +8,5 @@ extensions: - ["", "CSimpleArray", True, "GetData", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CSimpleArray", True, "SetAtIndex", "", "", "Argument[*1]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CSimpleArray", True, "operator[]", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - - ["", "CSimpleArray", True, "operator=", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] \ No newline at end of file + - ["", "CSimpleArray", True, "operator=", "", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["", "CSimpleArray", True, "operator=", "", "", "Argument[*0].Element[@]", "ReturnValue[*].Element[@]", "value", "manual"] \ No newline at end of file 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 8930cadb8d8a..81a9c605f005 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:799 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:797 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:798 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:800 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:798 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:799 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:798 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:799 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:799 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:800 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | From d3dc318ba1504c4e74874efe5e9d118ea5dd8784 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 13:26:46 +0000 Subject: [PATCH 157/213] C++: Make 'GetValueAt' a value-preserving step. --- cpp/ql/lib/ext/CSimpleMap.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/ext/CSimpleMap.model.yml b/cpp/ql/lib/ext/CSimpleMap.model.yml index 323b5be01742..814e814228ed 100644 --- a/cpp/ql/lib/ext/CSimpleMap.model.yml +++ b/cpp/ql/lib/ext/CSimpleMap.model.yml @@ -4,7 +4,7 @@ extensions: extensible: summaryModel data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance - ["", "CSimpleMap", True, "Add", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - - ["", "CSimpleMap", True, "GetValueAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "taint", "manual"] + - ["", "CSimpleMap", True, "GetValueAt", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] - ["", "CSimpleMap", True, "Lookup", "", "", "Argument[-1].Element[@]", "ReturnValue.Element[@]", "value", "manual"] - ["", "CSimpleMap", True, "SetAt", "", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] - ["", "CSimpleMap", True, "SetAtIndex", "", "", "Argument[*@2]", "Argument[-1].Element[@]", "value", "manual"] From db86f6aaf92b33bed3fb0d8da9535b353cb28ee4 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 13:32:22 +0000 Subject: [PATCH 158/213] C++: Fix annotation. --- cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp index 9a57fd604a5e..0e70a101620f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp @@ -785,7 +785,7 @@ void test_CSimpleMap() { { CSimpleMap a; auto pos = a.FindKey("hello"); - sink(a.GetValueAt(pos)); // $ MISSING: ir + sink(a.GetValueAt(pos)); // clean } { CSimpleMap a; From 674dbce36d71d284790d6ecc1864a7887424d835 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 13:38:37 +0000 Subject: [PATCH 159/213] C++: Add taint flow through 'CRegKey::Create'. --- cpp/ql/lib/ext/CRegKey.model.yml | 1 + .../dataflow/external-models/flow.expected | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/ext/CRegKey.model.yml b/cpp/ql/lib/ext/CRegKey.model.yml index 45114347ee0d..84d85c40a018 100644 --- a/cpp/ql/lib/ext/CRegKey.model.yml +++ b/cpp/ql/lib/ext/CRegKey.model.yml @@ -5,6 +5,7 @@ extensions: data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance - ["", "CRegKey", True, "CRegKey", "(CRegKey &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] - ["", "CRegKey", True, "CRegKey", "(HKEY)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["", "CRegKey", True, "Create", "", "", "Argument[*1]", "Argument[-1]", "taint", "manual"] - ["", "CRegKey", True, "Attach", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CRegKey", True, "QueryBinaryValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryDWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] 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 81a9c605f005..137642d522a4 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -11,14 +11,14 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 | -| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:800 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:798 | -| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:799 | +| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:801 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:799 | +| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:800 | | test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | | | test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | | -| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:799 | +| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:800 | | test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | | -| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:800 | +| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:801 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | From 7f87a25768dbd14718079766f91d04b45560abb8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 13:41:14 +0000 Subject: [PATCH 160/213] C++: Fix 'QueryMultiStringValue' model. --- cpp/ql/lib/ext/CRegKey.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/ext/CRegKey.model.yml b/cpp/ql/lib/ext/CRegKey.model.yml index 84d85c40a018..a68a360afc09 100644 --- a/cpp/ql/lib/ext/CRegKey.model.yml +++ b/cpp/ql/lib/ext/CRegKey.model.yml @@ -9,7 +9,7 @@ extensions: - ["", "CRegKey", True, "Attach", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["", "CRegKey", True, "QueryBinaryValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryDWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - - ["", "CRegKey", True, "QueryMultiStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryMultiStringValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryQWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"] From 184dfc24b9e199859db493dbd58c59f307d4ac1c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 13:42:39 +0000 Subject: [PATCH 161/213] C++: Fix 'QueryStringValue' model. --- cpp/ql/lib/ext/CRegKey.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/ext/CRegKey.model.yml b/cpp/ql/lib/ext/CRegKey.model.yml index a68a360afc09..fd13291591dc 100644 --- a/cpp/ql/lib/ext/CRegKey.model.yml +++ b/cpp/ql/lib/ext/CRegKey.model.yml @@ -11,7 +11,7 @@ extensions: - ["", "CRegKey", True, "QueryDWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryMultiStringValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryQWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - - ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"] + - ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(DWORD &,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[**0]", "taint", "manual"] From 5f33733b6e87f06d155bda4114d8174b0b038c1c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 14:27:24 +0000 Subject: [PATCH 162/213] C++: Fix 'QueryValue' model. --- cpp/ql/lib/ext/CRegKey.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/ext/CRegKey.model.yml b/cpp/ql/lib/ext/CRegKey.model.yml index fd13291591dc..6b3da2adfb7c 100644 --- a/cpp/ql/lib/ext/CRegKey.model.yml +++ b/cpp/ql/lib/ext/CRegKey.model.yml @@ -14,7 +14,7 @@ extensions: - ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(DWORD &,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] - - ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[**0]", "taint", "manual"] + - ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "operator HKEY", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] - ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "Argument[-1]", "value", "manual"] \ No newline at end of file From 8bdd10c0c23ccb3419002fa19f295be465feb4a8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 14:31:17 +0000 Subject: [PATCH 163/213] C++: Fix spurious columns in 'CRegKey'. --- cpp/ql/lib/ext/CRegKey.model.yml | 6 +++--- .../dataflow/external-models/validatemodels.expected | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/ext/CRegKey.model.yml b/cpp/ql/lib/ext/CRegKey.model.yml index 6b3da2adfb7c..1cf2a7d67733 100644 --- a/cpp/ql/lib/ext/CRegKey.model.yml +++ b/cpp/ql/lib/ext/CRegKey.model.yml @@ -15,6 +15,6 @@ extensions: - ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(DWORD &,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] - ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"] - - ["", "CRegKey", True, "QueryValue", "operator HKEY", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] - - ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "Argument[-1]", "value", "manual"] \ No newline at end of file + - ["", "CRegKey", True, "operator HKEY", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["", "CRegKey", True, "operator=", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["", "CRegKey", True, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index 423e238ecd7e..b2c54e67c2ff 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -1,4 +1,5 @@ | Dubious member name "operator BSTR" in summary model. | +| Dubious member name "operator HKEY" in summary model. | | Dubious member name "operator LPCSTR" in summary model. | | Dubious member name "operator LPSAFEARRAY" in summary model. | | Dubious member name "operator LPSTR" in summary model. | @@ -44,5 +45,3 @@ | Dubious signature "(size_type,const T &,const Allocator &)" in summary model. | | Dubious signature "(vector &&)" in summary model. | | Dubious signature "(vector &&,const Allocator &)" in summary model. | -| Dubious signature "operator HKEY" in summary model. | -| Dubious signature "operator=" in summary model. | From 9bcdfb6d019cf9f0099805649a1260c982a844ae Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 15:06:22 +0000 Subject: [PATCH 164/213] C++: VariableAddressInstructions with array types are not single-object types. --- .../lib/semmle/code/cpp/ir/dataflow/internal/TypeFlow.qll | 7 +++++-- .../dataflow/dataflow-tests/test-source-sink.expected | 1 + cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TypeFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TypeFlow.qll index 41e30e2902b1..df63b547da3b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TypeFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TypeFlow.qll @@ -27,8 +27,11 @@ private module Input implements TypeFlowInput { } private predicate hasExactSingleType(Instruction i) { - // The address of a variable is always a single object - i instanceof VariableAddressInstruction + // The address of a variable is always a single object (unless it's an array) + exists(VariableAddressInstruction vai | + i = vai and + not vai.getResultType() instanceof ArrayType + ) or // A reference always points to a single object i.getResultLanguageType().hasUnspecifiedType(any(ReferenceType rt), false) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index 6a65ddf952cf..fa141b614ea6 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -326,6 +326,7 @@ irFlow | test.cpp:1069:9:1069:14 | call to source | test.cpp:1081:10:1081:10 | i | | test.cpp:1117:27:1117:34 | call to source | test.cpp:1117:27:1117:34 | call to source | | test.cpp:1132:11:1132:16 | call to source | test.cpp:1121:8:1121:8 | x | +| test.cpp:1138:17:1138:22 | call to source | test.cpp:1140:8:1140:18 | * ... | | true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x | | true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x | | true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index 33c714a3139a..b138bfb0fba5 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -1137,5 +1137,5 @@ void test_uncertain_array(int n1, int n2) { int data[10]; *(data + 1) = source(); *data = 0; - sink(*(data + 1)); // $ ast=1138:17 ast=1137:7 MISSING: ir + sink(*(data + 1)); // $ ast=1138:17 ast=1137:7 ir } \ No newline at end of file From 0f49ba848de308fd7de80ee4d483e506c64e1925 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 9 Dec 2024 16:04:46 +0000 Subject: [PATCH 165/213] C++: Accept test changes. Nothing exciting to see here. --- .../ConstantSizeArrayOffByOne.expected | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected index fa7f625210d9..eb0212153e8e 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected @@ -21,7 +21,11 @@ edges | test.cpp:85:21:85:36 | buf | test.cpp:87:5:87:31 | access to array | provenance | Config | | test.cpp:85:21:85:36 | buf | test.cpp:88:5:88:27 | access to array | provenance | Config | | test.cpp:85:34:85:36 | buf | test.cpp:85:21:85:36 | buf | provenance | | +| test.cpp:92:9:92:11 | definition of arr | test.cpp:96:13:96:18 | access to array | provenance | Config | | test.cpp:96:13:96:15 | arr | test.cpp:96:13:96:18 | access to array | provenance | Config | +| test.cpp:102:9:102:11 | definition of arr | test.cpp:111:17:111:22 | access to array | provenance | Config | +| test.cpp:102:9:102:11 | definition of arr | test.cpp:115:35:115:40 | access to array | provenance | Config | +| test.cpp:102:9:102:11 | definition of arr | test.cpp:119:17:119:22 | access to array | provenance | Config | | test.cpp:111:17:111:19 | arr | test.cpp:111:17:111:22 | access to array | provenance | Config | | test.cpp:111:17:111:19 | arr | test.cpp:115:35:115:40 | access to array | provenance | Config | | test.cpp:111:17:111:19 | arr | test.cpp:119:17:119:22 | access to array | provenance | Config | @@ -31,40 +35,54 @@ edges | test.cpp:119:17:119:19 | arr | test.cpp:111:17:111:22 | access to array | provenance | Config | | test.cpp:119:17:119:19 | arr | test.cpp:115:35:115:40 | access to array | provenance | Config | | test.cpp:119:17:119:19 | arr | test.cpp:119:17:119:22 | access to array | provenance | Config | +| test.cpp:125:11:125:13 | definition of arr | test.cpp:128:9:128:14 | access to array | provenance | Config | | test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array | provenance | Config | | test.cpp:134:25:134:27 | arr | test.cpp:136:9:136:16 | ... += ... | provenance | Config | | test.cpp:136:9:136:16 | ... += ... | test.cpp:136:9:136:16 | ... += ... | provenance | | | test.cpp:136:9:136:16 | ... += ... | test.cpp:138:13:138:15 | arr | provenance | | +| test.cpp:142:10:142:13 | definition of asdf | test.cpp:143:18:143:21 | asdf | provenance | | | test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr | provenance | | | test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf | provenance | | | test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... | provenance | | +| test.cpp:154:7:154:9 | definition of buf | test.cpp:156:12:156:18 | ... + ... | provenance | Config | | test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... | provenance | Config | | test.cpp:156:12:156:18 | ... + ... | test.cpp:156:12:156:18 | ... + ... | provenance | | | test.cpp:156:12:156:18 | ... + ... | test.cpp:158:17:158:18 | *& ... | provenance | | | test.cpp:158:17:158:18 | *& ... | test.cpp:146:26:146:26 | *p | provenance | | +| test.cpp:217:19:217:24 | definition of buffer | test.cpp:218:16:218:28 | buffer | provenance | | | test.cpp:218:16:218:28 | buffer | test.cpp:220:5:220:11 | access to array | provenance | Config | | test.cpp:218:16:218:28 | buffer | test.cpp:221:5:221:11 | access to array | provenance | Config | | test.cpp:218:23:218:28 | buffer | test.cpp:218:16:218:28 | buffer | provenance | | +| test.cpp:228:10:228:14 | definition of array | test.cpp:229:17:229:29 | array | provenance | | | test.cpp:229:17:229:29 | array | test.cpp:231:5:231:10 | access to array | provenance | Config | | test.cpp:229:17:229:29 | array | test.cpp:232:5:232:10 | access to array | provenance | Config | | test.cpp:229:25:229:29 | array | test.cpp:229:17:229:29 | array | provenance | | | test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | Config | | test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | Config | +| test.cpp:273:19:273:25 | definition of buffer3 | test.cpp:274:14:274:20 | buffer3 | provenance | | | test.cpp:274:14:274:20 | buffer3 | test.cpp:245:30:245:30 | p | provenance | | | test.cpp:274:14:274:20 | buffer3 | test.cpp:274:14:274:20 | buffer3 | provenance | | | test.cpp:277:35:277:35 | p | test.cpp:278:14:278:14 | p | provenance | | | test.cpp:278:14:278:14 | p | test.cpp:245:30:245:30 | p | provenance | | +| test.cpp:282:19:282:25 | definition of buffer1 | test.cpp:283:19:283:25 | buffer1 | provenance | | | test.cpp:283:19:283:25 | buffer1 | test.cpp:277:35:277:35 | p | provenance | | | test.cpp:283:19:283:25 | buffer1 | test.cpp:283:19:283:25 | buffer1 | provenance | | +| test.cpp:285:19:285:25 | definition of buffer2 | test.cpp:286:19:286:25 | buffer2 | provenance | | | test.cpp:286:19:286:25 | buffer2 | test.cpp:277:35:277:35 | p | provenance | | | test.cpp:286:19:286:25 | buffer2 | test.cpp:286:19:286:25 | buffer2 | provenance | | +| test.cpp:288:19:288:25 | definition of buffer3 | test.cpp:289:19:289:25 | buffer3 | provenance | | | test.cpp:289:19:289:25 | buffer3 | test.cpp:277:35:277:35 | p | provenance | | | test.cpp:289:19:289:25 | buffer3 | test.cpp:289:19:289:25 | buffer3 | provenance | | | test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array | provenance | Config | +| test.cpp:305:9:305:12 | definition of arr1 | test.cpp:306:20:306:23 | arr1 | provenance | | | test.cpp:306:20:306:23 | arr1 | test.cpp:292:25:292:27 | arr | provenance | | | test.cpp:306:20:306:23 | arr1 | test.cpp:306:20:306:23 | arr1 | provenance | | +| test.cpp:308:9:308:12 | definition of arr2 | test.cpp:309:20:309:23 | arr2 | provenance | | | test.cpp:309:20:309:23 | arr2 | test.cpp:292:25:292:27 | arr | provenance | | | test.cpp:309:20:309:23 | arr2 | test.cpp:309:20:309:23 | arr2 | provenance | | +| test.cpp:314:10:314:13 | definition of temp | test.cpp:319:19:319:27 | ... + ... | provenance | Config | +| test.cpp:314:10:314:13 | definition of temp | test.cpp:322:19:322:27 | ... + ... | provenance | Config | +| test.cpp:314:10:314:13 | definition of temp | test.cpp:324:23:324:32 | ... + ... | provenance | Config | | test.cpp:319:13:319:27 | ... = ... | test.cpp:325:24:325:26 | end | provenance | | | test.cpp:319:19:319:22 | temp | test.cpp:319:19:319:27 | ... + ... | provenance | Config | | test.cpp:319:19:319:22 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | Config | @@ -114,32 +132,39 @@ nodes | test.cpp:85:34:85:36 | buf | semmle.label | buf | | test.cpp:87:5:87:31 | access to array | semmle.label | access to array | | test.cpp:88:5:88:27 | access to array | semmle.label | access to array | +| test.cpp:92:9:92:11 | definition of arr | semmle.label | definition of arr | | test.cpp:96:13:96:15 | arr | semmle.label | arr | | test.cpp:96:13:96:18 | access to array | semmle.label | access to array | +| test.cpp:102:9:102:11 | definition of arr | semmle.label | definition of arr | | test.cpp:111:17:111:19 | arr | semmle.label | arr | | test.cpp:111:17:111:22 | access to array | semmle.label | access to array | | test.cpp:115:35:115:37 | arr | semmle.label | arr | | test.cpp:115:35:115:40 | access to array | semmle.label | access to array | | test.cpp:119:17:119:19 | arr | semmle.label | arr | | test.cpp:119:17:119:22 | access to array | semmle.label | access to array | +| test.cpp:125:11:125:13 | definition of arr | semmle.label | definition of arr | | test.cpp:128:9:128:11 | arr | semmle.label | arr | | test.cpp:128:9:128:14 | access to array | semmle.label | access to array | | test.cpp:134:25:134:27 | arr | semmle.label | arr | | test.cpp:136:9:136:16 | ... += ... | semmle.label | ... += ... | | test.cpp:136:9:136:16 | ... += ... | semmle.label | ... += ... | | test.cpp:138:13:138:15 | arr | semmle.label | arr | +| test.cpp:142:10:142:13 | definition of asdf | semmle.label | definition of asdf | | test.cpp:143:18:143:21 | asdf | semmle.label | asdf | | test.cpp:143:18:143:21 | asdf | semmle.label | asdf | | test.cpp:146:26:146:26 | *p | semmle.label | *p | | test.cpp:147:4:147:9 | -- ... | semmle.label | -- ... | +| test.cpp:154:7:154:9 | definition of buf | semmle.label | definition of buf | | test.cpp:156:12:156:14 | buf | semmle.label | buf | | test.cpp:156:12:156:18 | ... + ... | semmle.label | ... + ... | | test.cpp:156:12:156:18 | ... + ... | semmle.label | ... + ... | | test.cpp:158:17:158:18 | *& ... | semmle.label | *& ... | +| test.cpp:217:19:217:24 | definition of buffer | semmle.label | definition of buffer | | test.cpp:218:16:218:28 | buffer | semmle.label | buffer | | test.cpp:218:23:218:28 | buffer | semmle.label | buffer | | test.cpp:220:5:220:11 | access to array | semmle.label | access to array | | test.cpp:221:5:221:11 | access to array | semmle.label | access to array | +| test.cpp:228:10:228:14 | definition of array | semmle.label | definition of array | | test.cpp:229:17:229:29 | array | semmle.label | array | | test.cpp:229:25:229:29 | array | semmle.label | array | | test.cpp:231:5:231:10 | access to array | semmle.label | access to array | @@ -147,22 +172,29 @@ nodes | test.cpp:245:30:245:30 | p | semmle.label | p | | test.cpp:245:30:245:30 | p | semmle.label | p | | test.cpp:261:27:261:30 | access to array | semmle.label | access to array | +| test.cpp:273:19:273:25 | definition of buffer3 | semmle.label | definition of buffer3 | | test.cpp:274:14:274:20 | buffer3 | semmle.label | buffer3 | | test.cpp:274:14:274:20 | buffer3 | semmle.label | buffer3 | | test.cpp:277:35:277:35 | p | semmle.label | p | | test.cpp:278:14:278:14 | p | semmle.label | p | +| test.cpp:282:19:282:25 | definition of buffer1 | semmle.label | definition of buffer1 | | test.cpp:283:19:283:25 | buffer1 | semmle.label | buffer1 | | test.cpp:283:19:283:25 | buffer1 | semmle.label | buffer1 | +| test.cpp:285:19:285:25 | definition of buffer2 | semmle.label | definition of buffer2 | | test.cpp:286:19:286:25 | buffer2 | semmle.label | buffer2 | | test.cpp:286:19:286:25 | buffer2 | semmle.label | buffer2 | +| test.cpp:288:19:288:25 | definition of buffer3 | semmle.label | definition of buffer3 | | test.cpp:289:19:289:25 | buffer3 | semmle.label | buffer3 | | test.cpp:289:19:289:25 | buffer3 | semmle.label | buffer3 | | test.cpp:292:25:292:27 | arr | semmle.label | arr | | test.cpp:299:16:299:21 | access to array | semmle.label | access to array | +| test.cpp:305:9:305:12 | definition of arr1 | semmle.label | definition of arr1 | | test.cpp:306:20:306:23 | arr1 | semmle.label | arr1 | | test.cpp:306:20:306:23 | arr1 | semmle.label | arr1 | +| test.cpp:308:9:308:12 | definition of arr2 | semmle.label | definition of arr2 | | test.cpp:309:20:309:23 | arr2 | semmle.label | arr2 | | test.cpp:309:20:309:23 | arr2 | semmle.label | arr2 | +| test.cpp:314:10:314:13 | definition of temp | semmle.label | definition of temp | | test.cpp:319:13:319:27 | ... = ... | semmle.label | ... = ... | | test.cpp:319:19:319:22 | temp | semmle.label | temp | | test.cpp:319:19:319:27 | ... + ... | semmle.label | ... + ... | @@ -187,13 +219,23 @@ subpaths | test.cpp:72:5:72:15 | PointerAdd: access to array | test.cpp:79:32:79:34 | buf | test.cpp:72:5:72:15 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:72:5:72:19 | Store: ... = ... | write | | test.cpp:77:27:77:44 | PointerAdd: access to array | test.cpp:77:32:77:34 | buf | test.cpp:66:32:66:32 | p | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:67:5:67:10 | Store: ... = ... | write | | test.cpp:88:5:88:27 | PointerAdd: access to array | test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:88:5:88:31 | Store: ... = ... | write | +| test.cpp:128:9:128:14 | PointerAdd: access to array | test.cpp:125:11:125:13 | definition of arr | test.cpp:128:9:128:14 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:125:11:125:13 | arr | arr | test.cpp:128:9:128:18 | Store: ... = ... | write | | test.cpp:128:9:128:14 | PointerAdd: access to array | test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:125:11:125:13 | arr | arr | test.cpp:128:9:128:18 | Store: ... = ... | write | +| test.cpp:136:9:136:16 | PointerAdd: ... += ... | test.cpp:142:10:142:13 | definition of asdf | test.cpp:138:13:138:15 | arr | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:142:10:142:13 | asdf | asdf | test.cpp:138:12:138:15 | Load: * ... | read | | test.cpp:136:9:136:16 | PointerAdd: ... += ... | test.cpp:143:18:143:21 | asdf | test.cpp:138:13:138:15 | arr | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:142:10:142:13 | asdf | asdf | test.cpp:138:12:138:15 | Load: * ... | read | +| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:154:7:154:9 | definition of buf | test.cpp:147:4:147:9 | -- ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:147:3:147:13 | Store: ... = ... | write | | test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:156:12:156:14 | buf | test.cpp:147:4:147:9 | -- ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:147:3:147:13 | Store: ... = ... | write | +| test.cpp:221:5:221:11 | PointerAdd: access to array | test.cpp:217:19:217:24 | definition of buffer | test.cpp:221:5:221:11 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:217:19:217:24 | buffer | buffer | test.cpp:221:5:221:15 | Store: ... = ... | write | | test.cpp:221:5:221:11 | PointerAdd: access to array | test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:217:19:217:24 | buffer | buffer | test.cpp:221:5:221:15 | Store: ... = ... | write | +| test.cpp:232:5:232:10 | PointerAdd: access to array | test.cpp:228:10:228:14 | definition of array | test.cpp:232:5:232:10 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:228:10:228:14 | array | array | test.cpp:232:5:232:19 | Store: ... = ... | write | | test.cpp:232:5:232:10 | PointerAdd: access to array | test.cpp:229:25:229:29 | array | test.cpp:232:5:232:10 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:228:10:228:14 | array | array | test.cpp:232:5:232:19 | Store: ... = ... | write | +| test.cpp:261:27:261:30 | PointerAdd: access to array | test.cpp:285:19:285:25 | definition of buffer2 | test.cpp:261:27:261:30 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:285:19:285:25 | buffer2 | buffer2 | test.cpp:261:27:261:30 | Load: access to array | read | | test.cpp:261:27:261:30 | PointerAdd: access to array | test.cpp:286:19:286:25 | buffer2 | test.cpp:261:27:261:30 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:285:19:285:25 | buffer2 | buffer2 | test.cpp:261:27:261:30 | Load: access to array | read | +| test.cpp:299:16:299:21 | PointerAdd: access to array | test.cpp:308:9:308:12 | definition of arr2 | test.cpp:299:16:299:21 | access to array | This pointer arithmetic may have an off-by-1014 error allowing it to overrun $@ at this $@. | test.cpp:308:9:308:12 | arr2 | arr2 | test.cpp:299:16:299:21 | Load: access to array | read | | test.cpp:299:16:299:21 | PointerAdd: access to array | test.cpp:309:20:309:23 | arr2 | test.cpp:299:16:299:21 | access to array | This pointer arithmetic may have an off-by-1014 error allowing it to overrun $@ at this $@. | test.cpp:308:9:308:12 | arr2 | arr2 | test.cpp:299:16:299:21 | Load: access to array | read | +| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:314:10:314:13 | definition of temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:330:13:330:24 | Store: ... = ... | write | +| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:314:10:314:13 | definition of temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:331:13:331:24 | Store: ... = ... | write | +| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:314:10:314:13 | definition of temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:333:13:333:24 | Store: ... = ... | write | | test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:330:13:330:24 | Store: ... = ... | write | | test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:331:13:331:24 | Store: ... = ... | write | | test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:333:13:333:24 | Store: ... = ... | write | From 8647073433cb518fc450ee0ecc504d7b9154a21b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 5 Nov 2024 17:06:53 +0000 Subject: [PATCH 166/213] Copy template injection to standard pack + add jinja sinks --- python/ql/lib/semmle/python/Concepts.qll | 26 ++++++++++ .../lib/semmle/python/frameworks/Jinja2.qll | 0 .../TemplateInjectionCustomizations.qll | 50 +++++++++++++++++++ .../dataflow/TemplateInjectionQuery.qll | 22 ++++++++ .../CWE-074/TemplateConstructionConcept.qll | 7 ++- .../TemplateInjectionCustomizations.qll | 4 +- 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 python/ql/lib/semmle/python/frameworks/Jinja2.qll create mode 100644 python/ql/lib/semmle/python/security/dataflow/TemplateInjectionCustomizations.qll create mode 100644 python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index cc0712d181b7..cf6f0214496f 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -861,6 +861,32 @@ class LdapFilterEscaping extends Escaping { LdapFilterEscaping() { super.getKind() = Escaping::getLdapFilterKind() } } +/** + * A data-flow node that constructs a template in a templating engine. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `TemplateConstruction::Range` instead. + */ +class TemplateConstruction extends DataFlow::Node instanceof TemplateConstruction::Range { + /** Gets the argument that specifies the template source. */ + DataFlow::Node getSourceArg() { result = super.getSourceArg() } +} + +/** Provides classes for modelling template construction APIs. */ +module TemplateConstruction { + /** + * A data-flow node that constructs a template in a templating engine. + * + * Extend this class to model new APIs. If you want to refine existing API models, + * extend `TemplateConstruction` instead. + */ + abstract class Range extends DataFlow::Node { + /** Gets the argument that specifies the template source. */ + abstract DataFlow::Node getSourceArg(); + } +} + + /** Provides classes for modeling HTTP-related APIs. */ module Http { /** Gets an HTTP verb, in upper case */ diff --git a/python/ql/lib/semmle/python/frameworks/Jinja2.qll b/python/ql/lib/semmle/python/frameworks/Jinja2.qll new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionCustomizations.qll new file mode 100644 index 000000000000..e61d55253090 --- /dev/null +++ b/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionCustomizations.qll @@ -0,0 +1,50 @@ +/** + * Provides default sources, sinks and sanitizers for detecting + * "template injection" + * vulnerabilities, as well as extension points for adding your own. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.Concepts +private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.dataflow.new.BarrierGuards + +/** + * Provides default sources, sinks and sanitizers for detecting + * "template injection" + * vulnerabilities, as well as extension points for adding your own. + */ +module TemplateInjection { + /** + * A data flow source for "template injection" vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for "template injection" vulnerabilities. + */ + abstract class Sink extends DataFlow::Node { } + + /** + * A sanitizer for "template injection" vulnerabilities. + */ + abstract class Sanitizer extends DataFlow::Node { } + + /** + * An active threat-model source, considered as a flow source. + */ + private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { } + + /** + * A SQL statement of a SQL construction, considered as a flow sink. + */ + class TemplateConstructionAsSink extends Sink { + TemplateConstructionAsSink() { this = any(TemplateConstruction c).getSourceArg() } + } + + /** + * A comparison with a constant, considered as a sanitizer-guard. + */ + class ConstCompareAsSanitizerGuard extends Sanitizer, ConstCompareBarrier { } +} diff --git a/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll new file mode 100644 index 000000000000..e5ad529fb37a --- /dev/null +++ b/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll @@ -0,0 +1,22 @@ +/** + * Provides a taint-tracking configuration for detecting "template injection" vulnerabilities. + * + * Note, for performance reasons: only import this file if + * `TemplateInjectionFlow` is needed, otherwise + * `TemplateInjectionCustomizations` should be imported instead. + */ + +private import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import TemplateInjectionCustomizations::TemplateInjection + +module TemplateInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof Source } + + predicate isSink(DataFlow::Node node) { node instanceof Sink } + + predicate isBarrierIn(DataFlow::Node node) { node instanceof Sanitizer } +} + +module TemplateInjectionFlow = TaintTracking::Global; diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll b/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll index a20babf15eb6..b4f5cae44491 100644 --- a/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll +++ b/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll @@ -134,7 +134,12 @@ class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallN /** A call to `jinja2.from_string`. */ class Jinja2FromStringConstruction extends TemplateConstruction::Range, API::CallNode { Jinja2FromStringConstruction() { - this = API::moduleImport("jinja2").getMember("from_string").getACall() + this = + API::moduleImport("jinja2") + .getMember("Environment") + .getReturn() + .getMember("from_string") + .getACall() } override DataFlow::Node getSourceArg() { result = this.getArg(0) } diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll b/python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll index 593ca9fee4cf..13c70fc7d04d 100644 --- a/python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll +++ b/python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll @@ -6,7 +6,7 @@ private import python private import semmle.python.dataflow.new.DataFlow -private import semmle.python.Concepts +private import semmle.python.Concepts as C private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.dataflow.new.BarrierGuards private import TemplateConstructionConcept @@ -40,7 +40,7 @@ module TemplateInjection { /** * An active threat-model source, considered as a flow source. */ - private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { } + private class ActiveThreatModelSourceAsSource extends Source, C::ActiveThreatModelSource { } /** * A SQL statement of a SQL construction, considered as a flow sink. From 60d8a85a9ccbd5c8099dd925dad7e98057c66c5b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 6 Nov 2024 09:09:42 +0000 Subject: [PATCH 167/213] Promote jinja sinks --- .../lib/semmle/python/frameworks/Jinja2.qll | 49 +++++++++++++++++++ .../CWE-074/TemplateConstructionConcept.qll | 1 + 2 files changed, 50 insertions(+) diff --git a/python/ql/lib/semmle/python/frameworks/Jinja2.qll b/python/ql/lib/semmle/python/frameworks/Jinja2.qll index e69de29bb2d1..0b681820f13c 100644 --- a/python/ql/lib/semmle/python/frameworks/Jinja2.qll +++ b/python/ql/lib/semmle/python/frameworks/Jinja2.qll @@ -0,0 +1,49 @@ +/** + * Provides classes modeling security-relevant aspects of the `jinja2` PyPI package. + * See https://jinja.palletsprojects.com. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.ApiGraphs +private import semmle.python.Concepts +private import semmle.python.frameworks.data.ModelsAsData + +module Jinja2 { + /** A call to `jinja2.Template`. */ + class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode { + Jinja2TemplateConstruction() { + this = API::moduleImport("jinja2").getMember("Template").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } + + module EnvironmentClass { + /** Gets a reference to the `jinja2.Environment` class. */ + API::Node classRef() { + result = API::moduleImport("jinja2").getMember("Environment") + or + result = ModelOutput::getATypeNode("jinja.Environment~Subclass").getASubclass*() + } + + /** Gets a reference to an instance of `jinja2.Environment`. */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result = EnvironmentClass::classRef().getACall() + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of `jinja2.Environment`. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** A call to `jinja2.Environment.from_string`. */ + class Jinja2FromStringConstruction extends TemplateConstruction::Range, DataFlow::MethodCallNode + { + Jinja2FromStringConstruction() { this.calls(EnvironmentClass::instance(), "from_string") } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } + } +} diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll b/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll index b4f5cae44491..5144e2ff97b1 100644 --- a/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll +++ b/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll @@ -122,6 +122,7 @@ class GenshiMarkupTemplateConstruction extends TemplateConstruction::Range, API: override DataFlow::Node getSourceArg() { result = this.getArg(0) } } +// /** A call to `jinja2.Template`. */ class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode { Jinja2TemplateConstruction() { From b2c13fe351894553b1e367c497a57ee10b5f3dc2 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 6 Nov 2024 16:13:36 +0000 Subject: [PATCH 168/213] Promote template injection sinks for each framework covered `Cheetah` was excluded as it was last updated 15 years ago and its documentation links are dead. --- python/ql/lib/semmle/python/Frameworks.qll | 8 ++++ .../lib/semmle/python/frameworks/Airspeed.qll | 26 +++++++++++ .../lib/semmle/python/frameworks/Bottle.qll | 14 +++++- .../semmle/python/frameworks/Chameleon.qll | 26 +++++++++++ .../lib/semmle/python/frameworks/Chevron.qll | 26 +++++++++++ .../lib/semmle/python/frameworks/Django.qll | 15 +++++++ .../ql/lib/semmle/python/frameworks/Flask.qll | 9 ++++ .../lib/semmle/python/frameworks/Genshi.qll | 45 +++++++++++++++++++ .../lib/semmle/python/frameworks/Jinja2.qll | 11 ++++- .../ql/lib/semmle/python/frameworks/Mako.qll | 26 +++++++++++ .../lib/semmle/python/frameworks/TRender.qll | 26 +++++++++++ 11 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 python/ql/lib/semmle/python/frameworks/Airspeed.qll create mode 100644 python/ql/lib/semmle/python/frameworks/Chameleon.qll create mode 100644 python/ql/lib/semmle/python/frameworks/Chevron.qll create mode 100644 python/ql/lib/semmle/python/frameworks/Genshi.qll create mode 100644 python/ql/lib/semmle/python/frameworks/Mako.qll create mode 100644 python/ql/lib/semmle/python/frameworks/TRender.qll diff --git a/python/ql/lib/semmle/python/Frameworks.qll b/python/ql/lib/semmle/python/Frameworks.qll index da35994b955d..af9417308ab3 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -11,13 +11,17 @@ private import semmle.python.frameworks.Aiohttp private import semmle.python.frameworks.Aiomysql private import semmle.python.frameworks.Aiopg private import semmle.python.frameworks.Aiosqlite +private import semmle.python.frameworks.Airspeed private import semmle.python.frameworks.Anyio private import semmle.python.frameworks.Asyncpg private import semmle.python.frameworks.Baize +private import semmle.python.frameworks.Bottle private import semmle.python.frameworks.BSon private import semmle.python.frameworks.Bottle private import semmle.python.frameworks.CassandraDriver +private import semmle.python.frameworks.Chameleon private import semmle.python.frameworks.Cherrypy +private import semmle.python.frameworks.Chevron private import semmle.python.frameworks.ClickhouseDriver private import semmle.python.frameworks.Cryptodome private import semmle.python.frameworks.Cryptography @@ -30,10 +34,12 @@ private import semmle.python.frameworks.FastApi private import semmle.python.frameworks.Flask private import semmle.python.frameworks.FlaskAdmin private import semmle.python.frameworks.FlaskSqlAlchemy +private import semmle.python.frameworks.Genshi private import semmle.python.frameworks.Gradio private import semmle.python.frameworks.Httpx private import semmle.python.frameworks.Idna private import semmle.python.frameworks.Invoke +private import semmle.python.frameworks.Jinja2 private import semmle.python.frameworks.Jmespath private import semmle.python.frameworks.Joblib private import semmle.python.frameworks.JsonPickle @@ -42,6 +48,7 @@ private import semmle.python.frameworks.Ldap3 private import semmle.python.frameworks.Libtaxii private import semmle.python.frameworks.Libxml2 private import semmle.python.frameworks.Lxml +private import semmle.python.frameworks.Mako private import semmle.python.frameworks.MarkupSafe private import semmle.python.frameworks.Multidict private import semmle.python.frameworks.Mysql @@ -78,6 +85,7 @@ private import semmle.python.frameworks.Streamlit private import semmle.python.frameworks.Toml private import semmle.python.frameworks.Torch private import semmle.python.frameworks.Tornado +private import semmle.python.frameworks.TRender private import semmle.python.frameworks.Twisted private import semmle.python.frameworks.Ujson private import semmle.python.frameworks.Urllib3 diff --git a/python/ql/lib/semmle/python/frameworks/Airspeed.qll b/python/ql/lib/semmle/python/frameworks/Airspeed.qll new file mode 100644 index 000000000000..bdfc2ae357db --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Airspeed.qll @@ -0,0 +1,26 @@ +/** + * Provides classes modeling security-relevant aspects of the `airspeed` library. + * See https://github.com/purcell/airspeed. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.ApiGraphs +private import semmle.python.Concepts + +/** + * INTERNAL: Do not use. + * + * Provides classes modeling security-relevant aspects of the `airspeed` library. + * See https://github.com/purcell/airspeed. + */ +module Airspeed { + /** A call to `airspeed.Template`. */ + private class AirspeedTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + AirspeedTemplateConstruction() { + this = API::moduleImport("airspeed").getMember("Template").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/Bottle.qll b/python/ql/lib/semmle/python/frameworks/Bottle.qll index ce2a41dbaf4e..c03ea3df184e 100644 --- a/python/ql/lib/semmle/python/frameworks/Bottle.qll +++ b/python/ql/lib/semmle/python/frameworks/Bottle.qll @@ -39,7 +39,7 @@ module Bottle { ViewCallable() { this = any(BottleRouteSetup rs).getARequestHandler() } } - /** Get methods that reprsent a route in Bottle */ + /** Get methods that represent a route in Bottle */ string routeMethods() { result = ["route", "get", "post", "put", "delete", "patch"] } private class BottleRouteSetup extends Http::Server::RouteSetup::Range, DataFlow::CallCfgNode { @@ -171,5 +171,17 @@ module Bottle { override predicate valueAllowsNewline() { none() } } } + + /** Provides models for functions that construct templates. */ + module Templates { + /** A call to `bottle.template`or `bottle.SimpleTemplate`. */ + private class BottleTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + BottleTemplateConstruction() { + this = API::moduleImport("bottle").getMember(["template", "SimpleTemplate"]).getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } + } } } diff --git a/python/ql/lib/semmle/python/frameworks/Chameleon.qll b/python/ql/lib/semmle/python/frameworks/Chameleon.qll new file mode 100644 index 000000000000..2f86d784b962 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Chameleon.qll @@ -0,0 +1,26 @@ +/** + * Provides classes modeling security-relevant aspects of the `chameleon` PyPI package. + * See https://chameleon.readthedocs.io/en/latest/. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.ApiGraphs +private import semmle.python.Concepts + +/** + * INTERNAL: Do not use. + * + * Provides classes modeling security-relevant aspects of the `chameleon` PyPI package. + * See https://chameleon.readthedocs.io/en/latest/. + */ +module Chameleon { + /** A call to `chameleon.PageTemplate`. */ + private class ChameleonTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + ChameleonTemplateConstruction() { + this = API::moduleImport("chameleon").getMember("PageTemplate").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/Chevron.qll b/python/ql/lib/semmle/python/frameworks/Chevron.qll new file mode 100644 index 000000000000..5d938fef2086 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Chevron.qll @@ -0,0 +1,26 @@ +/** + * Provides classes modeling security-relevant aspects of the `chevron` PyPI package. + * See https://pypi.org/project/chevron. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.ApiGraphs +private import semmle.python.Concepts + +/** + * INTERNAL: Do not use. + * + * Provides classes modeling security-relevant aspects of the `chevron` PyPI package. + * See https://pypi.org/project/chevron. + */ +module Chevron { + /** A call to `chevron.render`. */ + private class ChevronRenderConstruction extends TemplateConstruction::Range, API::CallNode { + ChevronRenderConstruction() { + this = API::moduleImport("chevron").getMember("render").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index 351420818c38..80ef4aef435d 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -2996,4 +2996,19 @@ module PrivateDjango { any() } } + + // --------------------------------------------------------------------------- + // Templates + // --------------------------------------------------------------------------- + + /** A call to `django.template.Template` */ + private class DjangoTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + DjangoTemplateConstruction() { + this = API::moduleImport("django").getMember("template").getMember("Template").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } + + // TODO: Support `from_string` on instances of `django.template.Engine`. } diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 62722a1958ac..cfb8048c6a13 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -721,4 +721,13 @@ module Flask { preservesValue = false } } + + /** A call to `flask.render_template_string` as a template construction sink. */ + private class FlaskTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + FlaskTemplateConstruction() { + this = API::moduleImport("flask").getMember("render_template_string").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } } diff --git a/python/ql/lib/semmle/python/frameworks/Genshi.qll b/python/ql/lib/semmle/python/frameworks/Genshi.qll new file mode 100644 index 000000000000..f01b5137aac3 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Genshi.qll @@ -0,0 +1,45 @@ +/** + * Provides classes modeling security-relevant aspects of the `Genshi` PyPI package. + * See https://genshi.edgewall.org/. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.ApiGraphs +private import semmle.python.Concepts + +/** + * INTERNAL: Do not use. + * + * Provides classes modeling security-relevant aspects of the `Genshi` PyPI package. + * See https://genshi.edgewall.org/. + */ +module Genshi { + /** A call to `genshi.template.text.NewTextTemplate` or `genshi.template.text.OldTextTemplate`. */ + private class GenshiTextTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + GenshiTextTemplateConstruction() { + this = + API::moduleImport("genshi") + .getMember("template") + .getMember("text") + .getMember(["NewTextTemplate", "OldTextTemplate"]) + .getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } + + /** A call to `genshi.template.MarkupTemplate` */ + private class GenshiMarkupTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + GenshiMarkupTemplateConstruction() { + this = + API::moduleImport("genshi") + .getMember("template") + .getMember("markup") + .getMember("MarkupTemplate") + .getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/Jinja2.qll b/python/ql/lib/semmle/python/frameworks/Jinja2.qll index 0b681820f13c..c89ffbe3cc97 100644 --- a/python/ql/lib/semmle/python/frameworks/Jinja2.qll +++ b/python/ql/lib/semmle/python/frameworks/Jinja2.qll @@ -9,9 +9,15 @@ private import semmle.python.ApiGraphs private import semmle.python.Concepts private import semmle.python.frameworks.data.ModelsAsData +/** + * INTERNAL: Do not use + * + * Provides classes modeling security-relevant aspects of the `jinja2` PyPI package. + * See https://jinja.palletsprojects.com. + */ module Jinja2 { /** A call to `jinja2.Template`. */ - class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode { + private class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode { Jinja2TemplateConstruction() { this = API::moduleImport("jinja2").getMember("Template").getACall() } @@ -39,7 +45,8 @@ module Jinja2 { DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } /** A call to `jinja2.Environment.from_string`. */ - class Jinja2FromStringConstruction extends TemplateConstruction::Range, DataFlow::MethodCallNode + private class Jinja2FromStringConstruction extends TemplateConstruction::Range, + DataFlow::MethodCallNode { Jinja2FromStringConstruction() { this.calls(EnvironmentClass::instance(), "from_string") } diff --git a/python/ql/lib/semmle/python/frameworks/Mako.qll b/python/ql/lib/semmle/python/frameworks/Mako.qll new file mode 100644 index 000000000000..5dd518a8afe0 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Mako.qll @@ -0,0 +1,26 @@ +/** + * Provides classes modeling security-relevant aspects of the `Mako` PyPI package. + * See https://www.makotemplates.org/. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.ApiGraphs +private import semmle.python.Concepts + +/** + * INTERNAL: Do not use. + * + * Provides classes modeling security-relevant aspects of the `Mako` PyPI package. + * See https://www.makotemplates.org/. + */ +module Mako { + /** A call to `mako.template.Template`. */ + private class MakoTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + MakoTemplateConstruction() { + this = API::moduleImport("mako").getMember("template").getMember("Template").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/TRender.qll b/python/ql/lib/semmle/python/frameworks/TRender.qll new file mode 100644 index 000000000000..08749676a06c --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/TRender.qll @@ -0,0 +1,26 @@ +/** + * Provides classes modeling security-relevant aspects of the `trender` PyPI package. + * See https://github.com/cesbit/trender. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.ApiGraphs +private import semmle.python.Concepts + +/** + * INTERNAL: Do not use. + * + * Provides classes modeling security-relevant aspects of the `trender` PyPI package. + * See https://github.com/cesbit/trender. + */ +module TRender { + /** A call to `trender.TRender`. */ + private class TRenderTemplateConstruction extends TemplateConstruction::Range, API::CallNode { + TRenderTemplateConstruction() { + this = API::moduleImport("trender").getMember("TRender").getACall() + } + + override DataFlow::Node getSourceArg() { result = this.getArg(0) } + } +} From 71ab82dee06a4252c64e650c76773133cfc8d9e1 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 7 Nov 2024 14:40:51 +0000 Subject: [PATCH 169/213] Fix qldoc, formatting, and redundant import warnings --- python/ql/lib/semmle/python/Concepts.qll | 3 +-- python/ql/lib/semmle/python/frameworks/Airspeed.qll | 1 - python/ql/lib/semmle/python/frameworks/Chameleon.qll | 1 - python/ql/lib/semmle/python/frameworks/Chevron.qll | 1 - python/ql/lib/semmle/python/frameworks/Django.qll | 2 -- python/ql/lib/semmle/python/frameworks/Genshi.qll | 1 - python/ql/lib/semmle/python/frameworks/Jinja2.qll | 1 - python/ql/lib/semmle/python/frameworks/Mako.qll | 1 - python/ql/lib/semmle/python/frameworks/TRender.qll | 1 - .../semmle/python/security/dataflow/TemplateInjectionQuery.qll | 3 ++- 10 files changed, 3 insertions(+), 12 deletions(-) diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index cf6f0214496f..94d660d75108 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -872,7 +872,7 @@ class TemplateConstruction extends DataFlow::Node instanceof TemplateConstructio DataFlow::Node getSourceArg() { result = super.getSourceArg() } } -/** Provides classes for modelling template construction APIs. */ +/** Provides classes for modeling template construction APIs. */ module TemplateConstruction { /** * A data-flow node that constructs a template in a templating engine. @@ -886,7 +886,6 @@ module TemplateConstruction { } } - /** Provides classes for modeling HTTP-related APIs. */ module Http { /** Gets an HTTP verb, in upper case */ diff --git a/python/ql/lib/semmle/python/frameworks/Airspeed.qll b/python/ql/lib/semmle/python/frameworks/Airspeed.qll index bdfc2ae357db..a08a1b4a46be 100644 --- a/python/ql/lib/semmle/python/frameworks/Airspeed.qll +++ b/python/ql/lib/semmle/python/frameworks/Airspeed.qll @@ -4,7 +4,6 @@ */ private import python -private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.Concepts diff --git a/python/ql/lib/semmle/python/frameworks/Chameleon.qll b/python/ql/lib/semmle/python/frameworks/Chameleon.qll index 2f86d784b962..cf5444c40ce2 100644 --- a/python/ql/lib/semmle/python/frameworks/Chameleon.qll +++ b/python/ql/lib/semmle/python/frameworks/Chameleon.qll @@ -4,7 +4,6 @@ */ private import python -private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.Concepts diff --git a/python/ql/lib/semmle/python/frameworks/Chevron.qll b/python/ql/lib/semmle/python/frameworks/Chevron.qll index 5d938fef2086..ec5676a2f04a 100644 --- a/python/ql/lib/semmle/python/frameworks/Chevron.qll +++ b/python/ql/lib/semmle/python/frameworks/Chevron.qll @@ -4,7 +4,6 @@ */ private import python -private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.Concepts diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index 80ef4aef435d..4aa5776ad54b 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -3000,7 +3000,6 @@ module PrivateDjango { // --------------------------------------------------------------------------- // Templates // --------------------------------------------------------------------------- - /** A call to `django.template.Template` */ private class DjangoTemplateConstruction extends TemplateConstruction::Range, API::CallNode { DjangoTemplateConstruction() { @@ -3009,6 +3008,5 @@ module PrivateDjango { override DataFlow::Node getSourceArg() { result = this.getArg(0) } } - // TODO: Support `from_string` on instances of `django.template.Engine`. } diff --git a/python/ql/lib/semmle/python/frameworks/Genshi.qll b/python/ql/lib/semmle/python/frameworks/Genshi.qll index f01b5137aac3..1e29295b4288 100644 --- a/python/ql/lib/semmle/python/frameworks/Genshi.qll +++ b/python/ql/lib/semmle/python/frameworks/Genshi.qll @@ -4,7 +4,6 @@ */ private import python -private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.Concepts diff --git a/python/ql/lib/semmle/python/frameworks/Jinja2.qll b/python/ql/lib/semmle/python/frameworks/Jinja2.qll index c89ffbe3cc97..9f267915e5c1 100644 --- a/python/ql/lib/semmle/python/frameworks/Jinja2.qll +++ b/python/ql/lib/semmle/python/frameworks/Jinja2.qll @@ -4,7 +4,6 @@ */ private import python -private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.Concepts private import semmle.python.frameworks.data.ModelsAsData diff --git a/python/ql/lib/semmle/python/frameworks/Mako.qll b/python/ql/lib/semmle/python/frameworks/Mako.qll index 5dd518a8afe0..2209c0f89d2f 100644 --- a/python/ql/lib/semmle/python/frameworks/Mako.qll +++ b/python/ql/lib/semmle/python/frameworks/Mako.qll @@ -4,7 +4,6 @@ */ private import python -private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.Concepts diff --git a/python/ql/lib/semmle/python/frameworks/TRender.qll b/python/ql/lib/semmle/python/frameworks/TRender.qll index 08749676a06c..fae27f418c34 100644 --- a/python/ql/lib/semmle/python/frameworks/TRender.qll +++ b/python/ql/lib/semmle/python/frameworks/TRender.qll @@ -4,7 +4,6 @@ */ private import python -private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.Concepts diff --git a/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll index e5ad529fb37a..22c228f48d59 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TemplateInjectionQuery.qll @@ -11,7 +11,7 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import TemplateInjectionCustomizations::TemplateInjection -module TemplateInjectionConfig implements DataFlow::ConfigSig { +private module TemplateInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node instanceof Source } predicate isSink(DataFlow::Node node) { node instanceof Sink } @@ -19,4 +19,5 @@ module TemplateInjectionConfig implements DataFlow::ConfigSig { predicate isBarrierIn(DataFlow::Node node) { node instanceof Sanitizer } } +/** Global taint-tracking for detecting "template injection" vulnerabilities. */ module TemplateInjectionFlow = TaintTracking::Global; From 1cb01a286d622d30a95077567fa42f02cd125669 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 20 Nov 2024 14:50:35 +0000 Subject: [PATCH 170/213] Add tests for jinja --- .../src/Security/CWE-074/TemplateInjection.ql | 19 ++++++++++++ .../CWE-074-TemplateInjection/JinjaSsti.py | 31 +++++++++++++++++++ .../TemplateInjection.expected | 16 ++++++++++ .../TemplateInjection.qlref | 1 + 4 files changed, 67 insertions(+) create mode 100644 python/ql/src/Security/CWE-074/TemplateInjection.ql create mode 100644 python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py create mode 100644 python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected create mode 100644 python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.ql b/python/ql/src/Security/CWE-074/TemplateInjection.ql new file mode 100644 index 000000000000..125478c801c8 --- /dev/null +++ b/python/ql/src/Security/CWE-074/TemplateInjection.ql @@ -0,0 +1,19 @@ +/** + * @name Server Side Template Injection + * @description Using user-controlled data to create a template can lead to remote code execution or cross site scripting. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/template-injection + * @tags security + * external/cwe/cwe-074 + */ + +import python +import semmle.python.security.dataflow.TemplateInjectionQuery +import TemplateInjectionFlow::PathGraph + +from TemplateInjectionFlow::PathNode source, TemplateInjectionFlow::PathNode sink +where TemplateInjectionFlow::flowPath(source, sink) +select sink.getNode(), source, sink, "This Template construction depends on $@.", source.getNode(), + "user-provided value" diff --git a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py new file mode 100644 index 000000000000..f1fe834e4936 --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py @@ -0,0 +1,31 @@ +from django.urls import path +from django.http import HttpResponse +from jinja2 import Template +from jinja2 import Environment, DictLoader, escape + + +def a(request): + # Load the template + template = request.GET['template'] + t = Template(template) # BAD: Template constructed from user input + name = request.GET['name'] + # Render the template with the context data + html = t.render(name=escape(name)) + return HttpResponse(html) + +def b(request): + import jinja2 + # Load the template + template = request.GET['template'] + env = Environment() + t = env.from_string(template) # BAD: Template constructed from user input + name = request.GET['name'] + # Render the template with the context data + html = t.render(name=escape(name)) + return HttpResponse(html) + + +urlpatterns = [ + path('a', a), + path('b', b) +] diff --git a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected new file mode 100644 index 000000000000..3a833787a982 --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected @@ -0,0 +1,16 @@ +edges +| JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | +| JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | provenance | | +| JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:19:5:19:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | +| JinjaSsti.py:19:5:19:12 | ControlFlowNode for template | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | provenance | | +nodes +| JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | +| JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | +| JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| JinjaSsti.py:19:5:19:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | +| JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | +subpaths +#select +| JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | This Template construction depends on $@. | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | user-provided value | +| JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | This Template construction depends on $@. | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref new file mode 100644 index 000000000000..ead6bb469c6a --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref @@ -0,0 +1 @@ +Security/CWE-074/TemplateInjection.ql \ No newline at end of file From cea196ec61cec37fc47f526a88b4775a5a629d65 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Nov 2024 14:56:44 +0000 Subject: [PATCH 171/213] Add concepts tests + some fixes --- .../ql/lib/semmle/python/frameworks/Flask.qll | 7 +++++-- .../ql/lib/semmle/python/frameworks/Genshi.qll | 2 +- .../ql/lib/semmle/python/frameworks/Jinja2.qll | 1 + .../ql/test/experimental/meta/ConceptsTest.qll | 17 ++++++++++++++++- .../frameworks/Genshi/ConceptsTest.expected | 2 ++ .../frameworks/Genshi/ConceptsTest.ql | 2 ++ .../frameworks/Genshi/template_test.py | 9 +++++++++ .../frameworks/Mako/ConceptsTest.expected | 2 ++ .../frameworks/Mako/ConceptsTest.ql | 2 ++ .../frameworks/Mako/template_test.py | 4 ++++ .../frameworks/TRender/ConceptsTest.expected | 2 ++ .../frameworks/TRender/ConceptsTest.ql | 2 ++ .../frameworks/TRender/template_test.py | 4 ++++ .../frameworks/airspeed/ConceptsTest.expected | 2 ++ .../frameworks/airspeed/ConceptsTest.ql | 2 ++ .../frameworks/airspeed/template_test.py | 4 ++++ .../frameworks/bottle/template_test.py | 9 +++++++++ .../frameworks/chameleon/ConceptsTest.expected | 2 ++ .../frameworks/chameleon/ConceptsTest.ql | 2 ++ .../frameworks/chameleon/template_test.py | 4 ++++ .../frameworks/chevron/ConceptsTest.expected | 2 ++ .../frameworks/chevron/ConceptsTest.ql | 2 ++ .../frameworks/chevron/template_test.py | 4 ++++ .../frameworks/django-v2-v3/template_test.py | 17 +++++++++++++++++ .../frameworks/flask/taint_test.py | 8 ++++---- .../frameworks/flask/template_test.py | 16 ++++++++++++++++ .../frameworks/jinja2/ConceptsTest.expected | 2 ++ .../frameworks/jinja2/ConceptsTest.ql | 2 ++ .../frameworks/jinja2/template_test.py | 7 +++++++ 29 files changed, 133 insertions(+), 8 deletions(-) create mode 100644 python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/Genshi/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/Mako/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/Mako/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/TRender/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/TRender/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/airspeed/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/bottle/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/chameleon/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/chevron/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/chevron/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/flask/template_test.py create mode 100644 python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/jinja2/template_test.py diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index cfb8048c6a13..0e5d6065c474 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -722,10 +722,13 @@ module Flask { } } - /** A call to `flask.render_template_string` as a template construction sink. */ + /** A call to `flask.render_template_string` or `flask.stream_template_string` as a template construction sink. */ private class FlaskTemplateConstruction extends TemplateConstruction::Range, API::CallNode { FlaskTemplateConstruction() { - this = API::moduleImport("flask").getMember("render_template_string").getACall() + this = + API::moduleImport("flask") + .getMember(["render_template_string", "stream_template_string"]) + .getACall() } override DataFlow::Node getSourceArg() { result = this.getArg(0) } diff --git a/python/ql/lib/semmle/python/frameworks/Genshi.qll b/python/ql/lib/semmle/python/frameworks/Genshi.qll index 1e29295b4288..8e368391cf74 100644 --- a/python/ql/lib/semmle/python/frameworks/Genshi.qll +++ b/python/ql/lib/semmle/python/frameworks/Genshi.qll @@ -21,7 +21,7 @@ module Genshi { API::moduleImport("genshi") .getMember("template") .getMember("text") - .getMember(["NewTextTemplate", "OldTextTemplate"]) + .getMember(["NewTextTemplate", "OldTextTemplate", "TextTemplate"]) .getACall() } diff --git a/python/ql/lib/semmle/python/frameworks/Jinja2.qll b/python/ql/lib/semmle/python/frameworks/Jinja2.qll index 9f267915e5c1..0d0a8d989211 100644 --- a/python/ql/lib/semmle/python/frameworks/Jinja2.qll +++ b/python/ql/lib/semmle/python/frameworks/Jinja2.qll @@ -24,6 +24,7 @@ module Jinja2 { override DataFlow::Node getSourceArg() { result = this.getArg(0) } } + /** Definitions for modeling jinja `Environment`s. */ module EnvironmentClass { /** Gets a reference to the `jinja2.Environment` class. */ API::Node classRef() { diff --git a/python/ql/test/experimental/meta/ConceptsTest.qll b/python/ql/test/experimental/meta/ConceptsTest.qll index 8ab87e56d1c4..40aa9c951b0d 100644 --- a/python/ql/test/experimental/meta/ConceptsTest.qll +++ b/python/ql/test/experimental/meta/ConceptsTest.qll @@ -663,6 +663,20 @@ module CorsMiddlewareTest implements TestSig { } } +module TemplateConstructionTest implements TestSig { + string getARelevantTag() { result = "templateConstruction" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(location.getFile().getRelativePath()) and + exists(TemplateConstruction tc | + location = tc.getLocation() and + element = tc.toString() and + value = prettyNodeForInlineTest(tc.getSourceArg()) and + tag = "templateConstruction" + ) + } +} + import MakeTest, MergeTests5, MergeTests5>>> + CsrfLocalProtectionSettingTest, + MergeTests3>>> diff --git a/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected new file mode 100644 index 000000000000..a74f2c23cda2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected @@ -0,0 +1,2 @@ +testFailures +failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.ql new file mode 100644 index 000000000000..b557a0bccb69 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/Genshi/template_test.py b/python/ql/test/library-tests/frameworks/Genshi/template_test.py new file mode 100644 index 000000000000..d585ee1a81ea --- /dev/null +++ b/python/ql/test/library-tests/frameworks/Genshi/template_test.py @@ -0,0 +1,9 @@ +from genshi.template.text import TextTemplate, NewTextTemplate, OldTextTemplate +from genshi.template.markup import MarkupTemplate + +def test(): + a = TextTemplate("abc") # $ templateConstruction="abc" + a = OldTextTemplate("abc") # $ templateConstruction="abc" + a = NewTextTemplate("abc") # $ templateConstruction="abc" + a = MarkupTemplate("abc") # $ templateConstruction="abc" + return a \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected new file mode 100644 index 000000000000..a74f2c23cda2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected @@ -0,0 +1,2 @@ +testFailures +failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.ql new file mode 100644 index 000000000000..b557a0bccb69 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/Mako/template_test.py b/python/ql/test/library-tests/frameworks/Mako/template_test.py new file mode 100644 index 000000000000..224954cf2633 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/Mako/template_test.py @@ -0,0 +1,4 @@ +from mako.template import Template + +def test(): + return Template("abc") # $ templateConstruction="abc" \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected new file mode 100644 index 000000000000..a74f2c23cda2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected @@ -0,0 +1,2 @@ +testFailures +failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.ql new file mode 100644 index 000000000000..b557a0bccb69 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/TRender/template_test.py b/python/ql/test/library-tests/frameworks/TRender/template_test.py new file mode 100644 index 000000000000..f62d33c26d53 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/TRender/template_test.py @@ -0,0 +1,4 @@ +from trender import TRender + +def test(): + return TRender("abc") # $ templateConstruction="abc" \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected new file mode 100644 index 000000000000..a74f2c23cda2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected @@ -0,0 +1,2 @@ +testFailures +failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.ql new file mode 100644 index 000000000000..b557a0bccb69 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/airspeed/template_test.py b/python/ql/test/library-tests/frameworks/airspeed/template_test.py new file mode 100644 index 000000000000..34d4c29fff6f --- /dev/null +++ b/python/ql/test/library-tests/frameworks/airspeed/template_test.py @@ -0,0 +1,4 @@ +from airspeed import Template + +def test(): + return Template("abc") # $ templateConstruction="abc" diff --git a/python/ql/test/library-tests/frameworks/bottle/template_test.py b/python/ql/test/library-tests/frameworks/bottle/template_test.py new file mode 100644 index 000000000000..db48cfc4fc9f --- /dev/null +++ b/python/ql/test/library-tests/frameworks/bottle/template_test.py @@ -0,0 +1,9 @@ +import bottle +from bottle import response, request, template, SimpleTemplate + +app = bottle.app() +@app.route('/test', method=['OPTIONS', 'GET']) # $ routeSetup="/test" +def test1(): # $ requestHandler + template("abc") # $ templateConstruction="abc" + SimpleTemplate("abc") # $ templateConstruction="abc" + return '[1]' # $ HttpResponse mimetype=text/html responseBody='[1]' \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected new file mode 100644 index 000000000000..a74f2c23cda2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected @@ -0,0 +1,2 @@ +testFailures +failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.ql new file mode 100644 index 000000000000..b557a0bccb69 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/chameleon/template_test.py b/python/ql/test/library-tests/frameworks/chameleon/template_test.py new file mode 100644 index 000000000000..ad6d85036eab --- /dev/null +++ b/python/ql/test/library-tests/frameworks/chameleon/template_test.py @@ -0,0 +1,4 @@ +from chameleon import PageTemplate + +def test(): + return PageTemplate("abc") # $ templateConstruction="abc" \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected new file mode 100644 index 000000000000..a74f2c23cda2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected @@ -0,0 +1,2 @@ +testFailures +failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.ql new file mode 100644 index 000000000000..b557a0bccb69 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/chevron/template_test.py b/python/ql/test/library-tests/frameworks/chevron/template_test.py new file mode 100644 index 000000000000..7aff524166d5 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/chevron/template_test.py @@ -0,0 +1,4 @@ +from chevron import render + +def test(): + return render("abc") # $ templateConstruction="abc" \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py b/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py new file mode 100644 index 000000000000..2d25848fde65 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py @@ -0,0 +1,17 @@ +from django.template import Template, engines +from django.urls import path +from django.http.response import HttpResponse, + +def a(request): # $requestHandler + t = Template("abc").render() # $templateConstruction="abc" + return HttpResponse(t) # $HttpResponse + +def b(request): # $requestHandler + # This case is not yet supported + t = django.template.engines["django"].from_string("abc") # $MISSING:templateConstruction="abc" + return HttpResponse(t) # $HttpResponse + +urlpatterns = [ + path("a", a), # $ routeSetup="a" + path("b", b), # $ routeSetup="b" +] \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/flask/taint_test.py b/python/ql/test/library-tests/frameworks/flask/taint_test.py index 227aecbf7452..ac8a5a82dc28 100644 --- a/python/ql/test/library-tests/frameworks/flask/taint_test.py +++ b/python/ql/test/library-tests/frameworks/flask/taint_test.py @@ -222,25 +222,25 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # render_template_string source = TAINTED_STRING ensure_tainted(source) # $ tainted - res = render_template_string(source) + res = render_template_string(source) # $ templateConstruction=source ensure_tainted(res) # $ tainted # since template variables are auto-escaped, we don't treat result as tainted # see https://flask.palletsprojects.com/en/2.3.x/api/#flask.render_template_string - res = render_template_string("Hello {{ foo }}", foo=TAINTED_STRING) + res = render_template_string("Hello {{ foo }}", foo=TAINTED_STRING) # $ templateConstruction="Hello {{ foo }}" ensure_not_tainted(res) # stream_template_string source = TAINTED_STRING ensure_tainted(source) # $ tainted - res = stream_template_string(source) + res = stream_template_string(source) # $ templateConstruction=source for x in res: ensure_tainted(x) # $ tainted # since template variables are auto-escaped, we don't treat result as tainted # see https://flask.palletsprojects.com/en/2.3.x/api/#flask.stream_template_string - res = stream_template_string("Hello {{ foo }}", foo=TAINTED_STRING) + res = stream_template_string("Hello {{ foo }}", foo=TAINTED_STRING) # $ templateConstruction="Hello {{ foo }}" for x in res: ensure_not_tainted(x) diff --git a/python/ql/test/library-tests/frameworks/flask/template_test.py b/python/ql/test/library-tests/frameworks/flask/template_test.py new file mode 100644 index 000000000000..8d867e148291 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/flask/template_test.py @@ -0,0 +1,16 @@ +from flask import Flask, Response, stream_with_context, render_template_string, stream_template_string +app = Flask(__name__) + +@app.route("/a") # $routeSetup="/a" +def a(): # $requestHandler + r = render_template_string("abc") # $ templateConstruction="abc" + return r # $ HttpResponse + +@app.route("/b") # $routeSetup="/b" +def b(): # $requestHandler + s = stream_template_string("abc") # $ templateConstruction="abc" + r = Response(stream_with_context(s)) # $ HttpResponse + return r # $ HttpResponse + +if __name__ == "__main__": + app.run(debug=True) \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected new file mode 100644 index 000000000000..a74f2c23cda2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected @@ -0,0 +1,2 @@ +testFailures +failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.ql new file mode 100644 index 000000000000..b557a0bccb69 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/jinja2/template_test.py b/python/ql/test/library-tests/frameworks/jinja2/template_test.py new file mode 100644 index 000000000000..587de84f6216 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/jinja2/template_test.py @@ -0,0 +1,7 @@ +from jinja2 import Environment, Template + +def test(): + env = Environment() + t = env.from_string("abc") # $ templateConstruction="abc" + t = Template("abc") # $ templateConstruction="abc" + return t \ No newline at end of file From 02f395f5f845e5c11aed8ff988867bd8e9722060 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Nov 2024 16:51:28 +0000 Subject: [PATCH 172/213] Add qhelp --- .../Security/CWE-074/TemplateInjection.qhelp | 30 +++++++++++++++++++ .../src/Security/CWE-074/examples/JinjaBad.py | 19 ++++++++++++ .../CWE-074/examples/JinjaGoodParam.py | 17 +++++++++++ .../CWE-074/examples/JinjaGoodSandbox.py | 21 +++++++++++++ .../CWE-074/examples/template_exploit.txt | 1 + 5 files changed, 88 insertions(+) create mode 100644 python/ql/src/Security/CWE-074/TemplateInjection.qhelp create mode 100644 python/ql/src/Security/CWE-074/examples/JinjaBad.py create mode 100644 python/ql/src/Security/CWE-074/examples/JinjaGoodParam.py create mode 100644 python/ql/src/Security/CWE-074/examples/JinjaGoodSandbox.py create mode 100644 python/ql/src/Security/CWE-074/examples/template_exploit.txt diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp new file mode 100644 index 000000000000..06990a7237b6 --- /dev/null +++ b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp @@ -0,0 +1,30 @@ + + + +

+ A template from a server templating engine such as Jinja constructed from user input can allow the user to execute arbitrary code using certain template features. It can also allow for cross-site scripting. +

+
+ +

+ Ensure that an untrusted value is not used to directly construct a template. + Jinja also provides a SandboxedEnvironment that prohibits access to unsafe methods and attributes, that can be used if constructing a template from user input is absolutely necessary. +

+
+ +

In the following case template is used to generate a Jinja2 template string. This can lead to remote code execution.

+ + +

The following is an example of a string that could be used to cause remote code execution when interpreted as a template:

+ + +

In the following case, user input is not used to construct the template; rather is only used for as the parameters to render the template, which is safe.

+ + +

In the following case, a SandboxedEnvironment is used, preventing remote code execution.

+ +
+ +
  • Portswigger : [Server Side Template Injection](https://portswigger.net/web-security/server-side-template-injection)
  • +
    +
    diff --git a/python/ql/src/Security/CWE-074/examples/JinjaBad.py b/python/ql/src/Security/CWE-074/examples/JinjaBad.py new file mode 100644 index 000000000000..0a82135b49ba --- /dev/null +++ b/python/ql/src/Security/CWE-074/examples/JinjaBad.py @@ -0,0 +1,19 @@ +from django.urls import path +from django.http import HttpResponse +from jinja2 import Template, escape + + +def a(request): + template = request.GET['template'] + + # BAD: Template is constructed from user input. + t = Template(template) + + name = request.GET['name'] + html = t.render(name=escape(name)) + return HttpResponse(html) + + +urlpatterns = [ + path('a', a), +] \ No newline at end of file diff --git a/python/ql/src/Security/CWE-074/examples/JinjaGoodParam.py b/python/ql/src/Security/CWE-074/examples/JinjaGoodParam.py new file mode 100644 index 000000000000..1d8bb6962f6a --- /dev/null +++ b/python/ql/src/Security/CWE-074/examples/JinjaGoodParam.py @@ -0,0 +1,17 @@ +from django.urls import path +from django.http import HttpResponse +from jinja2 import Template, escape + + +def a(request): + # GOOD: Template is a constant, not constructed from user input + t = Template("Hello, {{name}}!") + + name = request.GET['name'] + html = t.render(name=escape(name)) + return HttpResponse(html) + + +urlpatterns = [ + path('a', a), +] \ No newline at end of file diff --git a/python/ql/src/Security/CWE-074/examples/JinjaGoodSandbox.py b/python/ql/src/Security/CWE-074/examples/JinjaGoodSandbox.py new file mode 100644 index 000000000000..488591c6f83e --- /dev/null +++ b/python/ql/src/Security/CWE-074/examples/JinjaGoodSandbox.py @@ -0,0 +1,21 @@ +from django.urls import path +from django.http import HttpResponse +from jinja2 import escape +from jinja2.sandbox import SandboxedEnvironment + + +def a(request): + env = SandboxedEnvironment() + template = request.GET['template'] + + # GOOD: A sandboxed environment is used to construct the template. + t = env.from_string(template) + + name = request.GET['name'] + html = t.render(name=escape(name)) + return HttpResponse(html) + + +urlpatterns = [ + path('a', a), +] \ No newline at end of file diff --git a/python/ql/src/Security/CWE-074/examples/template_exploit.txt b/python/ql/src/Security/CWE-074/examples/template_exploit.txt new file mode 100644 index 000000000000..607b95bd8d8e --- /dev/null +++ b/python/ql/src/Security/CWE-074/examples/template_exploit.txt @@ -0,0 +1 @@ +{% for s in ().__class__.__base__.__subclasses__() %}{% if "warning" in s.__name__ %}{{s()._module.__builtins__['__import__']('os').system('cat /etc/passwd') }}{% endif %}{% endfor %} From e4e02ec6749947b6f2805482d07ea7d13ac86060 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Nov 2024 16:59:12 +0000 Subject: [PATCH 173/213] Add security severity + fix qhelp --- python/ql/src/Security/CWE-074/TemplateInjection.qhelp | 2 +- python/ql/src/Security/CWE-074/TemplateInjection.ql | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp index 06990a7237b6..477d1b0e139f 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp +++ b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp @@ -12,7 +12,7 @@

    -

    In the following case template is used to generate a Jinja2 template string. This can lead to remote code execution.

    +

    In the following case, template is used to generate a Jinja2 template string. This can lead to remote code execution.

    The following is an example of a string that could be used to cause remote code execution when interpreted as a template:

    diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.ql b/python/ql/src/Security/CWE-074/TemplateInjection.ql index 125478c801c8..2ea68414259e 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.ql +++ b/python/ql/src/Security/CWE-074/TemplateInjection.ql @@ -4,6 +4,7 @@ * @kind path-problem * @problem.severity error * @precision high + * @security-severity 9.3 * @id py/template-injection * @tags security * external/cwe/cwe-074 From 4602c5c90545c4d4b59464e4ccad51f0bd75a3da Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Nov 2024 17:06:25 +0000 Subject: [PATCH 174/213] Remove experimental version + qhelp fixes --- .../Security/CWE-074/TemplateInjection.qhelp | 4 +- .../experimental/Security/CWE-074/JinjaBad.py | 19 -- .../Security/CWE-074/JinjaGood.py | 20 --- .../CWE-074/TemplateConstructionConcept.qll | 165 ------------------ .../Security/CWE-074/TemplateInjection.qhelp | 24 --- .../Security/CWE-074/TemplateInjection.ql | 20 --- .../TemplateInjectionCustomizations.qll | 59 ------- .../CWE-074/TemplateInjectionQuery.qll | 18 -- .../CWE-074-TemplateInjection/AirspeedSsti.py | 11 -- .../CWE-074-TemplateInjection/BottleSsti.py | 20 --- .../CWE-074-TemplateInjection/Chameleon.py | 10 -- .../CWE-074-TemplateInjection/CheetahSinks.py | 22 --- .../CWE-074-TemplateInjection/ChevronSsti.py | 24 --- .../DjangoTemplates.py | 41 ----- .../FlaskTemplate.py | 22 --- .../CWE-074-TemplateInjection/Genshi.py | 18 -- .../CWE-074-TemplateInjection/JinjaSsti.py | 30 ---- .../CWE-074-TemplateInjection/MakoSsti.py | 15 -- .../CWE-074-TemplateInjection/TRender.py | 12 -- .../TemplateInjection.expected | 107 ------------ .../TemplateInjection.qlref | 1 - 21 files changed, 2 insertions(+), 660 deletions(-) delete mode 100644 python/ql/src/experimental/Security/CWE-074/JinjaBad.py delete mode 100644 python/ql/src/experimental/Security/CWE-074/JinjaGood.py delete mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll delete mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp delete mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql delete mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll delete mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjectionQuery.qll delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/AirspeedSsti.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/BottleSsti.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Chameleon.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/CheetahSinks.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/ChevronSsti.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/DjangoTemplates.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/FlaskTemplate.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Genshi.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/MakoSsti.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TRender.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp index 477d1b0e139f..619d834d1cfe 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp +++ b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp @@ -16,10 +16,10 @@

    The following is an example of a string that could be used to cause remote code execution when interpreted as a template:

    - +

    In the following case, user input is not used to construct the template; rather is only used for as the parameters to render the template, which is safe.

    - +

    In the following case, a SandboxedEnvironment is used, preventing remote code execution.

    diff --git a/python/ql/src/experimental/Security/CWE-074/JinjaBad.py b/python/ql/src/experimental/Security/CWE-074/JinjaBad.py deleted file mode 100644 index aaac3ec819eb..000000000000 --- a/python/ql/src/experimental/Security/CWE-074/JinjaBad.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from jinja2 import Template as Jinja2_Template -from jinja2 import Environment, DictLoader, escape - - -def a(request): - # Load the template - template = request.GET['template'] - t = Jinja2_Template(template) - name = request.GET['name'] - # Render the template with the context data - html = t.render(name=escape(name)) - return HttpResponse(html) - - -urlpatterns = [ - path('a', a), -] diff --git a/python/ql/src/experimental/Security/CWE-074/JinjaGood.py b/python/ql/src/experimental/Security/CWE-074/JinjaGood.py deleted file mode 100644 index a1b605618501..000000000000 --- a/python/ql/src/experimental/Security/CWE-074/JinjaGood.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from jinja2 import Template as Jinja2_Template -from jinja2 import Environment, DictLoader, escape - - -def a(request): - # Load the template - template = request.GET['template'] - env = SandboxedEnvironment(undefined=StrictUndefined) - t = env.from_string(template) - name = request.GET['name'] - # Render the template with the context data - html = t.render(name=escape(name)) - return HttpResponse(html) - - -urlpatterns = [ - path('a', a), -] diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll b/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll deleted file mode 100644 index 5144e2ff97b1..000000000000 --- a/python/ql/src/experimental/Security/CWE-074/TemplateConstructionConcept.qll +++ /dev/null @@ -1,165 +0,0 @@ -private import python -private import semmle.python.dataflow.new.DataFlow -private import semmle.python.ApiGraphs - -/** - * A data-flow node that constructs a template. - * - * Extend this class to refine existing API models. If you want to model new APIs, - * extend `TemplateConstruction::Range` instead. - */ -class TemplateConstruction extends DataFlow::Node instanceof TemplateConstruction::Range { - /** Gets the argument that specifies the template source. */ - DataFlow::Node getSourceArg() { result = super.getSourceArg() } -} - -/** Provides a class for modeling new system-command execution APIs. */ -module TemplateConstruction { - /** - * A data-flow node that constructs a template. - * - * Extend this class to model new APIs. If you want to refine existing API models, - * extend `TemplateConstruction` instead. - */ - abstract class Range extends DataFlow::Node { - /** Gets the argument that specifies the template source. */ - abstract DataFlow::Node getSourceArg(); - } -} - -// ----------------------------------------------------------------------------- -/** A call to `airspeed.Template`. */ -class AirspeedTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - AirspeedTemplateConstruction() { - this = API::moduleImport("airspeed").getMember("Template").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `bottle.SimpleTemplate`. */ -class BottleSimpleTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - BottleSimpleTemplateConstruction() { - this = API::moduleImport("bottle").getMember("SimpleTemplate").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `bottle.template`. */ -class BottleTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - BottleTemplateConstruction() { - this = API::moduleImport("bottle").getMember("template").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `chameleon.PageTemplate`. */ -class ChameleonTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - ChameleonTemplateConstruction() { - this = API::moduleImport("chameleon").getMember("PageTemplate").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `Cheetah.Template.Template`. */ -class CheetahTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - CheetahTemplateConstruction() { - this = - API::moduleImport("Cheetah") - .getMember("Template") - .getMember("Template") - .getASubclass*() - .getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `chevron.render`. */ -class ChevronRenderConstruction extends TemplateConstruction::Range, API::CallNode { - ChevronRenderConstruction() { this = API::moduleImport("chevron").getMember("render").getACall() } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `django.template.Template` */ -class DjangoTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - DjangoTemplateConstruction() { - this = API::moduleImport("django").getMember("template").getMember("Template").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -// TODO: support django.template.engines["django"]].from_string -/** A call to `flask.render_template_string`. */ -class FlaskTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - FlaskTemplateConstruction() { - this = API::moduleImport("flask").getMember("render_template_string").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `genshi.template.TextTemplate`. */ -class GenshiTextTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - GenshiTextTemplateConstruction() { - this = API::moduleImport("genshi").getMember("template").getMember("TextTemplate").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `genshi.template.MarkupTemplate` */ -class GenshiMarkupTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - GenshiMarkupTemplateConstruction() { - this = API::moduleImport("genshi").getMember("template").getMember("MarkupTemplate").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -// -/** A call to `jinja2.Template`. */ -class Jinja2TemplateConstruction extends TemplateConstruction::Range, API::CallNode { - Jinja2TemplateConstruction() { - this = API::moduleImport("jinja2").getMember("Template").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `jinja2.from_string`. */ -class Jinja2FromStringConstruction extends TemplateConstruction::Range, API::CallNode { - Jinja2FromStringConstruction() { - this = - API::moduleImport("jinja2") - .getMember("Environment") - .getReturn() - .getMember("from_string") - .getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `mako.template.Template`. */ -class MakoTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - MakoTemplateConstruction() { - this = API::moduleImport("mako").getMember("template").getMember("Template").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} - -/** A call to `trender.TRender`. */ -class TRenderTemplateConstruction extends TemplateConstruction::Range, API::CallNode { - TRenderTemplateConstruction() { - this = API::moduleImport("trender").getMember("TRender").getACall() - } - - override DataFlow::Node getSourceArg() { result = this.getArg(0) } -} diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp deleted file mode 100644 index b044243fc8e1..000000000000 --- a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp +++ /dev/null @@ -1,24 +0,0 @@ - - - -

    - Template Injection occurs when user input is embedded in a template in an unsafe manner. - When an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side is results in Server Side Template Injection. -

    -
    - -

    - To fix this, ensure that an untrusted value is not used as a template. If the application requirements do not alow this, use a sandboxed environment where access to unsafe attributes and methods is prohibited. -

    -
    - -

    Consider the example given below, an untrusted HTTP parameter `template` is used to generate a Jinja2 template string. This can lead to remote code execution.

    - - -

    Here we have fixed the problem by using the Jinja sandbox environment for evaluating untrusted code.

    - -
    - -
  • Portswigger : [Server Side Template Injection](https://portswigger.net/web-security/server-side-template-injection)
  • -
    -
    diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql deleted file mode 100644 index a10ad09a6ac9..000000000000 --- a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @name Server Side Template Injection - * @description Using user-controlled data to create a template can cause security issues. - * @kind path-problem - * @problem.severity error - * @precision high - * @id py/template-injection - * @tags security - * experimental - * external/cwe/cwe-074 - */ - -import python -import TemplateInjectionQuery -import TemplateInjectionFlow::PathGraph - -from TemplateInjectionFlow::PathNode source, TemplateInjectionFlow::PathNode sink -where TemplateInjectionFlow::flowPath(source, sink) -select sink.getNode(), source, sink, "This Template depends on $@.", source.getNode(), - "user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll b/python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll deleted file mode 100644 index 13c70fc7d04d..000000000000 --- a/python/ql/src/experimental/Security/CWE-074/TemplateInjectionCustomizations.qll +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Provides default sources, sinks and sanitizers for detecting - * "template injection" - * vulnerabilities, as well as extension points for adding your own. - */ - -private import python -private import semmle.python.dataflow.new.DataFlow -private import semmle.python.Concepts as C -private import semmle.python.dataflow.new.RemoteFlowSources -private import semmle.python.dataflow.new.BarrierGuards -private import TemplateConstructionConcept - -/** - * Provides default sources, sinks and sanitizers for detecting - * "template injection" - * vulnerabilities, as well as extension points for adding your own. - */ -module TemplateInjection { - /** - * A data flow source for "template injection" vulnerabilities. - */ - abstract class Source extends DataFlow::Node { } - - /** - * A data flow sink for "template injection" vulnerabilities. - */ - abstract class Sink extends DataFlow::Node { } - - /** - * A sanitizer for "template injection" vulnerabilities. - */ - abstract class Sanitizer extends DataFlow::Node { } - - /** - * DEPRECATED: Use `ActiveThreatModelSource` from Concepts instead! - */ - deprecated class RemoteFlowSourceAsSource = ActiveThreatModelSourceAsSource; - - /** - * An active threat-model source, considered as a flow source. - */ - private class ActiveThreatModelSourceAsSource extends Source, C::ActiveThreatModelSource { } - - /** - * A SQL statement of a SQL construction, considered as a flow sink. - */ - class TemplateConstructionAsSink extends Sink { - TemplateConstructionAsSink() { this = any(TemplateConstruction c).getSourceArg() } - } - - /** - * A comparison with a constant, considered as a sanitizer-guard. - */ - class ConstCompareAsSanitizerGuard extends Sanitizer, ConstCompareBarrier { } - - /** DEPRECATED: Use ConstCompareAsSanitizerGuard instead. */ - deprecated class StringConstCompareAsSanitizerGuard = ConstCompareAsSanitizerGuard; -} diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjectionQuery.qll b/python/ql/src/experimental/Security/CWE-074/TemplateInjectionQuery.qll deleted file mode 100644 index 111485e2602d..000000000000 --- a/python/ql/src/experimental/Security/CWE-074/TemplateInjectionQuery.qll +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Provides a taint-tracking configuration for detecting "template injection" vulnerabilities. - */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking -import TemplateInjectionCustomizations::TemplateInjection - -module TemplateInjectionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node node) { node instanceof Source } - - predicate isSink(DataFlow::Node node) { node instanceof Sink } - - predicate isBarrierIn(DataFlow::Node node) { node instanceof Sanitizer } -} - -module TemplateInjectionFlow = TaintTracking::Global; diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/AirspeedSsti.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/AirspeedSsti.py deleted file mode 100644 index 8938d8602f8d..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/AirspeedSsti.py +++ /dev/null @@ -1,11 +0,0 @@ -import airspeed -from flask import Flask, request - - -app = Flask(__name__) - - -@route('/other') -def a(): - template = request.args.get('template') - return airspeed.Template(template) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/BottleSsti.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/BottleSsti.py deleted file mode 100644 index b5f8a5feeffa..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/BottleSsti.py +++ /dev/null @@ -1,20 +0,0 @@ -from bottle import Bottle, route, request, redirect, response, SimpleTemplate -from bottle import template as temp - - -app = Bottle() - - -@route('/other') -def a(): - template = request.query.template - tpl = SimpleTemplate(template) - tpl.render(name='World') - return tmp - - -@route('/other2') -def b(): - template = request.query.template - temp(template, name='World') - return tmp diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Chameleon.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Chameleon.py deleted file mode 100644 index f58a641a9be3..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Chameleon.py +++ /dev/null @@ -1,10 +0,0 @@ -from chameleon import PageTemplate -from django.urls import path -from django.http import HttpResponse - - -def chameleon(request): - template = request.GET['template'] - tmpl = PageTemplate(template) - return HttpResponse(tmpl) - diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/CheetahSinks.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/CheetahSinks.py deleted file mode 100644 index 7f9fed4decf5..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/CheetahSinks.py +++ /dev/null @@ -1,22 +0,0 @@ -from flask import Flask, request -from Cheetah.Template import Template - - -app = Flask(__name__) - - -@app.route('/other') -def a(): - template = request.args.get('template') - return Template(template) - - -class Template3(Template): - title = 'Hello World Example!' - contents = 'Hello World!' - - -@app.route('/other2') -def b(): - template = request.args.get('template') - t3 = Template3(template) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/ChevronSsti.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/ChevronSsti.py deleted file mode 100644 index f3b0e57fc8f7..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/ChevronSsti.py +++ /dev/null @@ -1,24 +0,0 @@ -from flask import Flask, request -import chevron - - -app = Flask(__name__) - - -@app.route('/other') -def a(): - template = request.args.get('template') - return chevron.render(template, {"key": "value"}) - - -@app.route('/other2') -def b(): - template = request.args.get('template') - args = { - 'template': template, - - 'data': { - 'key': 'value' - } - } - return chevron.render(**args) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/DjangoTemplates.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/DjangoTemplates.py deleted file mode 100644 index 26f48fd92780..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/DjangoTemplates.py +++ /dev/null @@ -1,41 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from django.template import Template, Context, Engine, engines - - -def dj(request): - # Load the template - template = request.GET['template'] - t = Template(template) - ctx = Context(locals()) - html = t.render(ctx) - return HttpResponse(html) - - -def djEngine(request): - # Load the template - template = request.GET['template'] - - django_engine = engines['django'] - t = django_engine.from_string(template) - ctx = Context(locals()) - html = t.render(ctx) - return HttpResponse(html) - - -def djEngineJinja(request): - # Load the template - template = request.GET['template'] - - django_engine = engines['jinja'] - t = django_engine.from_string(template) - ctx = Context(locals()) - html = t.render(ctx) - return HttpResponse(html) - - -urlpatterns = [ - path('', dj), - path('', djEngine), - path('', djEngineJinja), -] diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/FlaskTemplate.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/FlaskTemplate.py deleted file mode 100644 index b74e3cce715d..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/FlaskTemplate.py +++ /dev/null @@ -1,22 +0,0 @@ -from flask import Flask, request - - -app = Flask(__name__) - - -@app.route("/") -def home(): - from flask import render_template_string - if request.args.get('template'): - return render_template_string(request.args.get('template')) - - -@app.route("/a") -def a(): - import flask - return flask.render_template_string(request.args.get('template')) - - - -if __name__ == "__main__": - app.run(debug=True) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Genshi.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Genshi.py deleted file mode 100644 index 7800c50da968..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/Genshi.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from genshi.template import TextTemplate,MarkupTemplate - -def genshi1(): - template = request.GET['template'] - tmpl = MarkupTemplate(template) - return HttpResponse(tmpl) - -def genshi2(): - template = request.GET['template'] - tmpl = TextTemplate(template) - return HttpResponse(tmpl) - -urlpatterns = [ - path('', genshi1), - path('', genshi2) -] diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py deleted file mode 100644 index 28225c81cbaa..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from jinja2 import Template as Jinja2_Template -from jinja2 import Environment, DictLoader, escape - - -def a(request): - # Load the template - template = request.GET['template'] - t = Jinja2_Template(template) - name = request.GET['name'] - # Render the template with the context data - html = t.render(name=escape(name)) - return HttpResponse(html) - -def b(request): - import jinja2 - # Load the template - template = request.GET['template'] - t = jinja2.from_string(template) - name = request.GET['name'] - # Render the template with the context data - html = t.render(name=escape(name)) - return HttpResponse(html) - - -urlpatterns = [ - path('a', a), - path('b', b) -] diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/MakoSsti.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/MakoSsti.py deleted file mode 100644 index 7f6b25cb26cb..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/MakoSsti.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from mako.template import Template - - -def mako(request): - # Load the template - template = request.GET['template'] - mytemplate = Template(template) - return HttpResponse(mytemplate) - - -urlpatterns = [ - path('', mako) -] diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TRender.py b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TRender.py deleted file mode 100644 index 2514f22b8059..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TRender.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from trender import TRender - -def trender(request): - template = request.GET['template'] - compiled = TRender(template) - return HttpResponse(compiled) - -urlpatterns = [ - path('', trender) -] diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected deleted file mode 100644 index 06cf81cc6aaf..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected +++ /dev/null @@ -1,107 +0,0 @@ -edges -| AirspeedSsti.py:2:26:2:32 | ControlFlowNode for ImportMember | AirspeedSsti.py:2:26:2:32 | ControlFlowNode for request | provenance | | -| AirspeedSsti.py:2:26:2:32 | ControlFlowNode for request | AirspeedSsti.py:10:16:10:22 | ControlFlowNode for request | provenance | | -| AirspeedSsti.py:10:5:10:12 | ControlFlowNode for template | AirspeedSsti.py:11:30:11:37 | ControlFlowNode for template | provenance | | -| AirspeedSsti.py:10:16:10:22 | ControlFlowNode for request | AirspeedSsti.py:10:16:10:27 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | -| AirspeedSsti.py:10:16:10:27 | ControlFlowNode for Attribute | AirspeedSsti.py:10:16:10:43 | ControlFlowNode for Attribute() | provenance | dict.get | -| AirspeedSsti.py:10:16:10:43 | ControlFlowNode for Attribute() | AirspeedSsti.py:10:5:10:12 | ControlFlowNode for template | provenance | | -| CheetahSinks.py:1:26:1:32 | ControlFlowNode for ImportMember | CheetahSinks.py:1:26:1:32 | ControlFlowNode for request | provenance | | -| CheetahSinks.py:1:26:1:32 | ControlFlowNode for request | CheetahSinks.py:10:16:10:22 | ControlFlowNode for request | provenance | | -| CheetahSinks.py:1:26:1:32 | ControlFlowNode for request | CheetahSinks.py:21:16:21:22 | ControlFlowNode for request | provenance | | -| CheetahSinks.py:10:5:10:12 | ControlFlowNode for template | CheetahSinks.py:11:21:11:28 | ControlFlowNode for template | provenance | | -| CheetahSinks.py:10:16:10:22 | ControlFlowNode for request | CheetahSinks.py:10:16:10:27 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | -| CheetahSinks.py:10:16:10:27 | ControlFlowNode for Attribute | CheetahSinks.py:10:16:10:43 | ControlFlowNode for Attribute() | provenance | dict.get | -| CheetahSinks.py:10:16:10:43 | ControlFlowNode for Attribute() | CheetahSinks.py:10:5:10:12 | ControlFlowNode for template | provenance | | -| CheetahSinks.py:21:5:21:12 | ControlFlowNode for template | CheetahSinks.py:22:20:22:27 | ControlFlowNode for template | provenance | | -| CheetahSinks.py:21:16:21:22 | ControlFlowNode for request | CheetahSinks.py:21:16:21:27 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | -| CheetahSinks.py:21:16:21:27 | ControlFlowNode for Attribute | CheetahSinks.py:21:16:21:43 | ControlFlowNode for Attribute() | provenance | dict.get | -| CheetahSinks.py:21:16:21:43 | ControlFlowNode for Attribute() | CheetahSinks.py:21:5:21:12 | ControlFlowNode for template | provenance | | -| ChevronSsti.py:1:26:1:32 | ControlFlowNode for ImportMember | ChevronSsti.py:1:26:1:32 | ControlFlowNode for request | provenance | | -| ChevronSsti.py:1:26:1:32 | ControlFlowNode for request | ChevronSsti.py:10:16:10:22 | ControlFlowNode for request | provenance | | -| ChevronSsti.py:10:5:10:12 | ControlFlowNode for template | ChevronSsti.py:11:27:11:34 | ControlFlowNode for template | provenance | | -| ChevronSsti.py:10:16:10:22 | ControlFlowNode for request | ChevronSsti.py:10:16:10:27 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | -| ChevronSsti.py:10:16:10:27 | ControlFlowNode for Attribute | ChevronSsti.py:10:16:10:43 | ControlFlowNode for Attribute() | provenance | dict.get | -| ChevronSsti.py:10:16:10:43 | ControlFlowNode for Attribute() | ChevronSsti.py:10:5:10:12 | ControlFlowNode for template | provenance | | -| DjangoTemplates.py:6:8:6:14 | ControlFlowNode for request | DjangoTemplates.py:8:5:8:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | -| DjangoTemplates.py:8:5:8:12 | ControlFlowNode for template | DjangoTemplates.py:9:18:9:25 | ControlFlowNode for template | provenance | | -| FlaskTemplate.py:1:26:1:32 | ControlFlowNode for ImportMember | FlaskTemplate.py:1:26:1:32 | ControlFlowNode for request | provenance | | -| FlaskTemplate.py:1:26:1:32 | ControlFlowNode for request | FlaskTemplate.py:10:8:10:14 | ControlFlowNode for request | provenance | | -| FlaskTemplate.py:1:26:1:32 | ControlFlowNode for request | FlaskTemplate.py:11:39:11:45 | ControlFlowNode for request | provenance | | -| FlaskTemplate.py:1:26:1:32 | ControlFlowNode for request | FlaskTemplate.py:17:41:17:47 | ControlFlowNode for request | provenance | | -| FlaskTemplate.py:10:8:10:14 | ControlFlowNode for request | FlaskTemplate.py:11:39:11:50 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | -| FlaskTemplate.py:11:39:11:45 | ControlFlowNode for request | FlaskTemplate.py:11:39:11:50 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | -| FlaskTemplate.py:11:39:11:50 | ControlFlowNode for Attribute | FlaskTemplate.py:11:39:11:66 | ControlFlowNode for Attribute() | provenance | dict.get | -| FlaskTemplate.py:17:41:17:47 | ControlFlowNode for request | FlaskTemplate.py:17:41:17:52 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | -| FlaskTemplate.py:17:41:17:52 | ControlFlowNode for Attribute | FlaskTemplate.py:17:41:17:68 | ControlFlowNode for Attribute() | provenance | dict.get | -| JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | -| JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | JinjaSsti.py:10:25:10:32 | ControlFlowNode for template | provenance | | -| JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:19:5:19:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | -| JinjaSsti.py:19:5:19:12 | ControlFlowNode for template | JinjaSsti.py:20:28:20:35 | ControlFlowNode for template | provenance | | -| MakoSsti.py:6:10:6:16 | ControlFlowNode for request | MakoSsti.py:8:5:8:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | -| MakoSsti.py:8:5:8:12 | ControlFlowNode for template | MakoSsti.py:9:27:9:34 | ControlFlowNode for template | provenance | | -| TRender.py:5:13:5:19 | ControlFlowNode for request | TRender.py:6:5:6:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | -| TRender.py:6:5:6:12 | ControlFlowNode for template | TRender.py:7:24:7:31 | ControlFlowNode for template | provenance | | -nodes -| AirspeedSsti.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| AirspeedSsti.py:2:26:2:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| AirspeedSsti.py:10:5:10:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| AirspeedSsti.py:10:16:10:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| AirspeedSsti.py:10:16:10:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| AirspeedSsti.py:10:16:10:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| AirspeedSsti.py:11:30:11:37 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| CheetahSinks.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| CheetahSinks.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| CheetahSinks.py:10:5:10:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| CheetahSinks.py:10:16:10:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| CheetahSinks.py:10:16:10:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| CheetahSinks.py:10:16:10:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| CheetahSinks.py:11:21:11:28 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| CheetahSinks.py:21:5:21:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| CheetahSinks.py:21:16:21:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| CheetahSinks.py:21:16:21:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| CheetahSinks.py:21:16:21:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| CheetahSinks.py:22:20:22:27 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| ChevronSsti.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| ChevronSsti.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| ChevronSsti.py:10:5:10:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| ChevronSsti.py:10:16:10:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| ChevronSsti.py:10:16:10:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| ChevronSsti.py:10:16:10:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| ChevronSsti.py:11:27:11:34 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| DjangoTemplates.py:6:8:6:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| DjangoTemplates.py:8:5:8:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| DjangoTemplates.py:9:18:9:25 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| FlaskTemplate.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| FlaskTemplate.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| FlaskTemplate.py:10:8:10:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| FlaskTemplate.py:11:39:11:45 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| FlaskTemplate.py:11:39:11:50 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| FlaskTemplate.py:11:39:11:66 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| FlaskTemplate.py:17:41:17:47 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| FlaskTemplate.py:17:41:17:52 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| FlaskTemplate.py:17:41:17:68 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| JinjaSsti.py:10:25:10:32 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| JinjaSsti.py:19:5:19:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| JinjaSsti.py:20:28:20:35 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| MakoSsti.py:6:10:6:16 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| MakoSsti.py:8:5:8:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| MakoSsti.py:9:27:9:34 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| TRender.py:5:13:5:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| TRender.py:6:5:6:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -| TRender.py:7:24:7:31 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | -subpaths -#select -| AirspeedSsti.py:11:30:11:37 | ControlFlowNode for template | AirspeedSsti.py:2:26:2:32 | ControlFlowNode for ImportMember | AirspeedSsti.py:11:30:11:37 | ControlFlowNode for template | This Template depends on $@. | AirspeedSsti.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| CheetahSinks.py:11:21:11:28 | ControlFlowNode for template | CheetahSinks.py:1:26:1:32 | ControlFlowNode for ImportMember | CheetahSinks.py:11:21:11:28 | ControlFlowNode for template | This Template depends on $@. | CheetahSinks.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| CheetahSinks.py:22:20:22:27 | ControlFlowNode for template | CheetahSinks.py:1:26:1:32 | ControlFlowNode for ImportMember | CheetahSinks.py:22:20:22:27 | ControlFlowNode for template | This Template depends on $@. | CheetahSinks.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| ChevronSsti.py:11:27:11:34 | ControlFlowNode for template | ChevronSsti.py:1:26:1:32 | ControlFlowNode for ImportMember | ChevronSsti.py:11:27:11:34 | ControlFlowNode for template | This Template depends on $@. | ChevronSsti.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| DjangoTemplates.py:9:18:9:25 | ControlFlowNode for template | DjangoTemplates.py:6:8:6:14 | ControlFlowNode for request | DjangoTemplates.py:9:18:9:25 | ControlFlowNode for template | This Template depends on $@. | DjangoTemplates.py:6:8:6:14 | ControlFlowNode for request | user-provided value | -| FlaskTemplate.py:11:39:11:66 | ControlFlowNode for Attribute() | FlaskTemplate.py:1:26:1:32 | ControlFlowNode for ImportMember | FlaskTemplate.py:11:39:11:66 | ControlFlowNode for Attribute() | This Template depends on $@. | FlaskTemplate.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| FlaskTemplate.py:17:41:17:68 | ControlFlowNode for Attribute() | FlaskTemplate.py:1:26:1:32 | ControlFlowNode for ImportMember | FlaskTemplate.py:17:41:17:68 | ControlFlowNode for Attribute() | This Template depends on $@. | FlaskTemplate.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| JinjaSsti.py:10:25:10:32 | ControlFlowNode for template | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:10:25:10:32 | ControlFlowNode for template | This Template depends on $@. | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | user-provided value | -| JinjaSsti.py:20:28:20:35 | ControlFlowNode for template | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:20:28:20:35 | ControlFlowNode for template | This Template depends on $@. | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | user-provided value | -| MakoSsti.py:9:27:9:34 | ControlFlowNode for template | MakoSsti.py:6:10:6:16 | ControlFlowNode for request | MakoSsti.py:9:27:9:34 | ControlFlowNode for template | This Template depends on $@. | MakoSsti.py:6:10:6:16 | ControlFlowNode for request | user-provided value | -| TRender.py:7:24:7:31 | ControlFlowNode for template | TRender.py:5:13:5:19 | ControlFlowNode for request | TRender.py:7:24:7:31 | ControlFlowNode for template | This Template depends on $@. | TRender.py:5:13:5:19 | ControlFlowNode for request | user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref b/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref deleted file mode 100644 index 90efec9f6360..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-074/TemplateInjection.ql From f0163894b679bc99dcc8f5dcb031b0432e12696d Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Nov 2024 17:23:49 +0000 Subject: [PATCH 175/213] fix link in qhelp refs --- python/ql/src/Security/CWE-074/TemplateInjection.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp index 619d834d1cfe..c3770d59cf2a 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp +++ b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp @@ -25,6 +25,6 @@
    -
  • Portswigger : [Server Side Template Injection](https://portswigger.net/web-security/server-side-template-injection)
  • +
  • Portswigger: Server-Side Template Injection.
  • From 494d779541f508f1f81dc85c06e914ea1269c805 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Nov 2024 17:43:36 +0000 Subject: [PATCH 176/213] Add changenote --- python/ql/src/change-notes/2024-11-21-template-injection.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/src/change-notes/2024-11-21-template-injection.md diff --git a/python/ql/src/change-notes/2024-11-21-template-injection.md b/python/ql/src/change-notes/2024-11-21-template-injection.md new file mode 100644 index 000000000000..a2d782f8cc07 --- /dev/null +++ b/python/ql/src/change-notes/2024-11-21-template-injection.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* The Server Side Template Injection query (`py/template-injection`), originally contributed to the experimental query pack by @porcupineyhairs, has been promoted to the ain query suite. This query finds instances of templates for a template engine such as Jinja being constructed with user input. \ No newline at end of file From 0f0c1e1609c34c100c05dfe0c452f6a407aff159 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 22 Nov 2024 16:32:10 +0000 Subject: [PATCH 177/213] Test update --- .../library-tests/frameworks/django-v2-v3/template_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py b/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py index 2d25848fde65..ba98c8f41964 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py @@ -1,13 +1,13 @@ from django.template import Template, engines from django.urls import path -from django.http.response import HttpResponse, +from django.http.response import HttpResponse def a(request): # $requestHandler t = Template("abc").render() # $templateConstruction="abc" return HttpResponse(t) # $HttpResponse def b(request): # $requestHandler - # This case is not yet supported + # This case is not currently supported t = django.template.engines["django"].from_string("abc") # $MISSING:templateConstruction="abc" return HttpResponse(t) # $HttpResponse From 6e16ed52e886979450264578a9b21835391e6d66 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 29 Nov 2024 09:49:31 +0000 Subject: [PATCH 178/213] Reveiw suggestions: Spelling/grammar fixes Co-authored-by: Taus --- python/ql/src/Security/CWE-074/TemplateInjection.qhelp | 2 +- python/ql/src/Security/CWE-074/TemplateInjection.ql | 2 +- python/ql/src/change-notes/2024-11-21-template-injection.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp index c3770d59cf2a..5b8827b05f3d 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp +++ b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp @@ -18,7 +18,7 @@

    The following is an example of a string that could be used to cause remote code execution when interpreted as a template:

    -

    In the following case, user input is not used to construct the template; rather is only used for as the parameters to render the template, which is safe.

    +

    In the following case, user input is not used to construct the template; rather it is only used as the parameters to render the template, which is safe.

    In the following case, a SandboxedEnvironment is used, preventing remote code execution.

    diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.ql b/python/ql/src/Security/CWE-074/TemplateInjection.ql index 2ea68414259e..53b0a2e9b15a 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.ql +++ b/python/ql/src/Security/CWE-074/TemplateInjection.ql @@ -16,5 +16,5 @@ import TemplateInjectionFlow::PathGraph from TemplateInjectionFlow::PathNode source, TemplateInjectionFlow::PathNode sink where TemplateInjectionFlow::flowPath(source, sink) -select sink.getNode(), source, sink, "This Template construction depends on $@.", source.getNode(), +select sink.getNode(), source, sink, "This template construction depends on a $@.", source.getNode(), "user-provided value" diff --git a/python/ql/src/change-notes/2024-11-21-template-injection.md b/python/ql/src/change-notes/2024-11-21-template-injection.md index a2d782f8cc07..7c604e9c9936 100644 --- a/python/ql/src/change-notes/2024-11-21-template-injection.md +++ b/python/ql/src/change-notes/2024-11-21-template-injection.md @@ -1,4 +1,4 @@ --- category: newQuery --- -* The Server Side Template Injection query (`py/template-injection`), originally contributed to the experimental query pack by @porcupineyhairs, has been promoted to the ain query suite. This query finds instances of templates for a template engine such as Jinja being constructed with user input. \ No newline at end of file +* The Server Side Template Injection query (`py/template-injection`), originally contributed to the experimental query pack by @porcupineyhairs, has been promoted to the main query suite. This query finds instances of templates for a template engine such as Jinja being constructed with user input. \ No newline at end of file From 55557f8dd3d5e73a959ca4ddfcc537f662380858 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 29 Nov 2024 10:12:46 +0000 Subject: [PATCH 179/213] Use API graohs directly --- .../lib/semmle/python/frameworks/Jinja2.qll | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Jinja2.qll b/python/ql/lib/semmle/python/frameworks/Jinja2.qll index 0d0a8d989211..070176077e3c 100644 --- a/python/ql/lib/semmle/python/frameworks/Jinja2.qll +++ b/python/ql/lib/semmle/python/frameworks/Jinja2.qll @@ -33,22 +33,13 @@ module Jinja2 { result = ModelOutput::getATypeNode("jinja.Environment~Subclass").getASubclass*() } - /** Gets a reference to an instance of `jinja2.Environment`. */ - private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { - t.start() and - result = EnvironmentClass::classRef().getACall() - or - exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) - } - - /** Gets a reference to an instance of `jinja2.Environment`. */ - DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + API::Node instance() { result = classRef().getAnInstance() } /** A call to `jinja2.Environment.from_string`. */ - private class Jinja2FromStringConstruction extends TemplateConstruction::Range, - DataFlow::MethodCallNode - { - Jinja2FromStringConstruction() { this.calls(EnvironmentClass::instance(), "from_string") } + private class Jinja2FromStringConstruction extends TemplateConstruction::Range, API::CallNode { + Jinja2FromStringConstruction() { + this = EnvironmentClass::instance().getMember("from_string").getACall() + } override DataFlow::Node getSourceArg() { result = this.getArg(0) } } From dd8b7a4a8fa3e26a3f7d61ce612574d6709f922d Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 29 Nov 2024 10:21:13 +0000 Subject: [PATCH 180/213] Add additional test for safe case in documentation --- .../ql/test/library-tests/frameworks/jinja2/template_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/jinja2/template_test.py b/python/ql/test/library-tests/frameworks/jinja2/template_test.py index 587de84f6216..23cc9f151b9a 100644 --- a/python/ql/test/library-tests/frameworks/jinja2/template_test.py +++ b/python/ql/test/library-tests/frameworks/jinja2/template_test.py @@ -1,7 +1,11 @@ from jinja2 import Environment, Template +from jinja2.sandbox import SandboxedEnvironment def test(): env = Environment() t = env.from_string("abc") # $ templateConstruction="abc" t = Template("abc") # $ templateConstruction="abc" + + env2 = SandboxedEnvironment() + t = env.from_string("abc") # No result as we don't model SandboxedEnvironment. We may wish to instead specifically model it as NOT vulnerable to template injection vulnerabilities. return t \ No newline at end of file From ebaab89933aaa6d2b95672d54ee6e8c04602a110 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 29 Nov 2024 10:29:37 +0000 Subject: [PATCH 181/213] Formatting updates --- python/ql/lib/semmle/python/Frameworks.qll | 1 - python/ql/src/Security/CWE-074/TemplateInjection.ql | 4 ++-- .../frameworks/django-v2-v3/template_test.py | 12 ++++++------ .../library-tests/frameworks/flask/template_test.py | 4 ++-- .../library-tests/frameworks/jinja2/template_test.py | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/python/ql/lib/semmle/python/Frameworks.qll b/python/ql/lib/semmle/python/Frameworks.qll index af9417308ab3..e6af222a615f 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -17,7 +17,6 @@ private import semmle.python.frameworks.Asyncpg private import semmle.python.frameworks.Baize private import semmle.python.frameworks.Bottle private import semmle.python.frameworks.BSon -private import semmle.python.frameworks.Bottle private import semmle.python.frameworks.CassandraDriver private import semmle.python.frameworks.Chameleon private import semmle.python.frameworks.Cherrypy diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.ql b/python/ql/src/Security/CWE-074/TemplateInjection.ql index 53b0a2e9b15a..bc4c935bc377 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.ql +++ b/python/ql/src/Security/CWE-074/TemplateInjection.ql @@ -16,5 +16,5 @@ import TemplateInjectionFlow::PathGraph from TemplateInjectionFlow::PathNode source, TemplateInjectionFlow::PathNode sink where TemplateInjectionFlow::flowPath(source, sink) -select sink.getNode(), source, sink, "This template construction depends on a $@.", source.getNode(), - "user-provided value" +select sink.getNode(), source, sink, "This template construction depends on a $@.", + source.getNode(), "user-provided value" diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py b/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py index ba98c8f41964..1f59b4a03c23 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/template_test.py @@ -2,14 +2,14 @@ from django.urls import path from django.http.response import HttpResponse -def a(request): # $requestHandler - t = Template("abc").render() # $templateConstruction="abc" - return HttpResponse(t) # $HttpResponse +def a(request): # $ requestHandler + t = Template("abc").render() # $ templateConstruction="abc" + return HttpResponse(t) # $ HttpResponse -def b(request): # $requestHandler +def b(request): # $ requestHandler # This case is not currently supported - t = django.template.engines["django"].from_string("abc") # $MISSING:templateConstruction="abc" - return HttpResponse(t) # $HttpResponse + t = django.template.engines["django"].from_string("abc") # $ MISSING:templateConstruction="abc" + return HttpResponse(t) # $ HttpResponse urlpatterns = [ path("a", a), # $ routeSetup="a" diff --git a/python/ql/test/library-tests/frameworks/flask/template_test.py b/python/ql/test/library-tests/frameworks/flask/template_test.py index 8d867e148291..e50ab7063550 100644 --- a/python/ql/test/library-tests/frameworks/flask/template_test.py +++ b/python/ql/test/library-tests/frameworks/flask/template_test.py @@ -2,12 +2,12 @@ app = Flask(__name__) @app.route("/a") # $routeSetup="/a" -def a(): # $requestHandler +def a(): # $ requestHandler r = render_template_string("abc") # $ templateConstruction="abc" return r # $ HttpResponse @app.route("/b") # $routeSetup="/b" -def b(): # $requestHandler +def b(): # $ requestHandler s = stream_template_string("abc") # $ templateConstruction="abc" r = Response(stream_with_context(s)) # $ HttpResponse return r # $ HttpResponse diff --git a/python/ql/test/library-tests/frameworks/jinja2/template_test.py b/python/ql/test/library-tests/frameworks/jinja2/template_test.py index 23cc9f151b9a..40004b4f1c50 100644 --- a/python/ql/test/library-tests/frameworks/jinja2/template_test.py +++ b/python/ql/test/library-tests/frameworks/jinja2/template_test.py @@ -7,5 +7,5 @@ def test(): t = Template("abc") # $ templateConstruction="abc" env2 = SandboxedEnvironment() - t = env.from_string("abc") # No result as we don't model SandboxedEnvironment. We may wish to instead specifically model it as NOT vulnerable to template injection vulnerabilities. + t = env2.from_string("abc") # No result as we don't model SandboxedEnvironment. We may wish to instead specifically model it as NOT vulnerable to template injection vulnerabilities. return t \ No newline at end of file From ef1d898b0d86bf0d2982ca6a65b54a9ff29bf0a0 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 29 Nov 2024 10:44:48 +0000 Subject: [PATCH 182/213] Add qldoc --- python/ql/lib/semmle/python/frameworks/Jinja2.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/lib/semmle/python/frameworks/Jinja2.qll b/python/ql/lib/semmle/python/frameworks/Jinja2.qll index 070176077e3c..0387db936311 100644 --- a/python/ql/lib/semmle/python/frameworks/Jinja2.qll +++ b/python/ql/lib/semmle/python/frameworks/Jinja2.qll @@ -33,6 +33,7 @@ module Jinja2 { result = ModelOutput::getATypeNode("jinja.Environment~Subclass").getASubclass*() } + /** Gets a reference to an instance of `jinja2.Environment`. */ API::Node instance() { result = classRef().getAnInstance() } /** A call to `jinja2.Environment.from_string`. */ From 462be46be9897ca9a7bd99f06d52eafb2e288bc6 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 29 Nov 2024 20:54:03 +0000 Subject: [PATCH 183/213] Update test output --- .../CWE-074-TemplateInjection/TemplateInjection.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected index 3a833787a982..f92107728395 100644 --- a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected @@ -12,5 +12,5 @@ nodes | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | subpaths #select -| JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | This Template construction depends on $@. | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | user-provided value | -| JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | This Template construction depends on $@. | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | user-provided value | +| JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | This template construction depends on a $@. | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | user-provided value | +| JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | This template construction depends on a $@. | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | user-provided value | From 8a778da25327d1fa6ebe62adcd326289cbc11871 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 9 Dec 2024 10:22:24 +0000 Subject: [PATCH 184/213] Apply suggestions from docs review Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- python/ql/src/Security/CWE-074/TemplateInjection.qhelp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp index 5b8827b05f3d..ee416b77eec9 100644 --- a/python/ql/src/Security/CWE-074/TemplateInjection.qhelp +++ b/python/ql/src/Security/CWE-074/TemplateInjection.qhelp @@ -8,7 +8,7 @@

    Ensure that an untrusted value is not used to directly construct a template. - Jinja also provides a SandboxedEnvironment that prohibits access to unsafe methods and attributes, that can be used if constructing a template from user input is absolutely necessary. + Jinja also provides SandboxedEnvironment that prohibits access to unsafe methods and attributes. This can be used if constructing a template from user input is absolutely necessary.

    @@ -18,7 +18,7 @@

    The following is an example of a string that could be used to cause remote code execution when interpreted as a template:

    -

    In the following case, user input is not used to construct the template; rather it is only used as the parameters to render the template, which is safe.

    +

    In the following case, user input is not used to construct the template. Instead, it is only used as the parameters to render the template, which is safe.

    In the following case, a SandboxedEnvironment is used, preventing remote code execution.

    From f82fa202496071d8587a6c6b96b836dd55813061 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 9 Dec 2024 20:37:11 +0000 Subject: [PATCH 185/213] Update test outputs --- .../test/library-tests/frameworks/Genshi/ConceptsTest.expected | 2 -- .../ql/test/library-tests/frameworks/Mako/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/TRender/ConceptsTest.expected | 2 -- .../library-tests/frameworks/airspeed/ConceptsTest.expected | 2 -- .../library-tests/frameworks/chameleon/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/chevron/ConceptsTest.expected | 2 -- .../test/library-tests/frameworks/jinja2/ConceptsTest.expected | 2 -- 7 files changed, 14 deletions(-) diff --git a/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected index a74f2c23cda2..e69de29bb2d1 100644 --- a/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/Genshi/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected index a74f2c23cda2..e69de29bb2d1 100644 --- a/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/Mako/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected index a74f2c23cda2..e69de29bb2d1 100644 --- a/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/TRender/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected index a74f2c23cda2..e69de29bb2d1 100644 --- a/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/airspeed/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected index a74f2c23cda2..e69de29bb2d1 100644 --- a/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/chameleon/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected index a74f2c23cda2..e69de29bb2d1 100644 --- a/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/chevron/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected index a74f2c23cda2..e69de29bb2d1 100644 --- a/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/jinja2/ConceptsTest.expected @@ -1,2 +0,0 @@ -testFailures -failures \ No newline at end of file From 8f5822e4c6b6618e029d02eb2ef94c356a175a35 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 00:22:53 +0000 Subject: [PATCH 186/213] Add changed framework coverage reports --- csharp/documentation/library-coverage/coverage.csv | 1 + csharp/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv index 39646702a8c0..50035b8a0099 100644 --- a/csharp/documentation/library-coverage/coverage.csv +++ b/csharp/documentation/library-coverage/coverage.csv @@ -14,6 +14,7 @@ Microsoft.Android.Build,,1,14,,,,,,,,,,,,,1,,,,,,12,2 Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,,,7, Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,,, Microsoft.AspNetCore.Components,,2,1,,,,,,,,,,,,,,,,2,,,1, +Microsoft.AspNetCore.Mvc,,,2,,,,,,,,,,,,,,,,,,,,2 Microsoft.AspNetCore.WebUtilities,,,2,,,,,,,,,,,,,,,,,,,2, Microsoft.CSharp,,,2,,,,,,,,,,,,,,,,,,,2, Microsoft.Diagnostics.Tools.Pgo,,,25,,,,,,,,,,,,,,,,,,,2,23 diff --git a/csharp/documentation/library-coverage/coverage.rst b/csharp/documentation/library-coverage/coverage.rst index 7023de4a356b..77354aa656dd 100644 --- a/csharp/documentation/library-coverage/coverage.rst +++ b/csharp/documentation/library-coverage/coverage.rst @@ -9,6 +9,6 @@ C# framework & library support Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting` `ServiceStack `_,"``ServiceStack.*``, ``ServiceStack``",,7,194, System,"``System.*``, ``System``",47,10819,54,5 - Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",59,2071,150,2 - Totals,,106,12897,398,7 + Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",59,2073,150,2 + Totals,,106,12899,398,7 From 4275813b87f5d1cba5d5f2694544579538a9a01c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 9 Dec 2024 16:31:11 +0100 Subject: [PATCH 187/213] C#: Make the path tests independent. --- .../extractor/Semmle.Util.Tests/LongPaths.cs | 196 ++++++++++-------- 1 file changed, 115 insertions(+), 81 deletions(-) diff --git a/csharp/extractor/Semmle.Util.Tests/LongPaths.cs b/csharp/extractor/Semmle.Util.Tests/LongPaths.cs index c1583e275036..90607bc8f02d 100644 --- a/csharp/extractor/Semmle.Util.Tests/LongPaths.cs +++ b/csharp/extractor/Semmle.Util.Tests/LongPaths.cs @@ -1,5 +1,6 @@ using Xunit; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using Semmle.Util; @@ -10,39 +11,51 @@ namespace SemmleTests.Semmle.Util /// Ensure that the Extractor works with long paths. /// These should be handled by .NET Core. /// - public sealed class LongPaths : IDisposable + public sealed class LongPaths { private static readonly string tmpDir = Environment.GetEnvironmentVariable("TEST_TMPDIR") ?? Path.GetTempPath(); - private static readonly string shortPath = Path.Combine(tmpDir, "test.txt"); - private static readonly string longPath = Path.Combine(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + private static readonly string longPathDir = Path.Combine(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ccccccccccccccccccccccccccccccc", "ddddddddddddddddddddddddddddddddddddd", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "fffffffffffffffffffffffffffffffff", - "ggggggggggggggggggggggggggggggggggg", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "iiiiiiiiiiiiiiii.txt"); + "ggggggggggggggggggggggggggggggggggg", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); - public LongPaths() + private static string MakeLongPath() { - CleanUp(); + var uniquePostfix = Guid.NewGuid().ToString("N"); + return Path.Combine(longPathDir, $"iiiiiiiiiiiiiiii{uniquePostfix}.txt"); } - public void Dispose() + private static string MakeShortPath() { - CleanUp(); + var uniquePostfix = Guid.NewGuid().ToString("N"); + return Path.Combine(tmpDir, $"test{uniquePostfix}.txt"); } - private static void CleanUp() + public LongPaths() { - try - { - File.Delete(shortPath); - } - catch (DirectoryNotFoundException) + // Create directory to avoid directory not found exceptions when deleting files + Directory.CreateDirectory(longPathDir); + } + + private static void Cleanup(params IEnumerable paths) + { + foreach (var path in paths) { + File.Delete(path); } + } + + private static void WithSetUpAndTearDown(Action test) + { + var longPath = MakeLongPath(); + var shortPath = MakeShortPath(); + Cleanup(longPath, shortPath); try { - File.Delete(longPath); + test(longPath, shortPath); } - catch (DirectoryNotFoundException) + finally { + Cleanup(longPath, shortPath); } } @@ -63,122 +76,143 @@ public void ParentDirectory() [Fact] public void Delete() { - // OK Do not exist. - File.Delete(shortPath); - File.Delete(longPath); + WithSetUpAndTearDown((longPath, shortPath) => + { + // OK Do not exist. + File.Delete(shortPath); + File.Delete(longPath); + }); } [Fact] public void Move() { - File.WriteAllText(shortPath, "abc"); - Directory.CreateDirectory(Path.GetDirectoryName(longPath)!); - File.Delete(longPath); - File.Move(shortPath, longPath); - File.Move(longPath, shortPath); - Assert.Equal("abc", File.ReadAllText(shortPath)); + WithSetUpAndTearDown((longPath, shortPath) => + { + File.WriteAllText(shortPath, "abc"); + File.Delete(longPath); + File.Move(shortPath, longPath); + File.Move(longPath, shortPath); + Assert.Equal("abc", File.ReadAllText(shortPath)); + }); } [Fact] public void Replace() { - File.WriteAllText(shortPath, "abc"); - File.Delete(longPath); - Directory.CreateDirectory(Path.GetDirectoryName(longPath)!); - File.Move(shortPath, longPath); - File.WriteAllText(shortPath, "def"); - FileUtils.MoveOrReplace(shortPath, longPath); - File.WriteAllText(shortPath, "abc"); - FileUtils.MoveOrReplace(longPath, shortPath); - Assert.Equal("def", File.ReadAllText(shortPath)); + WithSetUpAndTearDown((longPath, shortPath) => + { + File.WriteAllText(shortPath, "abc"); + File.Move(shortPath, longPath); + File.WriteAllText(shortPath, "def"); + FileUtils.MoveOrReplace(shortPath, longPath); + File.WriteAllText(shortPath, "abc"); + FileUtils.MoveOrReplace(longPath, shortPath); + Assert.Equal("def", File.ReadAllText(shortPath)); + }); } - private readonly byte[] buffer1 = new byte[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + private readonly byte[] buffer1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; [Fact] public void CreateShortStream() { - var buffer2 = new byte[10]; - - using (var s1 = new FileStream(shortPath, FileMode.Create, FileAccess.Write, FileShare.None)) + WithSetUpAndTearDown((_, shortPath) => { - s1.Write(buffer1, 0, 10); - } + var buffer2 = new byte[10]; - using (var s2 = new FileStream(shortPath, FileMode.Open, FileAccess.Read, FileShare.None)) - { - Assert.Equal(10, s2.Read(buffer2, 0, 10)); - Assert.True(Enumerable.SequenceEqual(buffer1, buffer2)); - } + using (var s1 = new FileStream(shortPath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + s1.Write(buffer1, 0, 10); + } + + using (var s2 = new FileStream(shortPath, FileMode.Open, FileAccess.Read, FileShare.None)) + { + Assert.Equal(10, s2.Read(buffer2, 0, 10)); + Assert.True(Enumerable.SequenceEqual(buffer1, buffer2)); + } + }); } [Fact] public void CreateLongStream() { - var buffer2 = new byte[10]; + WithSetUpAndTearDown((longPath, _) => + { + var buffer2 = new byte[10]; - Directory.CreateDirectory(Path.GetDirectoryName(longPath)!); + Directory.CreateDirectory(Path.GetDirectoryName(longPath)!); - using (var s3 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - s3.Write(buffer1, 0, 10); - } + using (var s3 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + s3.Write(buffer1, 0, 10); + } - using (var s4 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None)) - { - Assert.Equal(10, s4.Read(buffer2, 0, 10)); - Assert.True(Enumerable.SequenceEqual(buffer1, buffer2)); - } + using (var s4 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None)) + { + Assert.Equal(10, s4.Read(buffer2, 0, 10)); + Assert.True(Enumerable.SequenceEqual(buffer1, buffer2)); + } + }); } [Fact] public void FileDoesNotExist() { - // File does not exist - Assert.Throws(() => + WithSetUpAndTearDown((longPath, _) => { - using (new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None)) + // File does not exist + Assert.Throws(() => { - // - } + using (new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None)) + { + // + } + }); }); } [Fact] public void OverwriteFile() { - using (var s1 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None)) + WithSetUpAndTearDown((longPath, _) => { - s1.Write(buffer1, 0, 10); - } + using (var s1 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + s1.Write(buffer1, 0, 10); + } - byte[] buffer2 = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + byte[] buffer2 = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - using (var s2 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - s2.Write(buffer2, 0, 10); - } + using (var s2 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + s2.Write(buffer2, 0, 10); + } - byte[] buffer3 = new byte[10]; + byte[] buffer3 = new byte[10]; - using (var s3 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None)) - { - Assert.Equal(10, s3.Read(buffer3, 0, 10)); - } + using (var s3 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None)) + { + Assert.Equal(10, s3.Read(buffer3, 0, 10)); + } - Assert.True(Enumerable.SequenceEqual(buffer2, buffer3)); + Assert.True(Enumerable.SequenceEqual(buffer2, buffer3)); + }); } [Fact] public void LongFileExists() { - Assert.False(File.Exists("no such file")); - Assert.False(File.Exists("\":")); - Assert.False(File.Exists(@"C:\")); // A directory + WithSetUpAndTearDown((longPath, _) => + { + Assert.False(File.Exists("no such file")); + Assert.False(File.Exists("\":")); + Assert.False(File.Exists(@"C:\")); // A directory - Assert.False(File.Exists(longPath)); - new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None).Close(); - Assert.True(File.Exists(longPath)); + Assert.False(File.Exists(longPath)); + new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None).Close(); + Assert.True(File.Exists(longPath)); + }); } } } From 53ca5083a912e20358f5e1f1c995d347c8526c65 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Tue, 10 Dec 2024 11:47:45 +0100 Subject: [PATCH 188/213] Upgrade bazel to 8.0.0. Previously, we were using 8.0.0rc1. In particular, this upgrade means we need to explicitly import more rules, as they've been moved out of the core bazel repo. --- .bazelrc | 8 ++++++++ .bazelversion | 2 +- MODULE.bazel | 9 +++++---- csharp/scripts/BUILD.bazel | 2 ++ go/BUILD.bazel | 1 + java/kotlin-extractor/BUILD.bazel | 1 + misc/bazel/BUILD.bazel | 2 ++ misc/codegen/BUILD.bazel | 2 ++ misc/codegen/generators/BUILD.bazel | 2 ++ misc/codegen/lib/BUILD.bazel | 1 + misc/codegen/loaders/BUILD.bazel | 1 + misc/codegen/test/BUILD.bazel | 1 + misc/ripunzip/BUILD.bazel | 2 ++ python/extractor/BUILD.bazel | 1 + rust/codegen/BUILD.bazel | 1 + swift/extractor/BUILD.bazel | 1 + swift/logging/tests/assertion-diagnostics/BUILD.bazel | 1 + swift/ql/integration-tests/BUILD.bazel | 2 ++ swift/swift-autobuilder/tests/BUILD.bazel | 2 ++ swift/third_party/resource-dir/BUILD.bazel | 2 ++ swift/tools/BUILD.bazel | 1 + swift/tools/test/qltest/BUILD.bazel | 2 ++ 22 files changed, 42 insertions(+), 5 deletions(-) diff --git a/.bazelrc b/.bazelrc index 60455dd72c60..40beef6eecce 100644 --- a/.bazelrc +++ b/.bazelrc @@ -24,4 +24,12 @@ common --registry=https://bcr.bazel.build common --@rules_dotnet//dotnet/settings:strict_deps=false +# Reduce this eventually to empty, once we've fixed all our usages of java, and https://github.com/bazel-contrib/rules_go/issues/4193 is fixed +common --incompatible_autoload_externally="+@rules_java,+@rules_shell" + +build --java_language_version=17 +build --tool_java_language_version=17 +build --tool_java_runtime_version=remotejdk_17 +build --java_runtime_version=remotejdk_17 + try-import %workspace%/local.bazelrc diff --git a/.bazelversion b/.bazelversion index 5ce91d4d61c9..ae9a76b9249a 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -8.0.0rc1 +8.0.0 diff --git a/MODULE.bazel b/MODULE.bazel index 08a4aaa78af9..d2ae279af602 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -15,16 +15,17 @@ local_path_override( # see https://registry.bazel.build/ for a list of available packages bazel_dep(name = "platforms", version = "0.0.10") -bazel_dep(name = "rules_go", version = "0.50.0") +bazel_dep(name = "rules_go", version = "0.50.1") bazel_dep(name = "rules_pkg", version = "1.0.1") bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1") -bazel_dep(name = "rules_python", version = "0.36.0") +bazel_dep(name = "rules_python", version = "0.40.0") +bazel_dep(name = "rules_shell", version = "0.3.0") bazel_dep(name = "bazel_skylib", version = "1.7.1") -bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl") +bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl") bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json") bazel_dep(name = "fmt", version = "10.0.0") bazel_dep(name = "rules_kotlin", version = "2.0.0-codeql.1") -bazel_dep(name = "gazelle", version = "0.38.0") +bazel_dep(name = "gazelle", version = "0.40.0") bazel_dep(name = "rules_dotnet", version = "0.17.4") bazel_dep(name = "googletest", version = "1.14.0.bcr.1") bazel_dep(name = "rules_rust", version = "0.52.2") diff --git a/csharp/scripts/BUILD.bazel b/csharp/scripts/BUILD.bazel index c4b44ac28ac4..8f4f239104e0 100644 --- a/csharp/scripts/BUILD.bazel +++ b/csharp/scripts/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_python//python:defs.bzl", "py_binary") + py_binary( name = "gen-git-assembly-info", srcs = ["gen-git-assembly-info.py"], diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 931f061da9ef..d73e7ba1a6fa 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -1,5 +1,6 @@ load("@gazelle//:def.bzl", "gazelle") load("@rules_pkg//pkg:mappings.bzl", "pkg_files") +load("@rules_python//python:defs.bzl", "py_binary") load("//misc/bazel:pkg.bzl", "codeql_pack", "codeql_pkg_files") gazelle( diff --git a/java/kotlin-extractor/BUILD.bazel b/java/kotlin-extractor/BUILD.bazel index f95661f8128c..575b9788e8c5 100644 --- a/java/kotlin-extractor/BUILD.bazel +++ b/java/kotlin-extractor/BUILD.bazel @@ -40,6 +40,7 @@ load( ) load("@rules_kotlin//kotlin:core.bzl", "kt_javac_options", "kt_kotlinc_options") load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_python//python:defs.bzl", "py_binary") package(default_visibility = ["//java/kotlin-extractor:__subpackages__"]) diff --git a/misc/bazel/BUILD.bazel b/misc/bazel/BUILD.bazel index c3670b75c94a..e00a6f7a64c7 100644 --- a/misc/bazel/BUILD.bazel +++ b/misc/bazel/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_shell//shell:sh_library.bzl", "sh_library") + sh_library( name = "sh_runfiles", srcs = ["runfiles.sh"], diff --git a/misc/codegen/BUILD.bazel b/misc/codegen/BUILD.bazel index 52a5c0011345..c7b88de96b7d 100644 --- a/misc/codegen/BUILD.bazel +++ b/misc/codegen/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_python//python:defs.bzl", "py_binary") + py_binary( name = "codegen", srcs = ["codegen.py"], diff --git a/misc/codegen/generators/BUILD.bazel b/misc/codegen/generators/BUILD.bazel index f731c42ce23a..df89a2ac507f 100644 --- a/misc/codegen/generators/BUILD.bazel +++ b/misc/codegen/generators/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_python//python:defs.bzl", "py_library") + py_library( name = "generators", srcs = glob(["*.py"]), diff --git a/misc/codegen/lib/BUILD.bazel b/misc/codegen/lib/BUILD.bazel index 482d1ac178fa..a68840beca34 100644 --- a/misc/codegen/lib/BUILD.bazel +++ b/misc/codegen/lib/BUILD.bazel @@ -1,4 +1,5 @@ load("@codegen_deps//:requirements.bzl", "requirement") +load("@rules_python//python:defs.bzl", "py_library") py_library( name = "lib", diff --git a/misc/codegen/loaders/BUILD.bazel b/misc/codegen/loaders/BUILD.bazel index be07c6d884bc..7e7a5ec8acc4 100644 --- a/misc/codegen/loaders/BUILD.bazel +++ b/misc/codegen/loaders/BUILD.bazel @@ -1,4 +1,5 @@ load("@codegen_deps//:requirements.bzl", "requirement") +load("@rules_python//python:defs.bzl", "py_library") py_library( name = "loaders", diff --git a/misc/codegen/test/BUILD.bazel b/misc/codegen/test/BUILD.bazel index dde67283335d..d8c06175785d 100644 --- a/misc/codegen/test/BUILD.bazel +++ b/misc/codegen/test/BUILD.bazel @@ -1,4 +1,5 @@ load("@codegen_deps//:requirements.bzl", "requirement") +load("@rules_python//python:defs.bzl", "py_library", "py_test") py_library( name = "utils", diff --git a/misc/ripunzip/BUILD.bazel b/misc/ripunzip/BUILD.bazel index ea21e6b1c948..6575b692772b 100644 --- a/misc/ripunzip/BUILD.bazel +++ b/misc/ripunzip/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_shell//shell:sh_binary.bzl", "sh_binary") + alias( name = "ripunzip", actual = select({"@platforms//os:" + os: "@ripunzip-" + os for os in ("linux", "windows", "macos")}), diff --git a/python/extractor/BUILD.bazel b/python/extractor/BUILD.bazel index eabaee519ea5..77025503fe65 100644 --- a/python/extractor/BUILD.bazel +++ b/python/extractor/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_python//python:defs.bzl", "py_binary") load("//misc/bazel:pkg.bzl", "codeql_pkg_files", "strip_prefix") py_binary( diff --git a/rust/codegen/BUILD.bazel b/rust/codegen/BUILD.bazel index fbac3d04619f..37118ca8777a 100644 --- a/rust/codegen/BUILD.bazel +++ b/rust/codegen/BUILD.bazel @@ -1,4 +1,5 @@ load("@bazel_skylib//rules:native_binary.bzl", "native_binary") +load("@rules_shell//shell:sh_binary.bzl", "sh_binary") _args = [ "//rust/ast-generator", diff --git a/swift/extractor/BUILD.bazel b/swift/extractor/BUILD.bazel index 8290aec41216..342125c9d4fa 100644 --- a/swift/extractor/BUILD.bazel +++ b/swift/extractor/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_shell//shell:sh_binary.bzl", "sh_binary") load("//misc/bazel:pkg.bzl", "codeql_pkg_runfiles") load("//swift:rules.bzl", "swift_cc_binary") diff --git a/swift/logging/tests/assertion-diagnostics/BUILD.bazel b/swift/logging/tests/assertion-diagnostics/BUILD.bazel index 86fbbbee7c7f..c01a91fafd49 100644 --- a/swift/logging/tests/assertion-diagnostics/BUILD.bazel +++ b/swift/logging/tests/assertion-diagnostics/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_python//python:defs.bzl", "py_test") load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( diff --git a/swift/ql/integration-tests/BUILD.bazel b/swift/ql/integration-tests/BUILD.bazel index 3c376593c4ab..352170c4cef4 100644 --- a/swift/ql/integration-tests/BUILD.bazel +++ b/swift/ql/integration-tests/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_python//python:defs.bzl", "py_library") + py_library( name = "utils", srcs = [ diff --git a/swift/swift-autobuilder/tests/BUILD.bazel b/swift/swift-autobuilder/tests/BUILD.bazel index f9a2b8eb1781..507899cf445f 100644 --- a/swift/swift-autobuilder/tests/BUILD.bazel +++ b/swift/swift-autobuilder/tests/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_python//python:defs.bzl", "py_test") + [ py_test( name = test_dir + "-test", diff --git a/swift/third_party/resource-dir/BUILD.bazel b/swift/third_party/resource-dir/BUILD.bazel index 9cea2efd0293..b48be643b698 100644 --- a/swift/third_party/resource-dir/BUILD.bazel +++ b/swift/third_party/resource-dir/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_shell//shell:sh_binary.bzl", "sh_binary") + alias( name = "resource-dir", actual = select({"@platforms//os:" + os: "@swift-resource-dir-" + os for os in ("linux", "macos")}), diff --git a/swift/tools/BUILD.bazel b/swift/tools/BUILD.bazel index 777b96490685..0c59e2571e55 100644 --- a/swift/tools/BUILD.bazel +++ b/swift/tools/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_shell//shell:sh_binary.bzl", "sh_binary") load("//misc/bazel:pkg.bzl", "codeql_pkg_files") sh_binary( diff --git a/swift/tools/test/qltest/BUILD.bazel b/swift/tools/test/qltest/BUILD.bazel index f16563eb21df..c8a9b80364d0 100644 --- a/swift/tools/test/qltest/BUILD.bazel +++ b/swift/tools/test/qltest/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_python//python:defs.bzl", "py_library", "py_test") + py_library( name = "utils", srcs = ["utils.py"], From c8046fa8e0fcb2caff7422bc5e0d2a82ec0d01c0 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 11:25:27 +0100 Subject: [PATCH 189/213] Dataflow: Drop some ApApprox columns and joins. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 113 ++++++++---------- 1 file changed, 48 insertions(+), 65 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 313934378c63..635e8e24aee8 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -942,11 +942,9 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind) { + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind) { throughFlowNodeCand(ret) and - kind = ret.getKind() and - exists(argAp) and - exists(ap) + kind = ret.getKind() } pragma[nomagic] @@ -969,11 +967,10 @@ module MakeImpl Lang> { predicate callEdgeReturn( DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Ap ap + boolean allowsFieldFlow ) { flowOutOfCallNodeCand1(call, ret, kind, out, allowsFieldFlow) and - c = ret.getEnclosingCallable() and - exists(ap) + c = ret.getEnclosingCallable() } predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { @@ -981,7 +978,7 @@ module MakeImpl Lang> { } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - callEdgeReturn(call, c, _, _, _, _, _) + callEdgeReturn(call, c, _, _, _, _) } additional predicate stats( @@ -1004,7 +1001,7 @@ module MakeImpl Lang> { calledges = count(DataFlowCall call, DataFlowCallable c | callEdgeArgParam(call, c, _, _, _, _) or - callEdgeReturn(call, c, _, _, _, _, _) + callEdgeReturn(call, c, _, _, _, _) ) } /* End: Stage 1 logic. */ @@ -1287,7 +1284,7 @@ module MakeImpl Lang> { predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap); - predicate returnMayFlowThrough(RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind); + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind); predicate storeStepCand( NodeEx node1, Ap ap1, Content c, NodeEx node2, DataFlowType contentType, @@ -1303,7 +1300,7 @@ module MakeImpl Lang> { predicate callEdgeReturn( DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Ap ap + boolean allowsFieldFlow ); predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c); @@ -1437,13 +1434,12 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - ApApprox argApa, ApApprox apa + DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow ) { exists(ReturnKindExt kind | - PrevStage::callEdgeReturn(call, _, ret, kind, out, allowsFieldFlow, apa) and + PrevStage::callEdgeReturn(call, _, ret, kind, out, allowsFieldFlow) and PrevStage::callMayFlowThroughRev(call) and - PrevStage::returnMayFlowThrough(ret, argApa, apa, kind) and + PrevStage::returnMayFlowThrough(ret, kind) and matchesCall(ccc, call) ) } @@ -1560,12 +1556,9 @@ module MakeImpl Lang> { fwdFlowOut(_, _, node, state, cc, summaryCtx, t, ap, apa, stored) or // flow through a callable - exists( - DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, - ApApprox innerArgApa - | - fwdFlowThrough(call, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, innerArgApa) and - flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa) and + exists(DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow | + fwdFlowThrough(call, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, _) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow) and not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1925,7 +1918,7 @@ module MakeImpl Lang> { DataFlowCallable c, CcNoCall ctx ) { result = viableImplCallContextReducedReverse(c, ctx) and - PrevStage::callEdgeReturn(result, c, _, _, _, _, _) + PrevStage::callEdgeReturn(result, c, _, _, _, _) } bindingset[c, ctx] @@ -1939,21 +1932,20 @@ module MakeImpl Lang> { bindingset[call] pragma[inline_late] private predicate flowOutOfCallApaInlineLate( - DataFlowCall call, DataFlowCallable c, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - ApApprox apa + DataFlowCall call, DataFlowCallable c, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow ) { - PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow, apa) + PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) } - bindingset[c, ret, apa, innercc] + bindingset[c, ret, innercc] pragma[inline_late] pragma[noopt] private predicate flowOutOfCallApaNotCallContextReduced( DataFlowCall call, DataFlowCallable c, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, - ApApprox apa, CcNoCall innercc + CcNoCall innercc ) { viableImplNotCallContextReducedReverse(innercc) and - PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow, apa) + PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) } pragma[nomagic] @@ -1975,10 +1967,9 @@ module MakeImpl Lang> { inner = ret.getEnclosingCallable() and ( call = viableImplCallContextReducedReverseInlineLate(inner, innercc) and - flowOutOfCallApaInlineLate(call, inner, ret, out, allowsFieldFlow, apa) + flowOutOfCallApaInlineLate(call, inner, ret, out, allowsFieldFlow) or - flowOutOfCallApaNotCallContextReduced(call, inner, ret, out, allowsFieldFlow, apa, - innercc) + flowOutOfCallApaNotCallContextReduced(call, inner, ret, out, allowsFieldFlow, innercc) ) } @@ -2050,10 +2041,8 @@ module MakeImpl Lang> { private predicate fwdFlow1Out( NodeEx node, FlowState state, Cc cc, Typ t0, Ap ap, TypOption stored ) { - exists(ApApprox apa | - fwdFlow1(node, state, cc, _, t0, _, ap, apa, stored) and - PrevStage::callEdgeReturn(_, _, _, _, node, _, apa) - ) + fwdFlow1(node, state, cc, _, t0, _, ap, _, stored) and + PrevStage::callEdgeReturn(_, _, _, _, node, _) } pragma[nomagic] @@ -2097,15 +2086,14 @@ module MakeImpl Lang> { ) { exists(ReturnKindExt kind, ParamNodeEx p, Ap argAp | instanceofCcCall(ccc) and - fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, - pragma[only_bind_into](apa), stored) and + fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, apa, stored) and summaryCtx = TSummaryCtxSome(pragma[only_bind_into](p), _, _, pragma[only_bind_into](argAp), _) and not outBarrier(ret, state) and kind = ret.getKind() and parameterFlowThroughAllowed(p, kind) and argApa = getApprox(argAp) and - PrevStage::returnMayFlowThrough(ret, pragma[only_bind_into](argApa), apa, kind) + PrevStage::returnMayFlowThrough(ret, kind) ) } @@ -2178,10 +2166,10 @@ module MakeImpl Lang> { RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Typ argT, Ap argAp, ApApprox argApa, TypOption argStored, Ap ap ) { - exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow | - returnFlowsThrough0(call, state, ccc, ap, apa, ret, + exists(DataFlowCall call, boolean allowsFieldFlow | + returnFlowsThrough0(call, state, ccc, ap, _, ret, TSummaryCtxSome(p, _, argT, argAp, argStored), argApa) and - flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, argApa, apa) and + flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow) and pos = ret.getReturnPosition() and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2216,14 +2204,13 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowOutOfCallAp( DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnPosition pos, NodeEx out, - Ap ap + Ap ap, boolean allowsFieldFlow ) { - exists(ApApprox apa, boolean allowsFieldFlow | - PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow, apa) and - fwdFlow(ret, _, _, _, _, ap, apa, _) and - pos = ret.getReturnPosition() and - if allowsFieldFlow = false then ap instanceof ApNil else any() - | + PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) and + fwdFlow(ret, _, _, _, _, ap, _, _) and + pos = ret.getReturnPosition() and + (if allowsFieldFlow = false then ap instanceof ApNil else any()) and + ( // both directions are needed for flow-through FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or FwdTypeFlowInput::dataFlowTakenCallEdgeOut(call, c) @@ -2356,7 +2343,7 @@ module MakeImpl Lang> { predicate enableTypeFlow = Param::enableTypeFlow/0; predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - flowOutOfCallAp(call, c, _, _, _, _) + flowOutOfCallAp(call, c, _, _, _, _, _) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { @@ -2407,7 +2394,7 @@ module MakeImpl Lang> { DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Ap ap, boolean cc ) { exists(DataFlowCallable c | - flowOutOfCallAp(call, c, ret, pos, out, ap) and + flowOutOfCallAp(call, c, ret, pos, out, ap, _) and RevTypeFlow::typeFlowValidEdgeIn(call, c, cc) ) } @@ -2559,8 +2546,8 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate returnMayFlowThrough(RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind) { - exists(ParamNodeEx p, ReturnPosition pos | + predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind) { + exists(ParamNodeEx p, ReturnPosition pos, Ap argAp, Ap ap | returnFlowsThrough(ret, pos, _, _, p, _, argAp, _, _, ap) and parameterFlowsThroughRev(p, argAp, pos, ap) and kind = pos.getKind() @@ -2607,14 +2594,13 @@ module MakeImpl Lang> { predicate callEdgeReturn( DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, - boolean allowsFieldFlow, Ap ap + boolean allowsFieldFlow ) { - exists(FlowState state, ReturnPosition pos | - flowOutOfCallAp(call, c, ret, pos, out, ap) and + exists(FlowState state, ReturnPosition pos, Ap ap | + flowOutOfCallAp(call, c, ret, pos, out, ap, allowsFieldFlow) and revFlow(ret, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and revFlow(out, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and kind = pos.getKind() and - allowsFieldFlow = true and RevTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) ) } @@ -2624,7 +2610,7 @@ module MakeImpl Lang> { } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - callEdgeReturn(call, c, _, _, _, _, _) + callEdgeReturn(call, c, _, _, _, _) } /** Holds if `node1` can step to `node2` in one or more local steps. */ @@ -2719,7 +2705,7 @@ module MakeImpl Lang> { callEdgeArgParam(_, _, node, next, _, ap) and apNext = ap or - callEdgeReturn(_, _, node, _, next, _, ap) and + callEdgeReturn(_, _, node, _, next, _) and apNext = ap or storeStepCand(node, _, _, next, _, _) @@ -3206,13 +3192,10 @@ module MakeImpl Lang> { PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, NodeEx node, Cc cc, FlowState state, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { - exists( - DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, - ApApprox innerArgApa, ApApprox apa - | - fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, t, ap, apa, - stored, ret, innerArgApa) and - flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa) and + exists(DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow | + fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, t, ap, _, stored, + ret, _) and + flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow) and not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) From 7c888ebe062c41026e112e92cf5ca0bfaff1314c Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 11:43:01 +0100 Subject: [PATCH 190/213] Dataflow: Replace some allowsFieldFlow,apa pairs with emptyAp boolean. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 142 +++++++++--------- 1 file changed, 68 insertions(+), 74 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 635e8e24aee8..b3563d958618 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -931,12 +931,12 @@ module MakeImpl Lang> { * candidate for the origin of a summary. */ pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap) { + predicate parameterMayFlowThrough(ParamNodeEx p, boolean emptyAp) { exists(DataFlowCallable c, ReturnKindExt kind | throughFlowNodeCand(p) and returnFlowCallableNodeCand(c, kind) and p.getEnclosingCallable() = c and - exists(ap) and + emptyAp = [true, false] and parameterFlowThroughAllowed(p, kind) ) } @@ -957,12 +957,17 @@ module MakeImpl Lang> { } predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, - boolean allowsFieldFlow, Ap ap + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { - flowIntoCallNodeCand1(call, arg, p, allowsFieldFlow) and - c = p.getEnclosingCallable() and - exists(ap) + exists(boolean allowsFieldFlow | + flowIntoCallNodeCand1(call, arg, p, allowsFieldFlow) and + c = p.getEnclosingCallable() and + ( + emptyAp = true + or + allowsFieldFlow = true and emptyAp = false + ) + ) } predicate callEdgeReturn( @@ -974,7 +979,7 @@ module MakeImpl Lang> { } predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - callEdgeArgParam(call, c, _, _, _, _) + callEdgeArgParam(call, c, _, _, _) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { @@ -1000,7 +1005,7 @@ module MakeImpl Lang> { tuples = count(NodeEx n, boolean b | revFlow(n, b)) and calledges = count(DataFlowCall call, DataFlowCallable c | - callEdgeArgParam(call, c, _, _, _, _) or + callEdgeArgParam(call, c, _, _, _) or callEdgeReturn(call, c, _, _, _, _) ) } @@ -1282,7 +1287,7 @@ module MakeImpl Lang> { predicate callMayFlowThroughRev(DataFlowCall call); - predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap); + predicate parameterMayFlowThrough(ParamNodeEx p, boolean emptyAp); predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind); @@ -1294,8 +1299,7 @@ module MakeImpl Lang> { predicate readStepCand(NodeEx n1, Content c, NodeEx n2); predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, - boolean allowsFieldFlow, Ap ap + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ); predicate callEdgeReturn( @@ -1732,34 +1736,19 @@ module MakeImpl Lang> { private module FwdFlowIn { pragma[nomagic] private predicate callEdgeArgParamRestricted( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp, - ApApprox apa + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { - exists(boolean allowsFieldFlow | - PrevStage::callEdgeArgParam(call, c, arg, p, allowsFieldFlow, apa) - | - if - PrevStage::callMayFlowThroughRev(call) and - PrevStage::parameterMayFlowThrough(p, apa) - then - emptyAp = true and - apa instanceof PrevStage::ApNil and - flowThrough() - or - emptyAp = false and - allowsFieldFlow = true and - if allowsFieldFlowThrough(call, c) then flowThrough() else not flowThrough() - else ( - not flowThrough() and - ( - emptyAp = true and - apa instanceof PrevStage::ApNil - or - emptyAp = false and - allowsFieldFlow = true - ) - ) - ) + PrevStage::callEdgeArgParam(call, c, arg, p, emptyAp) and + if + PrevStage::callMayFlowThroughRev(call) and + PrevStage::parameterMayFlowThrough(p, emptyAp) + then + emptyAp = true and + flowThrough() + or + emptyAp = false and + if allowsFieldFlowThrough(call, c) then flowThrough() else not flowThrough() + else not flowThrough() } pragma[nomagic] @@ -1767,7 +1756,7 @@ module MakeImpl Lang> { DataFlowCall call, CcCall ctx ) { result = viableImplCallContextReduced(call, ctx) and - callEdgeArgParamRestricted(call, result, _, _, _, _) + callEdgeArgParamRestricted(call, result, _, _, _) } bindingset[call, ctx] @@ -1783,7 +1772,7 @@ module MakeImpl Lang> { private DataFlowCallable viableImplCallContextReducedInlineLate( DataFlowCall call, ArgNodeEx arg, CcCall ctx ) { - callEdgeArgParamRestricted(call, _, arg, _, _, _) and + callEdgeArgParamRestricted(call, _, arg, _, _) and instanceofCcCall(ctx) and result = viableImplCallContextReducedInlineLate(call, ctx) } @@ -1791,10 +1780,9 @@ module MakeImpl Lang> { bindingset[call] pragma[inline_late] private predicate callEdgeArgParamRestrictedInlineLate( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp, - ApApprox apa + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { - callEdgeArgParamRestricted(call, c, arg, p, emptyAp, apa) + callEdgeArgParamRestricted(call, c, arg, p, emptyAp) } bindingset[call, ctx] @@ -1809,7 +1797,7 @@ module MakeImpl Lang> { private predicate viableImplArgNotCallContextReduced( DataFlowCall call, ArgNodeEx arg, Cc outercc ) { - callEdgeArgParamRestricted(call, _, arg, _, _, _) and + callEdgeArgParamRestricted(call, _, arg, _, _) and instanceofCc(outercc) and viableImplNotCallContextReducedInlineLate(call, outercc) } @@ -1828,7 +1816,7 @@ module MakeImpl Lang> { ) and not outBarrier(arg, state) and not inBarrier(p, state) and - callEdgeArgParamRestrictedInlineLate(call, inner, arg, p, emptyAp, apa) + callEdgeArgParamRestrictedInlineLate(call, inner, arg, p, emptyAp) } pragma[inline] @@ -2072,10 +2060,9 @@ module MakeImpl Lang> { private module FwdTypeFlow = TypeFlow; private predicate flowIntoCallApaTaken( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, - boolean allowsFieldFlow, ApApprox apa + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { - PrevStage::callEdgeArgParam(call, c, arg, p, allowsFieldFlow, apa) and + PrevStage::callEdgeArgParam(call, c, arg, p, emptyAp) and FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) } @@ -2177,16 +2164,16 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, Ap argAp, Ap ap ) { - exists(ApApprox argApa, Typ argT, TypOption argStored | + exists(ApApprox argApa, Typ argT, TypOption argStored, boolean emptyArgAp | returnFlowsThrough(_, _, _, _, pragma[only_bind_into](p), pragma[only_bind_into](argT), pragma[only_bind_into](argAp), pragma[only_bind_into](argApa), pragma[only_bind_into](argStored), ap) and - flowIntoCallApaTaken(call, _, pragma[only_bind_into](arg), p, allowsFieldFlow, argApa) and + flowIntoCallApaTaken(call, _, pragma[only_bind_into](arg), p, emptyArgAp) and fwdFlow(arg, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), pragma[only_bind_into](argApa), pragma[only_bind_into](argStored)) and - if allowsFieldFlow = false then argAp instanceof ApNil else any() + if argAp instanceof ApNil then emptyArgAp = true else emptyArgAp = false ) } @@ -2194,10 +2181,10 @@ module MakeImpl Lang> { private predicate flowIntoCallAp( DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, Ap ap ) { - exists(ApApprox apa, boolean allowsFieldFlow | - flowIntoCallApaTaken(call, c, arg, p, allowsFieldFlow, apa) and - fwdFlow(arg, _, _, _, _, ap, apa, _) and - if allowsFieldFlow = false then ap instanceof ApNil else any() + exists(boolean emptyAp | + flowIntoCallApaTaken(call, c, arg, p, emptyAp) and + fwdFlow(arg, _, _, _, _, ap, _, _) and + if ap instanceof ApNil then emptyAp = true else emptyAp = false ) } @@ -2282,7 +2269,7 @@ module MakeImpl Lang> { // flow through a callable exists(DataFlowCall call, ParamNodeEx p, Ap innerReturnAp | revFlowThrough(call, returnCtx, p, state, _, returnAp, ap, innerReturnAp) and - flowThroughIntoCall(call, node, p, _, ap, innerReturnAp) + flowThroughIntoCall(call, node, p, ap, innerReturnAp) ) or // flow out of a callable @@ -2424,10 +2411,13 @@ module MakeImpl Lang> { private predicate revFlowParamToReturn( ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap ) { - revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), - apSome(returnAp), pragma[only_bind_into](ap)) and - parameterFlowThroughAllowed(p, pos.getKind()) and - PrevStage::parameterMayFlowThrough(p, getApprox(ap)) + exists(boolean emptyAp | + revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), + apSome(returnAp), pragma[only_bind_into](ap)) and + parameterFlowThroughAllowed(p, pos.getKind()) and + PrevStage::parameterMayFlowThrough(p, emptyAp) and + if ap instanceof ApNil then emptyAp = true else emptyAp = false + ) } pragma[nomagic] @@ -2517,13 +2507,21 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap) { + private predicate parameterMayFlowThroughAp(ParamNodeEx p, Ap ap) { exists(ReturnPosition pos | returnFlowsThrough(_, pos, _, _, p, _, ap, _, _, _) and parameterFlowsThroughRev(p, ap, pos, _) ) } + pragma[nomagic] + predicate parameterMayFlowThrough(ParamNodeEx p, boolean emptyAp) { + exists(Ap ap | + parameterMayFlowThroughAp(p, ap) and + if ap instanceof ApNil then emptyAp = true else emptyAp = false + ) + } + pragma[nomagic] private predicate nodeMayUseSummary0(NodeEx n, ParamNodeEx p, FlowState state, Ap ap) { exists(Ap ap0 | @@ -2540,7 +2538,7 @@ module MakeImpl Lang> { pragma[nomagic] additional predicate nodeMayUseSummary(NodeEx n, FlowState state, Ap ap) { exists(ParamNodeEx p | - parameterMayFlowThrough(p, ap) and + parameterMayFlowThroughAp(p, ap) and nodeMayUseSummary0(n, p, state, ap) ) } @@ -2561,7 +2559,7 @@ module MakeImpl Lang> { ) { exists(ParamNodeEx p, Ap innerReturnAp | revFlowThrough(call, returnCtx, p, state, _, returnAp, ap, innerReturnAp) and - flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp) + flowThroughIntoCall(call, arg, p, ap, innerReturnAp) ) } @@ -2574,17 +2572,13 @@ module MakeImpl Lang> { } predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, - boolean allowsFieldFlow, Ap ap + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { - exists(FlowState state | + exists(FlowState state, Ap ap | flowIntoCallAp(call, c, arg, p, ap) and revFlow(arg, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and revFlow(p, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and - // allowsFieldFlow has already been checked in flowIntoCallAp, since - // `Ap` is at least as precise as a boolean from Stage 2 and - // forward, so no need to check it again later. - allowsFieldFlow = true + if ap instanceof ApNil then emptyAp = true else emptyAp = false | // both directions are needed for flow-through RevTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or @@ -2606,7 +2600,7 @@ module MakeImpl Lang> { } predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - callEdgeArgParam(call, c, _, _, _, _) + callEdgeArgParam(call, c, _, _, _) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { @@ -2702,7 +2696,7 @@ module MakeImpl Lang> { apNext = ap and ap instanceof ApNil or - callEdgeArgParam(_, _, node, next, _, ap) and + callEdgeArgParam(_, _, node, next, _) and apNext = ap or callEdgeReturn(_, _, node, _, next, _) and From d4044062c511096b0f33899e876bb6e459cda7e0 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 12:38:10 +0100 Subject: [PATCH 191/213] Dataflow: Remove ApApprox column in out-flow. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index b3563d958618..4db25288eeb4 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1557,7 +1557,8 @@ module MakeImpl Lang> { summaryCtx = TSummaryCtxSome(node, state, t, ap, stored) or // flow out of a callable - fwdFlowOut(_, _, node, state, cc, summaryCtx, t, ap, apa, stored) + fwdFlowOut(_, _, node, state, cc, summaryCtx, t, ap, stored) and + apa = getApprox(ap) or // flow through a callable exists(DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow | @@ -1939,19 +1940,19 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowIntoRet( RetNodeEx ret, FlowState state, CcNoCall cc, SummaryCtx summaryCtx, Typ t, Ap ap, - ApApprox apa, TypOption stored + TypOption stored ) { instanceofCcNoCall(cc) and not outBarrier(ret, state) and - fwdFlow(ret, state, cc, summaryCtx, t, ap, apa, stored) + fwdFlow(ret, state, cc, summaryCtx, t, ap, _, stored) } pragma[nomagic] private predicate fwdFlowOutCand( DataFlowCall call, RetNodeEx ret, CcNoCall innercc, DataFlowCallable inner, NodeEx out, - ApApprox apa, boolean allowsFieldFlow + boolean allowsFieldFlow ) { - fwdFlowIntoRet(ret, _, innercc, _, _, _, apa, _) and + fwdFlowIntoRet(ret, _, innercc, _, _, _, _) and inner = ret.getEnclosingCallable() and ( call = viableImplCallContextReducedReverseInlineLate(inner, innercc) and @@ -1964,9 +1965,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowOutValidEdge( DataFlowCall call, RetNodeEx ret, CcNoCall innercc, DataFlowCallable inner, NodeEx out, - CcNoCall outercc, ApApprox apa, boolean allowsFieldFlow + CcNoCall outercc, boolean allowsFieldFlow ) { - fwdFlowOutCand(call, ret, innercc, inner, out, apa, allowsFieldFlow) and + fwdFlowOutCand(call, ret, innercc, inner, out, allowsFieldFlow) and FwdTypeFlow::typeFlowValidEdgeOut(call, inner) and outercc = getCallContextReturn(inner, call) } @@ -1974,11 +1975,11 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowOut( DataFlowCall call, DataFlowCallable inner, NodeEx out, FlowState state, CcNoCall outercc, - SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, TypOption stored + SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow | - fwdFlowIntoRet(ret, state, innercc, summaryCtx, t, ap, apa, stored) and - fwdFlowOutValidEdge(call, ret, innercc, inner, out, outercc, apa, allowsFieldFlow) and + fwdFlowIntoRet(ret, state, innercc, summaryCtx, t, ap, stored) and + fwdFlowOutValidEdge(call, ret, innercc, inner, out, outercc, allowsFieldFlow) and not inBarrier(out, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -2022,7 +2023,7 @@ module MakeImpl Lang> { DataFlowCall call, DataFlowCallable c, NodeEx node, FlowState state, Cc cc, Typ t, Ap ap, TypOption stored ) { - fwdFlowOut(call, c, node, state, cc, _, t, ap, _, stored) + fwdFlowOut(call, c, node, state, cc, _, t, ap, stored) } pragma[nomagic] @@ -3299,10 +3300,10 @@ module MakeImpl Lang> { ) or // flow out of a callable - exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow, ApApprox apa | + exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow | pn1 = TPathNodeMid(ret, state, innercc, summaryCtx, t, ap, stored) and - fwdFlowIntoRet(ret, state, innercc, summaryCtx, t, ap, apa, stored) and - fwdFlowOutValidEdge(_, ret, innercc, _, node, cc, apa, allowsFieldFlow) and + fwdFlowIntoRet(ret, state, innercc, summaryCtx, t, ap, stored) and + fwdFlowOutValidEdge(_, ret, innercc, _, node, cc, allowsFieldFlow) and not inBarrier(node, state) and label = "" and if allowsFieldFlow = false then ap instanceof ApNil else any() From 262f64f03751b93fc4a4df52e252561a0bc3471f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 12:42:07 +0100 Subject: [PATCH 192/213] Dataflow: Remove unused columns. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 4db25288eeb4..564810f0951f 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1562,7 +1562,7 @@ module MakeImpl Lang> { or // flow through a callable exists(DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow | - fwdFlowThrough(call, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, _) and + fwdFlowThrough(call, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow) and not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -2098,10 +2098,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThrough( DataFlowCall call, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, - Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret, ApApprox innerArgApa + Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret ) { - fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, _, - innerArgApa) + fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, _, _) } pragma[nomagic] @@ -3136,10 +3135,10 @@ module MakeImpl Lang> { private predicate fwdFlowThroughStep0( DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret, - SummaryCtxSome innerSummaryCtx, ApApprox innerArgApa + SummaryCtxSome innerSummaryCtx ) { fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, - innerSummaryCtx, innerArgApa) + innerSummaryCtx, _) } bindingset[node, state, cc, summaryCtx, t, ap, stored] @@ -3165,14 +3164,14 @@ module MakeImpl Lang> { private predicate fwdFlowThroughStep1( PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, DataFlowCall call, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, - TypOption stored, RetNodeEx ret, ApApprox innerArgApa + TypOption stored, RetNodeEx ret ) { exists( FlowState state0, ArgNodeEx arg, SummaryCtxSome innerSummaryCtx, ParamNodeEx p, Typ innerArgT, Ap innerArgAp, TypOption innerArgStored | fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, - innerSummaryCtx, innerArgApa) and + innerSummaryCtx) and innerSummaryCtx = TSummaryCtxSome(p, state0, innerArgT, innerArgAp, innerArgStored) and pn1 = mkPathNode(arg, state0, cc, summaryCtx, innerArgT, innerArgAp, innerArgStored) and pn2 = @@ -3189,7 +3188,7 @@ module MakeImpl Lang> { ) { exists(DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow | fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, t, ap, _, stored, - ret, _) and + ret) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow) and not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() From 882a9857881a11180b253a95e61a552745925f74 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 12:43:24 +0100 Subject: [PATCH 193/213] Dataflow: Remove useless join. --- .../dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 564810f0951f..914a24dbe2f8 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2166,13 +2166,12 @@ module MakeImpl Lang> { private predicate flowThroughIntoCall( DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, Ap argAp, Ap ap ) { - exists(ApApprox argApa, Typ argT, TypOption argStored, boolean emptyArgAp | + exists(Typ argT, TypOption argStored, boolean emptyArgAp | returnFlowsThrough(_, _, _, _, pragma[only_bind_into](p), pragma[only_bind_into](argT), - pragma[only_bind_into](argAp), pragma[only_bind_into](argApa), - pragma[only_bind_into](argStored), ap) and + pragma[only_bind_into](argAp), _, pragma[only_bind_into](argStored), ap) and flowIntoCallApaTaken(call, _, pragma[only_bind_into](arg), p, emptyArgAp) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), - pragma[only_bind_into](argApa), pragma[only_bind_into](argStored)) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), _, + pragma[only_bind_into](argStored)) and if argAp instanceof ApNil then emptyArgAp = true else emptyArgAp = false ) } From a77adadd0179323fa33b376da00bdc349bb27a86 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 12:46:30 +0100 Subject: [PATCH 194/213] Dataflow: Remove more unused columns. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 914a24dbe2f8..6b24db3ea0c5 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2069,8 +2069,8 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowRetFromArg( - RetNodeEx ret, FlowState state, CcCall ccc, SummaryCtxSome summaryCtx, ApApprox argApa, - Typ t, Ap ap, ApApprox apa, TypOption stored + RetNodeEx ret, FlowState state, CcCall ccc, SummaryCtxSome summaryCtx, Typ t, Ap ap, + ApApprox apa, TypOption stored ) { exists(ReturnKindExt kind, ParamNodeEx p, Ap argAp | instanceofCcCall(ccc) and @@ -2080,7 +2080,6 @@ module MakeImpl Lang> { not outBarrier(ret, state) and kind = ret.getKind() and parameterFlowThroughAllowed(p, kind) and - argApa = getApprox(argAp) and PrevStage::returnMayFlowThrough(ret, kind) ) } @@ -2089,9 +2088,9 @@ module MakeImpl Lang> { private predicate fwdFlowThrough0( DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret, - SummaryCtxSome innerSummaryCtx, ApApprox innerArgApa + SummaryCtxSome innerSummaryCtx ) { - fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgApa, t, ap, apa, stored) and + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, t, ap, apa, stored) and fwdFlowIsEntered(call, arg, cc, ccc, summaryCtx, innerSummaryCtx) } @@ -2100,7 +2099,7 @@ module MakeImpl Lang> { DataFlowCall call, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret ) { - fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, _, _) + fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, _) } pragma[nomagic] @@ -2141,21 +2140,20 @@ module MakeImpl Lang> { pragma[nomagic] private predicate returnFlowsThrough0( - DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, - SummaryCtxSome innerSummaryCtx, ApApprox innerArgApa + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, RetNodeEx ret, + SummaryCtxSome innerSummaryCtx ) { - fwdFlowThrough0(call, _, _, state, ccc, _, _, ap, apa, _, ret, innerSummaryCtx, - innerArgApa) + fwdFlowThrough0(call, _, _, state, ccc, _, _, ap, _, _, ret, innerSummaryCtx) } pragma[nomagic] private predicate returnFlowsThrough( RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Typ argT, - Ap argAp, ApApprox argApa, TypOption argStored, Ap ap + Ap argAp, TypOption argStored, Ap ap ) { exists(DataFlowCall call, boolean allowsFieldFlow | - returnFlowsThrough0(call, state, ccc, ap, _, ret, - TSummaryCtxSome(p, _, argT, argAp, argStored), argApa) and + returnFlowsThrough0(call, state, ccc, ap, ret, + TSummaryCtxSome(p, _, argT, argAp, argStored)) and flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow) and pos = ret.getReturnPosition() and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -2168,7 +2166,7 @@ module MakeImpl Lang> { ) { exists(Typ argT, TypOption argStored, boolean emptyArgAp | returnFlowsThrough(_, _, _, _, pragma[only_bind_into](p), pragma[only_bind_into](argT), - pragma[only_bind_into](argAp), _, pragma[only_bind_into](argStored), ap) and + pragma[only_bind_into](argAp), pragma[only_bind_into](argStored), ap) and flowIntoCallApaTaken(call, _, pragma[only_bind_into](arg), p, emptyArgAp) and fwdFlow(arg, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), _, pragma[only_bind_into](argStored)) and @@ -2274,7 +2272,7 @@ module MakeImpl Lang> { // flow out of a callable exists(ReturnPosition pos | revFlowOut(_, node, pos, state, _, _, _, ap) and - if returnFlowsThrough(node, pos, state, _, _, _, _, _, _, ap) + if returnFlowsThrough(node, pos, state, _, _, _, _, _, ap) then ( returnCtx = TReturnCtxMaybeFlowThrough(pos) and returnAp = apSome(ap) @@ -2439,7 +2437,7 @@ module MakeImpl Lang> { ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | revFlowOut(call, ret, pos, state, returnCtx, _, returnAp, ap) and - returnFlowsThrough(ret, pos, state, ccc, _, _, _, _, _, ap) and + returnFlowsThrough(ret, pos, state, ccc, _, _, _, _, ap) and matchesCall(ccc, call) ) } @@ -2508,7 +2506,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate parameterMayFlowThroughAp(ParamNodeEx p, Ap ap) { exists(ReturnPosition pos | - returnFlowsThrough(_, pos, _, _, p, _, ap, _, _, _) and + returnFlowsThrough(_, pos, _, _, p, _, ap, _, _) and parameterFlowsThroughRev(p, ap, pos, _) ) } @@ -2545,7 +2543,7 @@ module MakeImpl Lang> { pragma[nomagic] predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind) { exists(ParamNodeEx p, ReturnPosition pos, Ap argAp, Ap ap | - returnFlowsThrough(ret, pos, _, _, p, _, argAp, _, _, ap) and + returnFlowsThrough(ret, pos, _, _, p, _, argAp, _, ap) and parameterFlowsThroughRev(p, argAp, pos, ap) and kind = pos.getKind() ) @@ -3133,11 +3131,11 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep0( DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, - SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret, + SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNodeEx ret, SummaryCtxSome innerSummaryCtx ) { - fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, - innerSummaryCtx, _) + fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, t, ap, _, stored, ret, + innerSummaryCtx) } bindingset[node, state, cc, summaryCtx, t, ap, stored] @@ -3162,14 +3160,14 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep1( PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, DataFlowCall call, Cc cc, - FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, - TypOption stored, RetNodeEx ret + FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, + RetNodeEx ret ) { exists( FlowState state0, ArgNodeEx arg, SummaryCtxSome innerSummaryCtx, ParamNodeEx p, Typ innerArgT, Ap innerArgAp, TypOption innerArgStored | - fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, + fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, t, ap, stored, ret, innerSummaryCtx) and innerSummaryCtx = TSummaryCtxSome(p, state0, innerArgT, innerArgAp, innerArgStored) and pn1 = mkPathNode(arg, state0, cc, summaryCtx, innerArgT, innerArgAp, innerArgStored) and @@ -3186,7 +3184,7 @@ module MakeImpl Lang> { FlowState state, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { exists(DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow | - fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, t, ap, _, stored, + fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, t, ap, stored, ret) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow) and not inBarrier(node, state) and From 22e0636cbad63262545f392b5f53f6ca64b74ce2 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 13:06:29 +0100 Subject: [PATCH 195/213] Dataflow: Insert a few getApprox calls to remove even more columns. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 6b24db3ea0c5..64630390fec5 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1545,7 +1545,8 @@ module MakeImpl Lang> { apa = getApprox(ap) or // flow into a callable without summary context - fwdFlowInNoFlowThrough(node, apa, state, cc, t, ap, stored) and + fwdFlowInNoFlowThrough(node, state, cc, t, ap, stored) and + apa = getApprox(ap) and summaryCtx = TSummaryCtxNone() and // When the call contexts of source and sink needs to match then there's // never any reason to enter a callable except to find a summary. See also @@ -1553,7 +1554,8 @@ module MakeImpl Lang> { not Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext or // flow into a callable with summary context (non-linear recursion) - fwdFlowInFlowThrough(node, apa, state, cc, t, ap, stored) and + fwdFlowInFlowThrough(node, state, cc, t, ap, stored) and + apa = getApprox(ap) and summaryCtx = TSummaryCtxSome(node, state, t, ap, stored) or // flow out of a callable @@ -1562,8 +1564,9 @@ module MakeImpl Lang> { or // flow through a callable exists(DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow | - fwdFlowThrough(call, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret) and + fwdFlowThrough(call, cc, state, ccc, summaryCtx, t, ap, stored, ret) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow) and + apa = getApprox(ap) and not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) @@ -1572,7 +1575,7 @@ module MakeImpl Lang> { private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, Typ t, Ap ap, TypOption stored) { - fwdFlowInFlowThrough(p, _, state, _, t, ap, stored) + fwdFlowInFlowThrough(p, state, _, t, ap, stored) } /** @@ -1823,11 +1826,10 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowInCandTypeFlowDisabled( DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, - ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, TypOption stored, - boolean cc + ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, boolean cc ) { not enableTypeFlow() and - fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, t, ap, _, apa, stored, cc) + fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, t, ap, _, _, stored, cc) } pragma[nomagic] @@ -1862,15 +1864,15 @@ module MakeImpl Lang> { predicate fwdFlowIn( DataFlowCall call, ArgNodeEx arg, DataFlowCallable inner, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, SummaryCtx summaryCtx, Typ t, Ap ap, - ApApprox apa, TypOption stored, boolean cc + TypOption stored, boolean cc ) { // type flow disabled: linear recursion fwdFlowInCandTypeFlowDisabled(call, arg, state, outercc, inner, p, summaryCtx, t, ap, - apa, stored, cc) and + stored, cc) and fwdFlowInValidEdgeTypeFlowDisabled(call, inner, innercc, pragma[only_bind_into](cc)) or // type flow enabled: non-linear recursion - exists(boolean emptyAp | + exists(boolean emptyAp, ApApprox apa | fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, stored, cc) and fwdFlowInValidEdgeTypeFlowEnabled(call, arg, outercc, inner, p, innercc, emptyAp, apa, cc) @@ -1884,10 +1886,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInNoFlowThrough( - ParamNodeEx p, ApApprox apa, FlowState state, CcCall innercc, Typ t, Ap ap, - TypOption stored + ParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, TypOption stored ) { - FwdFlowInNoThrough::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, apa, stored, _) + FwdFlowInNoThrough::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, stored, _) } private predicate top() { any() } @@ -1896,10 +1897,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInFlowThrough( - ParamNodeEx p, ApApprox apa, FlowState state, CcCall innercc, Typ t, Ap ap, - TypOption stored + ParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, TypOption stored ) { - FwdFlowInThrough::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, apa, stored, _) + FwdFlowInThrough::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, stored, _) } pragma[nomagic] @@ -1997,9 +1997,9 @@ module MakeImpl Lang> { DataFlowCall call, DataFlowCallable c, ParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, TypOption stored, boolean cc ) { - FwdFlowInNoThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, _, stored, cc) + FwdFlowInNoThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, stored, cc) or - FwdFlowInThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, _, stored, cc) + FwdFlowInThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, stored, cc) } pragma[nomagic] @@ -2070,11 +2070,11 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowRetFromArg( RetNodeEx ret, FlowState state, CcCall ccc, SummaryCtxSome summaryCtx, Typ t, Ap ap, - ApApprox apa, TypOption stored + TypOption stored ) { exists(ReturnKindExt kind, ParamNodeEx p, Ap argAp | instanceofCcCall(ccc) and - fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, apa, stored) and + fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, _, stored) and summaryCtx = TSummaryCtxSome(pragma[only_bind_into](p), _, _, pragma[only_bind_into](argAp), _) and not outBarrier(ret, state) and @@ -2087,19 +2087,19 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowThrough0( DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, - SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret, + SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNodeEx ret, SummaryCtxSome innerSummaryCtx ) { - fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, t, ap, apa, stored) and + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, t, ap, stored) and fwdFlowIsEntered(call, arg, cc, ccc, summaryCtx, innerSummaryCtx) } pragma[nomagic] private predicate fwdFlowThrough( DataFlowCall call, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, - Ap ap, ApApprox apa, TypOption stored, RetNodeEx ret + Ap ap, TypOption stored, RetNodeEx ret ) { - fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, apa, stored, ret, _) + fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, stored, ret, _) } pragma[nomagic] @@ -2107,7 +2107,7 @@ module MakeImpl Lang> { DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, ParamNodeEx p, FlowState state, Typ t, Ap ap, TypOption stored ) { - FwdFlowInThrough::fwdFlowIn(call, arg, _, p, state, cc, innerCc, summaryCtx, t, ap, _, + FwdFlowInThrough::fwdFlowIn(call, arg, _, p, state, cc, innerCc, summaryCtx, t, ap, stored, _) } @@ -2143,7 +2143,7 @@ module MakeImpl Lang> { DataFlowCall call, FlowState state, CcCall ccc, Ap ap, RetNodeEx ret, SummaryCtxSome innerSummaryCtx ) { - fwdFlowThrough0(call, _, _, state, ccc, _, _, ap, _, _, ret, innerSummaryCtx) + fwdFlowThrough0(call, _, _, state, ccc, _, _, ap, _, ret, innerSummaryCtx) } pragma[nomagic] @@ -3120,11 +3120,11 @@ module MakeImpl Lang> { SummaryCtx outerSummaryCtx, SummaryCtx innerSummaryCtx, Typ t, Ap ap, TypOption stored ) { FwdFlowInNoThrough::fwdFlowIn(_, arg, _, p, state, outercc, innercc, outerSummaryCtx, t, - ap, _, stored, _) and + ap, stored, _) and innerSummaryCtx = TSummaryCtxNone() or FwdFlowInThrough::fwdFlowIn(_, arg, _, p, state, outercc, innercc, outerSummaryCtx, t, - ap, _, stored, _) and + ap, stored, _) and innerSummaryCtx = TSummaryCtxSome(p, state, t, ap, stored) } @@ -3134,7 +3134,7 @@ module MakeImpl Lang> { SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNodeEx ret, SummaryCtxSome innerSummaryCtx ) { - fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, t, ap, _, stored, ret, + fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, t, ap, stored, ret, innerSummaryCtx) } From 501cbdab3c4e5bdbd6e417d4e5e369dfcfcb3657 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 13:12:32 +0100 Subject: [PATCH 196/213] Dataflow: Remove another ApApprox join and related columns. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 64630390fec5..20ead18e692b 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1717,9 +1717,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowIntoArg( ArgNodeEx arg, FlowState state, Cc outercc, SummaryCtx summaryCtx, Typ t, Ap ap, - boolean emptyAp, ApApprox apa, TypOption stored, boolean cc + boolean emptyAp, TypOption stored, boolean cc ) { - fwdFlow(arg, state, outercc, summaryCtx, t, ap, apa, stored) and + fwdFlow(arg, state, outercc, summaryCtx, t, ap, _, stored) and (if instanceofCcCall(outercc) then cc = true else cc = false) and if ap instanceof ApNil then emptyAp = true else emptyAp = false } @@ -1809,10 +1809,10 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowInCand( DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, - ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, boolean emptyAp, ApApprox apa, - TypOption stored, boolean cc + ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, boolean emptyAp, TypOption stored, + boolean cc ) { - fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, stored, cc) and + fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, stored, cc) and ( inner = viableImplCallContextReducedInlineLate(call, arg, outercc) or @@ -1829,16 +1829,16 @@ module MakeImpl Lang> { ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, boolean cc ) { not enableTypeFlow() and - fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, t, ap, _, _, stored, cc) + fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, t, ap, _, stored, cc) } pragma[nomagic] private predicate fwdFlowInCandTypeFlowEnabled( DataFlowCall call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, - boolean emptyAp, ApApprox apa, boolean cc + boolean emptyAp, boolean cc ) { enableTypeFlow() and - fwdFlowInCand(call, arg, _, outercc, inner, p, _, _, _, emptyAp, apa, _, cc) + fwdFlowInCand(call, arg, _, outercc, inner, p, _, _, _, emptyAp, _, cc) } pragma[nomagic] @@ -1853,9 +1853,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInValidEdgeTypeFlowEnabled( DataFlowCall call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, - CcCall innercc, boolean emptyAp, ApApprox apa, boolean cc + CcCall innercc, boolean emptyAp, boolean cc ) { - fwdFlowInCandTypeFlowEnabled(call, arg, outercc, inner, p, emptyAp, apa, cc) and + fwdFlowInCandTypeFlowEnabled(call, arg, outercc, inner, p, emptyAp, cc) and FwdTypeFlow::typeFlowValidEdgeIn(call, inner, cc) and innercc = getCallContextCall(call, inner) } @@ -1872,10 +1872,9 @@ module MakeImpl Lang> { fwdFlowInValidEdgeTypeFlowDisabled(call, inner, innercc, pragma[only_bind_into](cc)) or // type flow enabled: non-linear recursion - exists(boolean emptyAp, ApApprox apa | - fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, stored, cc) and - fwdFlowInValidEdgeTypeFlowEnabled(call, arg, outercc, inner, p, innercc, emptyAp, apa, - cc) + exists(boolean emptyAp | + fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, stored, cc) and + fwdFlowInValidEdgeTypeFlowEnabled(call, arg, outercc, inner, p, innercc, emptyAp, cc) ) } } From 231bf9d1c9e0fdf0c30300112501fe8a882a5591 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 13:20:27 +0100 Subject: [PATCH 197/213] Dataflow: Drop ApApprox join in fwdFlowStore. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 20ead18e692b..426c6200e907 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -877,13 +877,11 @@ module MakeImpl Lang> { pragma[nomagic] predicate storeStepCand( - NodeEx node1, Ap ap1, Content c, NodeEx node2, DataFlowType contentType, - DataFlowType containerType + NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType ) { revFlowIsReadAndStored(c) and revFlow(node2) and - store(node1, c, node2, contentType, containerType) and - exists(ap1) + store(node1, c, node2, contentType, containerType) } pragma[nomagic] @@ -1292,8 +1290,7 @@ module MakeImpl Lang> { predicate returnMayFlowThrough(RetNodeEx ret, ReturnKindExt kind); predicate storeStepCand( - NodeEx node1, Ap ap1, Content c, NodeEx node2, DataFlowType contentType, - DataFlowType containerType + NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType ); predicate readStepCand(NodeEx n1, Content c, NodeEx n2); @@ -1451,7 +1448,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate compatibleContainer0(ApHeadContent apc, DataFlowType containerType) { exists(DataFlowType containerType0, Content c | - PrevStage::storeStepCand(_, _, c, _, _, containerType0) and + PrevStage::storeStepCand(_, c, _, _, containerType0) and not isTopType(containerType0) and compatibleTypesCached(containerType0, containerType) and apc = projectToHeadContent(c) @@ -1461,7 +1458,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate topTypeContent(ApHeadContent apc) { exists(DataFlowType containerType0, Content c | - PrevStage::storeStepCand(_, _, c, _, _, containerType0) and + PrevStage::storeStepCand(_, c, _, _, containerType0) and isTopType(containerType0) and apc = projectToHeadContent(c) ) @@ -1646,11 +1643,11 @@ module MakeImpl Lang> { NodeEx node1, Typ t1, Ap ap1, TypOption stored1, Content c, Typ t2, TypOption stored2, NodeEx node2, FlowState state, Cc cc, SummaryCtx summaryCtx ) { - exists(DataFlowType contentType, DataFlowType containerType, ApApprox apa1 | - fwdFlow(node1, state, cc, summaryCtx, t1, ap1, apa1, stored1) and + exists(DataFlowType contentType, DataFlowType containerType | + fwdFlow(node1, state, cc, summaryCtx, t1, ap1, _, stored1) and not outBarrier(node1, state) and not inBarrier(node2, state) and - PrevStage::storeStepCand(node1, apa1, c, node2, contentType, containerType) and + PrevStage::storeStepCand(node1, c, node2, contentType, containerType) and t2 = getTyp(containerType) and // We need to typecheck stores here, since reverse flow through a getter // might have a different type here compared to inside the getter. @@ -2443,11 +2440,11 @@ module MakeImpl Lang> { pragma[nomagic] predicate storeStepCand( - NodeEx node1, Ap ap1, Content c, NodeEx node2, DataFlowType contentType, + NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType ) { - exists(Ap ap2 | - PrevStage::storeStepCand(node1, _, c, node2, contentType, containerType) and + exists(Ap ap2, Ap ap1 | + PrevStage::storeStepCand(node1, c, node2, contentType, containerType) and revFlowStore(ap2, c, ap1, node1, _, node2, _, _) and revFlowConsCand(ap2, c, ap1) ) @@ -2664,7 +2661,7 @@ module MakeImpl Lang> { or node instanceof OutNodeEx or - storeStepCand(_, _, _, node, _, _) + storeStepCand(_, _, node, _, _) or readStepCand(_, _, node) or @@ -2698,7 +2695,7 @@ module MakeImpl Lang> { callEdgeReturn(_, _, node, _, next, _) and apNext = ap or - storeStepCand(node, _, _, next, _, _) + storeStepCand(node, _, next, _, _) or readStepCand(node, _, next) ) @@ -3950,7 +3947,7 @@ module MakeImpl Lang> { PrevStage::readStepCand(_, pragma[only_bind_into](c), _) and c = cs.getAReadContent() and clearSet(node, cs) and - if PrevStage::storeStepCand(_, _, _, node, _, _) + if PrevStage::storeStepCand(_, _, node, _, _) then isStoreTarget = true else isStoreTarget = false ) From 4e155f8542c4dcfb4216d078c34e6f69fabd52f5 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 13:23:51 +0100 Subject: [PATCH 198/213] Dataflow: Insert a few getApprox calls to remove ApApprox from fwdFlow. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 85 ++++++++++--------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 426c6200e907..56bf55307042 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1479,26 +1479,27 @@ module MakeImpl Lang> { */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, - TypOption stored + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { - fwdFlow1(node, state, cc, summaryCtx, _, t, ap, apa, stored) + fwdFlow1(node, state, cc, summaryCtx, _, t, ap, stored) } private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t0, Typ t, Ap ap, - ApApprox apa, TypOption stored + TypOption stored ) { - fwdFlow0(node, state, cc, summaryCtx, t0, ap, apa, stored) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t0, ap, t) and - ( - if node instanceof CastingNodeEx - then - ap instanceof ApNil or - compatibleContainer(getHeadContent(ap), node.getDataFlowType()) or - topTypeContent(getHeadContent(ap)) - else any() + exists(ApApprox apa | + fwdFlow0(node, state, cc, summaryCtx, t0, ap, apa, stored) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) and + ( + if node instanceof CastingNodeEx + then + ap instanceof ApNil or + compatibleContainer(getHeadContent(ap), node.getDataFlowType()) or + topTypeContent(getHeadContent(ap)) + else any() + ) ) } @@ -1516,7 +1517,8 @@ module MakeImpl Lang> { stored.isNone() or exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | - fwdFlow(mid, state0, cc, summaryCtx, t0, ap, apa, stored) and + fwdFlow(mid, state0, cc, summaryCtx, t0, ap, stored) and + apa = getApprox(ap) and localCc = getLocalCc(cc) | localStep(mid, state0, node, state, true, _, localCc, _) and @@ -1526,7 +1528,8 @@ module MakeImpl Lang> { ap instanceof ApNil ) or - fwdFlowJump(node, state, t, ap, apa, stored) and + fwdFlowJump(node, state, t, ap, stored) and + apa = getApprox(ap) and cc = ccNone() and summaryCtx = TSummaryCtxNone() or @@ -1615,23 +1618,21 @@ module MakeImpl Lang> { override Location getLocation() { result = p.getLocation() } } - private predicate fwdFlowJump( - NodeEx node, FlowState state, Typ t, Ap ap, ApApprox apa, TypOption stored - ) { + private predicate fwdFlowJump(NodeEx node, FlowState state, Typ t, Ap ap, TypOption stored) { exists(NodeEx mid | - fwdFlow(mid, state, _, _, t, ap, apa, stored) and + fwdFlow(mid, state, _, _, t, ap, stored) and jumpStepEx(mid, node) ) or exists(NodeEx mid | - fwdFlow(mid, state, _, _, _, ap, apa, stored) and + fwdFlow(mid, state, _, _, _, ap, stored) and additionalJumpStep(mid, node, _) and t = getNodeTyp(node) and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0 | - fwdFlow(mid, state0, _, _, _, ap, apa, stored) and + fwdFlow(mid, state0, _, _, _, ap, stored) and additionalJumpStateStep(mid, state0, node, state, _) and t = getNodeTyp(node) and ap instanceof ApNil @@ -1644,7 +1645,7 @@ module MakeImpl Lang> { NodeEx node2, FlowState state, Cc cc, SummaryCtx summaryCtx ) { exists(DataFlowType contentType, DataFlowType containerType | - fwdFlow(node1, state, cc, summaryCtx, t1, ap1, _, stored1) and + fwdFlow(node1, state, cc, summaryCtx, t1, ap1, stored1) and not outBarrier(node1, state) and not inBarrier(node2, state) and PrevStage::storeStepCand(node1, c, node2, contentType, containerType) and @@ -1685,7 +1686,7 @@ module MakeImpl Lang> { Cc cc, SummaryCtx summaryCtx ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, t, ap, _, stored) and + fwdFlow(node1, state, cc, summaryCtx, t, ap, stored) and not outBarrier(node1, state) and not inBarrier(node2, state) and apc = getHeadContent(ap) and @@ -1716,7 +1717,7 @@ module MakeImpl Lang> { ArgNodeEx arg, FlowState state, Cc outercc, SummaryCtx summaryCtx, Typ t, Ap ap, boolean emptyAp, TypOption stored, boolean cc ) { - fwdFlow(arg, state, outercc, summaryCtx, t, ap, _, stored) and + fwdFlow(arg, state, outercc, summaryCtx, t, ap, stored) and (if instanceofCcCall(outercc) then cc = true else cc = false) and if ap instanceof ApNil then emptyAp = true else emptyAp = false } @@ -1940,7 +1941,7 @@ module MakeImpl Lang> { ) { instanceofCcNoCall(cc) and not outBarrier(ret, state) and - fwdFlow(ret, state, cc, summaryCtx, t, ap, _, stored) + fwdFlow(ret, state, cc, summaryCtx, t, ap, stored) } pragma[nomagic] @@ -2003,7 +2004,7 @@ module MakeImpl Lang> { ParamNodeEx p, FlowState state, CcCall cc, Typ t0, Ap ap, TypOption stored ) { instanceofCcCall(cc) and - fwdFlow1(p, state, cc, _, t0, _, ap, _, stored) + fwdFlow1(p, state, cc, _, t0, _, ap, stored) } pragma[nomagic] @@ -2026,7 +2027,7 @@ module MakeImpl Lang> { private predicate fwdFlow1Out( NodeEx node, FlowState state, Cc cc, Typ t0, Ap ap, TypOption stored ) { - fwdFlow1(node, state, cc, _, t0, _, ap, _, stored) and + fwdFlow1(node, state, cc, _, t0, _, ap, stored) and PrevStage::callEdgeReturn(_, _, _, _, node, _) } @@ -2048,7 +2049,7 @@ module MakeImpl Lang> { or exists(NodeEx node | cc = false and - fwdFlowJump(node, _, _, _, _, _) and + fwdFlowJump(node, _, _, _, _) and c = node.getEnclosingCallable() ) } @@ -2070,7 +2071,7 @@ module MakeImpl Lang> { ) { exists(ReturnKindExt kind, ParamNodeEx p, Ap argAp | instanceofCcCall(ccc) and - fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, _, stored) and + fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, stored) and summaryCtx = TSummaryCtxSome(pragma[only_bind_into](p), _, _, pragma[only_bind_into](argAp), _) and not outBarrier(ret, state) and @@ -2164,7 +2165,7 @@ module MakeImpl Lang> { returnFlowsThrough(_, _, _, _, pragma[only_bind_into](p), pragma[only_bind_into](argT), pragma[only_bind_into](argAp), pragma[only_bind_into](argStored), ap) and flowIntoCallApaTaken(call, _, pragma[only_bind_into](arg), p, emptyArgAp) and - fwdFlow(arg, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), _, + fwdFlow(arg, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), pragma[only_bind_into](argStored)) and if argAp instanceof ApNil then emptyArgAp = true else emptyArgAp = false ) @@ -2176,7 +2177,7 @@ module MakeImpl Lang> { ) { exists(boolean emptyAp | flowIntoCallApaTaken(call, c, arg, p, emptyAp) and - fwdFlow(arg, _, _, _, _, ap, _, _) and + fwdFlow(arg, _, _, _, _, ap, _) and if ap instanceof ApNil then emptyAp = true else emptyAp = false ) } @@ -2187,7 +2188,7 @@ module MakeImpl Lang> { Ap ap, boolean allowsFieldFlow ) { PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) and - fwdFlow(ret, _, _, _, _, ap, _, _) and + fwdFlow(ret, _, _, _, _, ap, _) and pos = ret.getReturnPosition() and (if allowsFieldFlow = false then ap instanceof ApNil else any()) and ( @@ -2210,14 +2211,14 @@ module MakeImpl Lang> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, ap, _, _) + fwdFlow(node, state, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, ap, _, _) and + fwdFlow(node, state, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -2345,7 +2346,7 @@ module MakeImpl Lang> { predicate dataFlowNonCallEntry(DataFlowCallable c, boolean cc) { exists(NodeEx node, FlowState state, ApNil nil | - fwdFlow(node, state, _, _, _, nil, _, _) and + fwdFlow(node, state, _, _, _, nil, _) and sinkNode(node, state) and (if hasSinkCallCtx() then cc = true else cc = false) and c = node.getEnclosingCallable() @@ -2520,7 +2521,7 @@ module MakeImpl Lang> { exists(Ap ap0 | parameterMayFlowThrough(p, _) and revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, ap0) and - fwdFlow(n, state, any(CcCall ccc), TSummaryCtxSome(p, _, _, ap, _), _, ap0, _, _) + fwdFlow(n, state, any(CcCall ccc), TSummaryCtxSome(p, _, _, ap, _), _, ap0, _) ) } @@ -2812,7 +2813,7 @@ module MakeImpl Lang> { NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { - fwdFlow(node, state, cc, summaryCtx, t, ap, _, stored) and + fwdFlow(node, state, cc, summaryCtx, t, ap, stored) and revFlow(node, state, _, _, ap) } or TPathNodeSink(NodeEx node, FlowState state) { @@ -3148,7 +3149,7 @@ module MakeImpl Lang> { TypOption stored ) { exists(Typ t | - fwdFlow1(node, state, cc, summaryCtx, t0, t, ap, _, stored) and + fwdFlow1(node, state, cc, summaryCtx, t0, t, ap, stored) and result = TPathNodeMid(node, state, cc, summaryCtx, t, ap, stored) ) } @@ -3598,13 +3599,13 @@ module MakeImpl Lang> { int tfnodes, int tftuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _)) and conscand = count(Content f0, Ap ap | fwdConsCand(f0, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, - TypOption stored | fwdFlow(n, state, cc, summaryCtx, t, ap, _, stored)) and + TypOption stored | fwdFlow(n, state, cc, summaryCtx, t, ap, stored)) and calledges = count(DataFlowCall call, DataFlowCallable c | FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or From 40f77136787ab75491b604b9e6a7bfaa2b1f6f00 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 13:28:43 +0100 Subject: [PATCH 199/213] Dataflow: Minor simplification. --- shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 56bf55307042..6ead5b719065 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2043,7 +2043,7 @@ module MakeImpl Lang> { exists(NodeEx node, FlowState state | sourceNode(node, state) and (if hasSourceCallCtx() then cc = true else cc = false) and - PrevStage::revFlow(node, state, getApprox(any(ApNil nil))) and + PrevStage::revFlow(node, state, any(PrevStage::ApNil nil)) and c = node.getEnclosingCallable() ) or From da179705c393598d6c15d57b5a266b397e3232ac Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 10 Dec 2024 14:52:06 +0100 Subject: [PATCH 200/213] Java: Accept expected file changes. --- .../test/library-tests/dataflow/capture/inlinetest.expected | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/test/library-tests/dataflow/capture/inlinetest.expected b/java/ql/test/library-tests/dataflow/capture/inlinetest.expected index d127b92ddafa..a336577503f2 100644 --- a/java/ql/test/library-tests/dataflow/capture/inlinetest.expected +++ b/java/ql/test/library-tests/dataflow/capture/inlinetest.expected @@ -171,10 +171,12 @@ edges | B.java:154:17:154:28 | source(...) : String | B.java:175:5:175:6 | String s2 : String | provenance | | | B.java:158:7:158:13 | parameter this : MyLocal [String s1] : String | B.java:159:18:159:19 | this : MyLocal [String s1] : String | provenance | | | B.java:158:7:158:13 | parameter this : MyLocal [String s2] : String | B.java:160:14:160:15 | this : MyLocal [String s2] : String | provenance | | +| B.java:158:7:158:13 | parameter this : MyLocal [String s2] : String | B.java:160:14:160:15 | this : MyLocal [String s2] : String | provenance | | | B.java:159:9:159:12 | this [post update] : MyLocal [f] : String | B.java:158:7:158:13 | parameter this [Return] : MyLocal [f] : String | provenance | | | B.java:159:18:159:19 | s1 : String | B.java:159:9:159:12 | this [post update] : MyLocal [f] : String | provenance | | | B.java:159:18:159:19 | this : MyLocal [String s1] : String | B.java:159:18:159:19 | s1 : String | provenance | | | B.java:160:14:160:15 | this : MyLocal [String s2] : String | B.java:160:14:160:15 | s2 | provenance | | +| B.java:160:14:160:15 | this : MyLocal [String s2] : String | B.java:160:14:160:15 | s2 | provenance | | | B.java:162:12:162:15 | parameter this : MyLocal [String s2] : String | B.java:164:14:164:15 | this : MyLocal [String s2] : String | provenance | | | B.java:162:12:162:15 | parameter this : MyLocal [f] : String | B.java:163:14:163:14 | this <.field> : MyLocal [f] : String | provenance | | | B.java:163:14:163:14 | this <.field> : MyLocal [f] : String | B.java:163:14:163:14 | f | provenance | | @@ -464,12 +466,14 @@ nodes | B.java:154:17:154:28 | source(...) : String | semmle.label | source(...) : String | | B.java:158:7:158:13 | parameter this : MyLocal [String s1] : String | semmle.label | parameter this : MyLocal [String s1] : String | | B.java:158:7:158:13 | parameter this : MyLocal [String s2] : String | semmle.label | parameter this : MyLocal [String s2] : String | +| B.java:158:7:158:13 | parameter this : MyLocal [String s2] : String | semmle.label | parameter this : MyLocal [String s2] : String | | B.java:158:7:158:13 | parameter this [Return] : MyLocal [f] : String | semmle.label | parameter this [Return] : MyLocal [f] : String | | B.java:159:9:159:12 | this [post update] : MyLocal [f] : String | semmle.label | this [post update] : MyLocal [f] : String | | B.java:159:18:159:19 | s1 : String | semmle.label | s1 : String | | B.java:159:18:159:19 | this : MyLocal [String s1] : String | semmle.label | this : MyLocal [String s1] : String | | B.java:160:14:160:15 | s2 | semmle.label | s2 | | B.java:160:14:160:15 | this : MyLocal [String s2] : String | semmle.label | this : MyLocal [String s2] : String | +| B.java:160:14:160:15 | this : MyLocal [String s2] : String | semmle.label | this : MyLocal [String s2] : String | | B.java:162:12:162:15 | parameter this : MyLocal [String s2] : String | semmle.label | parameter this : MyLocal [String s2] : String | | B.java:162:12:162:15 | parameter this : MyLocal [f] : String | semmle.label | parameter this : MyLocal [f] : String | | B.java:163:14:163:14 | f | semmle.label | f | From 0f3dd6d8f112484556e4ce15c0da5c72bce1696b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 12 Nov 2024 17:01:51 +0000 Subject: [PATCH 201/213] Java: IPA the CFG --- java/ql/consistency-queries/cfgDeadEnds.ql | 14 +- .../lib/semmle/code/java/ControlFlowGraph.qll | 303 +++++++++++------- java/ql/lib/semmle/code/java/Expr.qll | 4 +- java/ql/lib/semmle/code/java/Statement.qll | 4 +- .../code/java/controlflow/BasicBlocks.qll | 5 + .../code/java/controlflow/Dominance.qll | 21 +- .../semmle/code/java/controlflow/Guards.qll | 6 +- .../semmle/code/java/controlflow/Paths.qll | 14 +- .../java/controlflow/UnreachableBlocks.qll | 12 +- .../code/java/dataflow/InstanceAccess.qll | 8 +- .../semmle/code/java/dataflow/Nullness.qll | 24 +- .../code/java/dataflow/RangeAnalysis.qll | 6 +- java/ql/lib/semmle/code/java/dataflow/SSA.qll | 35 +- .../semmle/code/java/dataflow/TypeFlow.qll | 4 +- .../code/java/dataflow/internal/BaseSSA.qll | 19 +- .../dataflow/internal/DataFlowPrivate.qll | 2 +- .../java/dataflow/internal/DataFlowUtil.qll | 6 +- .../rangeanalysis/ModulusAnalysisSpecific.qll | 2 +- .../rangeanalysis/SignAnalysisSpecific.qll | 2 +- .../rangeanalysis/SsaReadPositionSpecific.qll | 6 +- .../code/java/frameworks/Assertions.qll | 8 +- .../code/java/metrics/MetricCallable.qll | 6 +- .../code/java/security/PathSanitizer.qll | 10 +- .../semmle/code/java/security/Validation.qll | 2 +- .../Comparison/UselessComparisonTest.qll | 2 +- .../DoubleCheckedLockingWithInitRace.ql | 2 +- .../Concurrency/LazyInitStaticField.ql | 4 +- .../Likely Bugs/Concurrency/UnreleasedLock.ql | 14 +- .../Termination/ConstantLoopCondition.ql | 4 +- .../CWE/CWE-833/LockOrderInconsistency.ql | 4 +- .../Declarations/BreakInSwitchCase.ql | 2 +- .../Declarations/Common.qll | 6 +- .../CWE/CWE-094/SpringViewManipulationLib.qll | 2 +- .../controlflow/basic/bbStmts.expected | 4 +- .../controlflow/basic/bbStmts.ql | 2 +- .../basic/bbStrictDominance.expected | 4 +- .../controlflow/basic/bbSuccessor.expected | 4 +- .../controlflow/basic/strictDominance.ql | 2 +- .../controlflow/basic/strictPostDominance.ql | 2 +- .../controlflow/dominance/dominanceBad.ql | 4 +- .../controlflow/dominance/dominanceWrong.ql | 2 +- .../controlflow/dominance/dominatedByStart.ql | 6 +- .../controlflow/dominance/dominator.expected | 4 +- .../controlflow/dominance/dominatorExists.ql | 4 +- .../library-tests/controlflow/paths/paths.ql | 2 +- .../MultiCatch/MultiCatchControlFlow.expected | 10 +- .../pattern-instanceof/cfg.expected | 14 +- .../library-tests/pattern-instanceof/cfg.ql | 2 +- .../pattern-switch/cfg/test.expected | 22 +- .../library-tests/pattern-switch/cfg/test.ql | 2 +- .../CloseReaderTest/TestSucc.expected | 6 +- .../successors/CloseReaderTest/TestSucc.ql | 2 +- .../LoopVarReadTest/TestSucc.expected | 4 +- .../successors/LoopVarReadTest/TestSucc.ql | 2 +- .../successors/SaveFileTest/TestSucc.expected | 6 +- .../successors/SaveFileTest/TestSucc.ql | 2 +- .../successors/SchackTest/TestSucc.expected | 12 +- .../successors/SchackTest/TestSucc.ql | 2 +- .../successors/TestBreak/TestSucc.expected | 8 +- .../successors/TestBreak/TestSucc.ql | 2 +- .../TestContinue/FalseSuccessors.expected | 2 +- .../successors/TestContinue/TestSucc.expected | 6 +- .../successors/TestContinue/TestSucc.ql | 2 +- .../TestDeclarations/TestSucc.expected | 6 +- .../successors/TestDeclarations/TestSucc.ql | 2 +- .../successors/TestFinally/TestSucc.expected | 10 +- .../successors/TestFinally/TestSucc.ql | 2 +- .../TestSucc.expected | 6 +- .../TestFinallyBreakContinue/TestSucc.ql | 2 +- .../TestLoopBranch/TestSucc.expected | 14 +- .../successors/TestLoopBranch/TestSucc.ql | 2 +- .../successors/TestThrow/TestSucc.expected | 18 +- .../successors/TestThrow/TestSucc.ql | 2 +- .../successors/TestThrow2/TestSucc.expected | 6 +- .../successors/TestThrow2/TestSucc.ql | 2 +- .../successors/TestTryCatch/TestSucc.expected | 6 +- .../successors/TestTryCatch/TestSucc.ql | 2 +- .../TestTryWithResources/TestSucc.expected | 4 +- .../TestTryWithResources/TestSucc.ql | 2 +- 79 files changed, 451 insertions(+), 344 deletions(-) diff --git a/java/ql/consistency-queries/cfgDeadEnds.ql b/java/ql/consistency-queries/cfgDeadEnds.ql index 73c30015a6fc..817d8e858c63 100644 --- a/java/ql/consistency-queries/cfgDeadEnds.ql +++ b/java/ql/consistency-queries/cfgDeadEnds.ql @@ -1,7 +1,6 @@ import java -import semmle.code.java.ControlFlowGraph -predicate shouldBeDeadEnd(ControlFlowNode n) { +predicate shouldBeDeadEnd(ExprParent n) { n instanceof BreakStmt and n.getFile().isKotlinSourceFile() // TODO or n instanceof Interface // TODO @@ -55,8 +54,11 @@ predicate shouldBeDeadEnd(ControlFlowNode n) { n = any(ConstCase c).getValue(_) // TODO } -from ControlFlowNode n, string s +from ControlFlowNode n, ExprParent astnode, string s where - // TODO: exists(n.getASuccessor()) and shouldBeDeadEnd(n) and s = "expected dead end" - not exists(n.getASuccessor()) and not shouldBeDeadEnd(n) and s = "unexpected dead end" -select n, n.getPrimaryQlClasses(), s + astnode = n.getAstNode() and + // TODO: exists(n.getASuccessor()) and shouldBeDeadEnd(n.getAstNode()) and s = "expected dead end" + not exists(n.getASuccessor()) and + not shouldBeDeadEnd(astnode) and + s = "unexpected dead end" +select n, astnode.getPrimaryQlClasses(), s diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index f8e94dc76844..26fae3c4108c 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -4,7 +4,7 @@ * The only API exported by this library are the toplevel classes `ControlFlowNode` * and its subclass `ConditionNode`, which wrap the successor relation and the * concept of true- and false-successors of conditions. A cfg node may either be a - * statement, an expression, or the enclosing callable, indicating that + * statement, an expression, or an exit node for a callable, indicating that * execution of the callable terminates. */ @@ -84,45 +84,122 @@ private import Completion private import controlflow.internal.Preconditions private import controlflow.internal.SwitchCases -/** A node in the expression-level control-flow graph. */ -class ControlFlowNode extends Top, @exprparent { - /** Gets the statement containing this node, if any. */ - Stmt getEnclosingStmt() { - result = this or - result = this.(Expr).getEnclosingStmt() +/** Provides the definition of control flow nodes. */ +module ControlFlow { + private predicate hasControlFlow(Expr e) { + not exists(ConstCase cc | e = cc.getValue(_)) and + not e.getParent*() instanceof Annotation and + not e instanceof TypeAccess and + not e instanceof ArrayTypeAccess and + not e instanceof UnionTypeAccess and + not e instanceof IntersectionTypeAccess and + not e instanceof WildcardTypeAccess and + not exists(AssignExpr ae | ae.getDest() = e) } - /** Gets the immediately enclosing callable whose body contains this node. */ - Callable getEnclosingCallable() { - result = this or - result = this.(Stmt).getEnclosingCallable() or - result = this.(Expr).getEnclosingCallable() - } + private newtype TNode = + TExprNode(Expr e) { hasControlFlow(e) } or + TStmtNode(Stmt s) or + TExitNode(Callable c) { exists(c.getBody()) } + + /** A node in the expression-level control-flow graph. */ + class Node extends TNode { + /** Gets the statement containing this node, if any. */ + Stmt getEnclosingStmt() { + result = this.asStmt() or + result = this.asExpr().getEnclosingStmt() + } + + /** Gets the immediately enclosing callable whose body contains this node. */ + Callable getEnclosingCallable() { + this = TExitNode(result) or + result = this.asStmt().getEnclosingCallable() or + result = this.asExpr().getEnclosingCallable() + } + + /** Gets the statement this `Node` corresponds to, if any. */ + Stmt asStmt() { this = TStmtNode(result) } + + /** Gets the expression this `Node` corresponds to, if any. */ + Expr asExpr() { this = TExprNode(result) } + + /** Gets the call this `Node` corresponds to, if any. */ + Call asCall() { + result = this.asExpr() or + result = this.asStmt() + } - /** Gets an immediate successor of this node. */ - ControlFlowNode getASuccessor() { result = succ(this) } + /** Gets an immediate successor of this node. */ + Node getASuccessor() { result = succ(this) } - /** Gets an immediate predecessor of this node. */ - ControlFlowNode getAPredecessor() { this = succ(result) } + /** Gets an immediate predecessor of this node. */ + Node getAPredecessor() { this = succ(result) } - /** Gets an exception successor of this node. */ - ControlFlowNode getAnExceptionSuccessor() { result = succ(this, ThrowCompletion(_)) } + /** Gets an exception successor of this node. */ + Node getAnExceptionSuccessor() { result = succ(this, ThrowCompletion(_)) } + + /** Gets a successor of this node that is neither an exception successor nor a jump (break, continue, return). */ + Node getANormalSuccessor() { + result = succ(this, BooleanCompletion(_, _)) or + result = succ(this, NormalCompletion()) + } + + /** Gets the basic block that contains this node. */ + BasicBlock getBasicBlock() { result.getANode() = this } + + /** Gets a textual representation of this element. */ + string toString() { + result = this.asExpr().toString() + or + result = this.asStmt().toString() + or + result = "Exit" and this instanceof ExitNode + } + + /** Gets the source location for this element. */ + Location getLocation() { + result = this.asExpr().getLocation() or + result = this.asStmt().getLocation() or + result = this.(ExitNode).getEnclosingCallable().getLocation() + } - /** Gets a successor of this node that is neither an exception successor nor a jump (break, continue, return). */ - ControlFlowNode getANormalSuccessor() { - result = succ(this, BooleanCompletion(_, _)) or - result = succ(this, NormalCompletion()) + /** + * Get the most appropriate AST node for this control flow node, if any. + * + * This is needed for the equivalence relation on basic blocks in range + * analysis. + */ + ExprParent getAstNode() { + result = this.asExpr() or + result = this.asStmt() or + this = TExitNode(result) + } } - /** Gets the basic block that contains this node. */ - BasicBlock getBasicBlock() { result.getANode() = this } + /** A synthetic node for the exit of a callable. */ + class ExitNode extends Node, TExitNode { } } +class ControlFlowNode = ControlFlow::Node; + /** Gets the intra-procedural successor of `n`. */ private ControlFlowNode succ(ControlFlowNode n) { result = succ(n, _) } cached private module ControlFlowGraphImpl { + private import ControlFlow + + private class AstNode extends ExprParent { + AstNode() { this instanceof Expr or this instanceof Stmt } + + Stmt getEnclosingStmt() { + result = this or + result = this.(Expr).getEnclosingStmt() + } + + Node getCFGNode() { result.asExpr() = this or result.asStmt() = this } + } + /** * Gets a label that applies to this statement. */ @@ -167,7 +244,7 @@ private module ControlFlowGraphImpl { * `ClassCastException` is expected, or because it is a Kotlin not-null check * and a `NullPointerException` is expected. */ - private predicate mayThrow(ControlFlowNode n, ThrowableType t) { + private predicate mayThrow(AstNode n, ThrowableType t) { t = n.(ThrowStmt).getThrownExceptionType() or exists(Call c | c = n | @@ -200,7 +277,7 @@ private module ControlFlowGraphImpl { * Bind `t` to an unchecked exception that may transfer control to a finally * block inside which `n` is nested. */ - private predicate uncheckedExceptionFromFinally(ControlFlowNode n, ThrowableType t) { + private predicate uncheckedExceptionFromFinally(AstNode n, ThrowableType t) { exists(TryStmt try | n.getEnclosingStmt().getEnclosingStmt+() = try.getBlock() or n.(Expr).getParent*() = try.getAResource() @@ -214,7 +291,7 @@ private module ControlFlowGraphImpl { * Bind `t` to all unchecked exceptions that may be caught by some * `try-catch` inside which `n` is nested. */ - private predicate uncheckedExceptionFromCatch(ControlFlowNode n, ThrowableType t) { + private predicate uncheckedExceptionFromCatch(AstNode n, ThrowableType t) { exists(TryStmt try, UncheckedThrowableSuperType caught | n.getEnclosingStmt().getEnclosingStmt+() = try.getBlock() or n.(Expr).getParent*() = try.getAResource() @@ -229,7 +306,7 @@ private module ControlFlowGraphImpl { * body or the resources (if any) of `try`. */ private ThrowableType thrownInBody(TryStmt try) { - exists(ControlFlowNode n | mayThrow(n, result) | + exists(AstNode n | mayThrow(n, result) | n.getEnclosingStmt().getEnclosingStmt+() = try.getBlock() or n.(Expr).getParent*() = try.getAResource() ) @@ -287,7 +364,7 @@ private module ControlFlowGraphImpl { * That is, contexts where the control-flow edges depend on `value` given that `b` ends * with a `booleanCompletion(value, _)`. */ - private predicate inBooleanContext(ControlFlowNode b) { + private predicate inBooleanContext(AstNode b) { exists(LogicExpr logexpr | logexpr.(BinaryExpr).getLeftOperand() = b or @@ -493,9 +570,7 @@ private module ControlFlowGraphImpl { * immediately before either falling through to execute successor statements or execute a rule body * if present. `completion` is the completion kind of the last operation. */ - private predicate lastPatternCaseMatchingOp( - PatternCase pc, ControlFlowNode last, Completion completion - ) { + private predicate lastPatternCaseMatchingOp(PatternCase pc, Node last, Completion completion) { last(pc.getAPattern(), last, completion) and completion = NormalCompletion() and not exists(pc.getGuard()) @@ -514,7 +589,7 @@ private module ControlFlowGraphImpl { * and `ThrowStmt`. CFG nodes without child nodes in the CFG that may complete * normally are also included. */ - private class PostOrderNode extends ControlFlowNode { + private class PostOrderNode extends AstNode { PostOrderNode() { // For VarAccess and ArrayAccess only read accesses (r-values) are included, // as write accesses aren't included in the CFG. @@ -576,7 +651,7 @@ private module ControlFlowGraphImpl { } /** Gets child nodes in their order of execution. Indexing starts at either -1 or 0. */ - ControlFlowNode getChildNode(int index) { + AstNode getChildNode(int index) { exists(ArrayAccess e | e = this | index = 0 and result = e.getArray() or @@ -649,7 +724,7 @@ private module ControlFlowGraphImpl { } /** Gets the first child node, if any. */ - ControlFlowNode firstChild() { + AstNode firstChild() { result = this.getChildNode(-1) or result = this.getChildNode(0) and not exists(this.getChildNode(-1)) @@ -687,18 +762,18 @@ private module ControlFlowGraphImpl { /** * Determine the part of the AST node `n` that will be executed first. */ - private ControlFlowNode first(ControlFlowNode n) { - result = n and n instanceof LogicExpr + private Node first(AstNode n) { + result.asExpr() = n and n instanceof LogicExpr or - result = n and n instanceof ConditionalExpr + result.asExpr() = n and n instanceof ConditionalExpr or - result = n and n instanceof WhenExpr + result.asExpr() = n and n instanceof WhenExpr or - result = n and n instanceof WhenBranch + result.asStmt() = n and n instanceof WhenBranch or - result = n and n instanceof StmtExpr + result.asExpr() = n and n instanceof StmtExpr or - result = n and n.(PostOrderNode).isLeafNode() + result = n.getCFGNode() and n.(PostOrderNode).isLeafNode() or result = first(n.(PostOrderNode).firstChild()) or @@ -706,12 +781,11 @@ private module ControlFlowGraphImpl { or result = first(n.(SynchronizedStmt).getExpr()) or - result = n and - n instanceof Stmt and + result.asStmt() = n and not n instanceof PostOrderNode and not n instanceof SynchronizedStmt or - result = n and n instanceof SwitchExpr + result.asExpr() = n and n instanceof SwitchExpr } /** @@ -722,9 +796,7 @@ private module ControlFlowGraphImpl { * node in the `try` block that may not complete normally, or a node in * the `try` block that has no control flow successors inside the block. */ - private predicate catchOrFinallyCompletion( - TryStmt try, ControlFlowNode last, Completion completion - ) { + private predicate catchOrFinallyCompletion(TryStmt try, Node last, Completion completion) { last(try.getBlock(), last, completion) or last(try.getAResource(), last, completion) and completion = ThrowCompletion(_) @@ -737,7 +809,7 @@ private module ControlFlowGraphImpl { * In other words, if `last` throws an exception it is possibly not caught by any * of the catch clauses. */ - private predicate uncaught(TryStmt try, ControlFlowNode last, Completion completion) { + private predicate uncaught(TryStmt try, Node last, Completion completion) { catchOrFinallyCompletion(try, last, completion) and ( exists(ThrowableType thrown | @@ -767,12 +839,12 @@ private module ControlFlowGraphImpl { * This is similar to `uncaught`, but also includes final statements of `catch` * clauses. */ - private predicate finallyPred(TryStmt try, ControlFlowNode last, Completion completion) { + private predicate finallyPred(TryStmt try, Node last, Completion completion) { uncaught(try, last, completion) or last(try.getACatchClause(), last, completion) } - private predicate lastInFinally(TryStmt try, ControlFlowNode last) { + private predicate lastInFinally(TryStmt try, Node last) { last(try.getFinally(), last, NormalCompletion()) } @@ -796,7 +868,7 @@ private module ControlFlowGraphImpl { * A `booleanCompletion` implies that `n` is an `Expr`. Any abnormal * completion besides `throwCompletion` implies that `n` is a `Stmt`. */ - private predicate last(ControlFlowNode n, ControlFlowNode last, Completion completion) { + private predicate last(AstNode n, Node last, Completion completion) { // Exceptions are propagated from any sub-expression. // As are any break, yield, continue, or return completions. exists(Expr e | e.getParent() = n | @@ -853,15 +925,18 @@ private module ControlFlowGraphImpl { ) or exists(InstanceOfExpr ioe | ioe.isPattern() and ioe = n | - last = n and completion = basicBooleanCompletion(false) + last.asExpr() = n and completion = basicBooleanCompletion(false) or last(ioe.getPattern(), last, NormalCompletion()) and completion = basicBooleanCompletion(true) ) or // The last node of a node executed in post-order is the node itself. - n.(PostOrderNode).mayCompleteNormally() and last = n and completion = NormalCompletion() + // n.(PostOrderNode).mayCompleteNormally() and last = n and completion = NormalCompletion() + exists(PostOrderNode p | p = n | + p.mayCompleteNormally() and last = p.getCFGNode() and completion = NormalCompletion() + ) or - last = n and completion = basicBooleanCompletion(n.(BooleanLiteral).getBooleanValue()) + last.asExpr() = n and completion = basicBooleanCompletion(n.(BooleanLiteral).getBooleanValue()) or // The last statement in a block is any statement that does not complete normally, // or the last statement. @@ -997,7 +1072,7 @@ private module ControlFlowGraphImpl { // * On success of its guard test, if it is not a rule (boolean true) // (the latter two cases are accounted for by lastPatternCaseMatchingOp) exists(PatternCase pc | n = pc | - last = pc and completion = basicBooleanCompletion(false) + last.asStmt() = pc and completion = basicBooleanCompletion(false) or last(pc.getGuard(), last, completion) and completion = BooleanCompletion(false, _) @@ -1010,13 +1085,15 @@ private module ControlFlowGraphImpl { last(n.(SynchronizedStmt).getBlock(), last, completion) or // `return` statements give rise to a `Return` completion - last = n.(ReturnStmt) and completion = ReturnCompletion() + last.asStmt() = n.(ReturnStmt) and completion = ReturnCompletion() or // `throw` statements or throwing calls give rise to ` Throw` completion - exists(ThrowableType tt | mayThrow(n, tt) | last = n and completion = ThrowCompletion(tt)) + exists(ThrowableType tt | mayThrow(n, tt) | + last = n.getCFGNode() and completion = ThrowCompletion(tt) + ) or // `break` statements give rise to a `Break` completion - exists(BreakStmt break | break = n and last = n | + exists(BreakStmt break | break = n and last.asStmt() = n | completion = labelledBreakCompletion(MkLabel(break.getLabel())) or not exists(break.getLabel()) and completion = anonymousBreakCompletion() @@ -1031,7 +1108,7 @@ private module ControlFlowGraphImpl { ) or // `continue` statements give rise to a `Continue` completion - exists(ContinueStmt cont | cont = n and last = n | + exists(ContinueStmt cont | cont = n and last.asStmt() = n | completion = labelledContinueCompletion(MkLabel(cont.getLabel())) or not exists(cont.getLabel()) and completion = anonymousContinueCompletion() @@ -1067,7 +1144,7 @@ private module ControlFlowGraphImpl { // the last node of the condition of the last branch in the absence of an else-branch. exists(WhenExpr whenexpr | whenexpr = n | // If we have no branches then we are the last node - last = n and + last.asExpr() = n and completion = NormalCompletion() and not exists(whenexpr.getBranch(_)) or @@ -1117,17 +1194,19 @@ private module ControlFlowGraphImpl { * execution finishes with the given completion. */ cached - ControlFlowNode succ(ControlFlowNode n, Completion completion) { - // Callables serve as their own exit nodes. - exists(Callable c | last(c.getBody(), n, completion) | result = c) + Node succ(Node n, Completion completion) { + // The successor of a callable is its exit node. + exists(Callable c | last(c.getBody(), n, completion) | + result.(ExitNode).getEnclosingCallable() = c + ) or // Logic expressions and conditional expressions execute in AST pre-order. completion = NormalCompletion() and ( - result = first(n.(AndLogicalExpr).getLeftOperand()) or - result = first(n.(OrLogicalExpr).getLeftOperand()) or - result = first(n.(LogNotExpr).getExpr()) or - result = first(n.(ConditionalExpr).getCondition()) + result = first(n.asExpr().(AndLogicalExpr).getLeftOperand()) or + result = first(n.asExpr().(OrLogicalExpr).getLeftOperand()) or + result = first(n.asExpr().(LogNotExpr).getExpr()) or + result = first(n.asExpr().(ConditionalExpr).getCondition()) ) or // If a logic expression doesn't short-circuit then control flows from its left operand to its right. @@ -1151,9 +1230,11 @@ private module ControlFlowGraphImpl { ) or exists(InstanceOfExpr ioe | ioe.isPattern() | - last(ioe.getExpr(), n, completion) and completion = NormalCompletion() and result = ioe + last(ioe.getExpr(), n, completion) and + completion = NormalCompletion() and + result.asExpr() = ioe or - n = ioe and + n.asExpr() = ioe and result = first(ioe.getPattern()) and completion = basicBooleanCompletion(true) ) @@ -1164,11 +1245,11 @@ private module ControlFlowGraphImpl { | result = first(p.getChildNode(i + 1)) or - not exists(p.getChildNode(i + 1)) and result = p + not exists(p.getChildNode(i + 1)) and result = p.getCFGNode() ) or // Statements within a block execute sequentially. - result = first(n.(BlockStmt).getStmt(0)) and completion = NormalCompletion() + result = first(n.asStmt().(BlockStmt).getStmt(0)) and completion = NormalCompletion() or exists(BlockStmt blk, int i | last(blk.getStmt(i), n, completion) and @@ -1178,7 +1259,7 @@ private module ControlFlowGraphImpl { or // Control flows to the corresponding branch depending on the boolean completion of the condition. exists(IfStmt s | - n = s and result = first(s.getCondition()) and completion = NormalCompletion() + n.asStmt() = s and result = first(s.getCondition()) and completion = NormalCompletion() or last(s.getCondition(), n, completion) and completion = BooleanCompletion(true, _) and @@ -1190,7 +1271,7 @@ private module ControlFlowGraphImpl { ) or // For statements: - exists(ForStmt for, ControlFlowNode condentry | + exists(ForStmt for, Node condentry | // Any part of the control flow that aims for the condition needs to hit either the condition... condentry = first(for.getCondition()) or @@ -1198,10 +1279,10 @@ private module ControlFlowGraphImpl { not exists(for.getCondition()) and condentry = first(for.getStmt()) | // From the entry point, which is the for statement itself, control goes to either the first init expression... - n = for and result = first(for.getInit(0)) and completion = NormalCompletion() + n.asStmt() = for and result = first(for.getInit(0)) and completion = NormalCompletion() or // ...or the condition if the for doesn't include init expressions. - n = for and + n.asStmt() = for and not exists(for.getAnInit()) and result = condentry and completion = NormalCompletion() @@ -1238,27 +1319,29 @@ private module ControlFlowGraphImpl { // Enhanced for statements: exists(EnhancedForStmt for | // First the expression gets evaluated... - n = for and result = first(for.getExpr()) and completion = NormalCompletion() + n.asStmt() = for and result = first(for.getExpr()) and completion = NormalCompletion() or // ...then the variable gets assigned... last(for.getExpr(), n, completion) and completion = NormalCompletion() and - result = for.getVariable() + result.asExpr() = for.getVariable() or // ...and then control goes to the body of the loop. - n = for.getVariable() and result = first(for.getStmt()) and completion = NormalCompletion() + n.asExpr() = for.getVariable() and + result = first(for.getStmt()) and + completion = NormalCompletion() or // Finally, the back edge of the loop goes to reassign the variable. last(for.getStmt(), n, completion) and continues(completion, for) and - result = for.getVariable() + result.asExpr() = for.getVariable() ) or // While loops start at the condition... - result = first(n.(WhileStmt).getCondition()) and completion = NormalCompletion() + result = first(n.asStmt().(WhileStmt).getCondition()) and completion = NormalCompletion() or // ...and do-while loops start at the body. - result = first(n.(DoStmt).getStmt()) and completion = NormalCompletion() + result = first(n.asStmt().(DoStmt).getStmt()) and completion = NormalCompletion() or exists(LoopStmt loop | loop instanceof WhileStmt or loop instanceof DoStmt | // Control goes from the condition via a true-completion to the body... @@ -1282,7 +1365,7 @@ private module ControlFlowGraphImpl { ) or // After the last resource declaration, control transfers to the body. - exists(TryStmt try | n = try and completion = NormalCompletion() | + exists(TryStmt try | n.asStmt() = try and completion = NormalCompletion() | result = first(try.getResource(0)) or not exists(try.getAResource()) and result = first(try.getBlock()) @@ -1310,7 +1393,7 @@ private module ControlFlowGraphImpl { or // Catch clauses first assign their variable and then execute their block exists(CatchClause cc | completion = NormalCompletion() | - n = cc and result = first(cc.getVariable()) + n.asStmt() = cc and result = first(cc.getVariable()) or last(cc.getVariable(), n, completion) and result = first(cc.getBlock()) ) @@ -1321,7 +1404,9 @@ private module ControlFlowGraphImpl { switchExpr = switch.(SwitchStmt).getExpr() or switchExpr = switch.(SwitchExpr).getExpr() | // From the entry point control is transferred first to the expression... - n = switch and result = first(switchExpr) and completion = NormalCompletion() + (n.asStmt() = switch or n.asExpr() = switch) and + result = first(switchExpr) and + completion = NormalCompletion() or // ...and then to any case up to and including the first pattern case, if any. last(switchExpr, n, completion) and @@ -1345,7 +1430,7 @@ private module ControlFlowGraphImpl { or // A pattern case that completes boolean false (type test or guard failure) continues to consider other cases: exists(PatternCase case | completion = BooleanCompletion(false, _) | - last(case, n, completion) and result = getASuccessorSwitchCase(case, switch) + last(case, n, completion) and result.asStmt() = getASuccessorSwitchCase(case, switch) ) ) or @@ -1358,7 +1443,7 @@ private module ControlFlowGraphImpl { // * Variable declarations -normal-> rule execution (when there is no guard) // * Guard success -true-> rule execution exists(PatternCase pc | - n = pc and + n.asStmt() = pc and completion = basicBooleanCompletion(true) and result = first(pc.getAPattern()) or @@ -1375,7 +1460,7 @@ private module ControlFlowGraphImpl { ) or // Non-pattern cases have an internal edge leading to their rule body if any when the case matches. - exists(SwitchCase case | n = case | + exists(SwitchCase case | n.asStmt() = case | not case instanceof PatternCase and completion = NormalCompletion() and ( @@ -1387,32 +1472,32 @@ private module ControlFlowGraphImpl { or // Yield exists(YieldStmt yield | completion = NormalCompletion() | - n = yield and result = first(yield.getValue()) + n.asStmt() = yield and result = first(yield.getValue()) ) or // Synchronized statements execute their expression _before_ synchronization, so the CFG reflects that. exists(SynchronizedStmt synch | completion = NormalCompletion() | - last(synch.getExpr(), n, completion) and result = synch + last(synch.getExpr(), n, completion) and result.asStmt() = synch or - n = synch and result = first(synch.getBlock()) + n.asStmt() = synch and result = first(synch.getBlock()) ) or - result = first(n.(ExprStmt).getExpr()) and completion = NormalCompletion() + result = first(n.asStmt().(ExprStmt).getExpr()) and completion = NormalCompletion() or - result = first(n.(StmtExpr).getStmt()) and completion = NormalCompletion() + result = first(n.asExpr().(StmtExpr).getStmt()) and completion = NormalCompletion() or - result = first(n.(LabeledStmt).getStmt()) and completion = NormalCompletion() + result = first(n.asStmt().(LabeledStmt).getStmt()) and completion = NormalCompletion() or // Variable declarations in a variable declaration statement are executed sequentially. exists(LocalVariableDeclStmt s | completion = NormalCompletion() | - n = s and result = first(s.getVariable(1)) + n.asStmt() = s and result = first(s.getVariable(1)) or exists(int i | last(s.getVariable(i), n, completion) and result = first(s.getVariable(i + 1))) ) or // When expressions: exists(WhenExpr whenexpr | - n = whenexpr and + n.asExpr() = whenexpr and result = first(whenexpr.getBranch(0)) and completion = NormalCompletion() or @@ -1425,7 +1510,7 @@ private module ControlFlowGraphImpl { or // When branches: exists(WhenBranch whenbranch | - n = whenbranch and + n.asStmt() = whenbranch and completion = NormalCompletion() and result = first(whenbranch.getCondition()) or @@ -1463,7 +1548,7 @@ private module ControlFlowGraphImpl { * predicate `finallyPred`, since their completion is resumed after normal * completion of the `finally`. */ - private Completion resumption(ControlFlowNode n) { + private Completion resumption(Node n) { exists(TryStmt try | lastInFinally(try, n) and finallyPred(try, _, result)) or not lastInFinally(_, n) and result = NormalCompletion() @@ -1474,9 +1559,7 @@ private module ControlFlowGraphImpl { * * That is, the `booleanCompletion` is the label of the edge in the CFG. */ - private ControlFlowNode mainBranchSucc(ControlFlowNode n, boolean b) { - result = succ(n, BooleanCompletion(_, b)) - } + private Node mainBranchSucc(Node n, boolean b) { result = succ(n, BooleanCompletion(_, b)) } /** * A true- or false-successor that is not tagged with a `booleanCompletion`. @@ -1487,8 +1570,8 @@ private module ControlFlowGraphImpl { * In the latter case, when `n` occurs as the last node in a finally block, there might be * multiple different such successors. */ - private ControlFlowNode otherBranchSucc(ControlFlowNode n, boolean b) { - exists(ControlFlowNode main | main = mainBranchSucc(n, b.booleanNot()) | + private Node otherBranchSucc(Node n, boolean b) { + exists(Node main | main = mainBranchSucc(n, b.booleanNot()) | result = succ(n, resumption(n)) and not result = main and (b = true or b = false) @@ -1497,7 +1580,7 @@ private module ControlFlowGraphImpl { /** Gets a true- or false-successor of `n`. */ cached - ControlFlowNode branchSuccessor(ControlFlowNode n, boolean branch) { + Node branchSuccessor(Node n, boolean branch) { result = mainBranchSucc(n, branch) or result = otherBranchSucc(n, branch) } @@ -1506,18 +1589,18 @@ private module ControlFlowGraphImpl { private import ControlFlowGraphImpl /** A control-flow node that branches based on a condition. */ -class ConditionNode extends ControlFlowNode { +class ConditionNode extends ControlFlow::Node { ConditionNode() { exists(branchSuccessor(this, _)) } /** Gets a true- or false-successor of the `ConditionNode`. */ - ControlFlowNode getABranchSuccessor(boolean branch) { result = branchSuccessor(this, branch) } + ControlFlow::Node getABranchSuccessor(boolean branch) { result = branchSuccessor(this, branch) } /** Gets a true-successor of the `ConditionNode`. */ - ControlFlowNode getATrueSuccessor() { result = this.getABranchSuccessor(true) } + ControlFlow::Node getATrueSuccessor() { result = this.getABranchSuccessor(true) } /** Gets a false-successor of the `ConditionNode`. */ - ControlFlowNode getAFalseSuccessor() { result = this.getABranchSuccessor(false) } + ControlFlow::Node getAFalseSuccessor() { result = this.getABranchSuccessor(false) } /** Gets the condition of this `ConditionNode`. This is equal to the node itself. */ - ExprParent getCondition() { result = this } + ExprParent getCondition() { result = this.asExpr() or result = this.asStmt() } } diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 1862319e30bb..24e5a6e24d8b 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -61,10 +61,10 @@ class Expr extends ExprParent, @expr { Expr getAChildExpr() { exprs(result, _, _, this, _) } /** Gets the basic block in which this expression occurs, if any. */ - BasicBlock getBasicBlock() { result.getANode() = this } + BasicBlock getBasicBlock() { result.getANode().asExpr() = this } /** Gets the `ControlFlowNode` corresponding to this expression. */ - ControlFlowNode getControlFlowNode() { result = this } + ControlFlowNode getControlFlowNode() { result.asExpr() = this } /** This statement's Halstead ID (used to compute Halstead metrics). */ string getHalsteadID() { result = this.toString() } diff --git a/java/ql/lib/semmle/code/java/Statement.qll b/java/ql/lib/semmle/code/java/Statement.qll index f4eafd39e9ff..da9621f9ce3a 100644 --- a/java/ql/lib/semmle/code/java/Statement.qll +++ b/java/ql/lib/semmle/code/java/Statement.qll @@ -45,10 +45,10 @@ class Stmt extends StmtParent, ExprParent, @stmt { Stmt getAChild() { result.getParent() = this } /** Gets the basic block in which this statement occurs. */ - BasicBlock getBasicBlock() { result.getANode() = this } + BasicBlock getBasicBlock() { result.getANode().asStmt() = this } /** Gets the `ControlFlowNode` corresponding to this statement. */ - ControlFlowNode getControlFlowNode() { result = this } + ControlFlowNode getControlFlowNode() { result.asStmt() = this } /** Cast this statement to a class that provides access to metrics information. */ MetricStmt getMetrics() { result = this } diff --git a/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll b/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll index 3fae0f0b4d27..972f97ba3674 100644 --- a/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll +++ b/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll @@ -66,3 +66,8 @@ class BasicBlock extends ControlFlowNode { /** Holds if this basic block post-dominates `node`. (This is reflexive.) */ predicate bbPostDominates(BasicBlock node) { bbPostDominates(this, node) } } + +/** A basic block that ends in an exit node. */ +class ExitBlock extends BasicBlock { + ExitBlock() { this.getLastNode() instanceof ControlFlow::ExitNode } +} diff --git a/java/ql/lib/semmle/code/java/controlflow/Dominance.qll b/java/ql/lib/semmle/code/java/controlflow/Dominance.qll index a1263ce3f0eb..953bfa12e640 100644 --- a/java/ql/lib/semmle/code/java/controlflow/Dominance.qll +++ b/java/ql/lib/semmle/code/java/controlflow/Dominance.qll @@ -9,13 +9,15 @@ import java */ /** Entry points for control-flow. */ -private predicate flowEntry(Stmt entry) { - exists(Callable c | entry = c.getBody()) - or - // This disjunct is technically superfluous, but safeguards against extractor problems. - entry instanceof BlockStmt and - not exists(entry.getEnclosingCallable()) and - not entry.getParent() instanceof Stmt +private predicate flowEntry(BasicBlock entry) { + exists(Stmt entrystmt | entrystmt = entry.getFirstNode().asStmt() | + exists(Callable c | entrystmt = c.getBody()) + or + // This disjunct is technically superfluous, but safeguards against extractor problems. + entrystmt instanceof BlockStmt and + not exists(entry.getEnclosingCallable()) and + not entrystmt.getParent() instanceof Stmt + ) } /** The successor relation for basic blocks. */ @@ -31,11 +33,8 @@ predicate hasDominanceInformation(BasicBlock bb) { exists(BasicBlock entry | flowEntry(entry) and bbSucc*(entry, bb)) } -/** Exit points for control-flow. */ -private predicate flowExit(Callable exit) { exists(ControlFlowNode s | s.getASuccessor() = exit) } - /** Exit points for basic-block control-flow. */ -private predicate bbSink(BasicBlock exit) { flowExit(exit.getLastNode()) } +private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode } /** Reversed `bbSucc`. */ private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getABBSuccessor() } diff --git a/java/ql/lib/semmle/code/java/controlflow/Guards.qll b/java/ql/lib/semmle/code/java/controlflow/Guards.qll index 0d0ecd5b2ea4..ff564b3a4469 100644 --- a/java/ql/lib/semmle/code/java/controlflow/Guards.qll +++ b/java/ql/lib/semmle/code/java/controlflow/Guards.qll @@ -113,7 +113,7 @@ private PatternCase getClosestPrecedingPatternCase(SwitchCase case) { private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pred) { pred = sc.getControlFlowNode().getAPredecessor() and ( - pred.(Expr).getParent*() = sc.getSelectorExpr() + pred.asExpr().getParent*() = sc.getSelectorExpr() or // Ambiguous: in the case of `case String _ when x: case "SomeConstant":`, the guard `x` // passing edge will fall through into the constant case, and the guard failing edge @@ -122,7 +122,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre exists(PatternCase previousPatternCase | previousPatternCase = getClosestPrecedingPatternCase(sc) | - pred.(Expr).getParent*() = previousPatternCase.getGuard() and + pred.asExpr().getParent*() = previousPatternCase.getGuard() and // Check there is any statement in between the previous pattern case and this one, // or the case is a rule, so there is no chance of a fall-through. ( @@ -133,7 +133,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre or // Unambigious: on the test-passing edge there must be at least one intervening // declaration node, including anonymous `_` declarations. - pred = getClosestPrecedingPatternCase(sc) + pred.asStmt() = getClosestPrecedingPatternCase(sc) ) } diff --git a/java/ql/lib/semmle/code/java/controlflow/Paths.qll b/java/ql/lib/semmle/code/java/controlflow/Paths.qll index b4e9a68b280e..5a06a3a1ee5d 100644 --- a/java/ql/lib/semmle/code/java/controlflow/Paths.qll +++ b/java/ql/lib/semmle/code/java/controlflow/Paths.qll @@ -32,7 +32,7 @@ abstract class ActionConfiguration extends string { private BasicBlock actionBlock(ActionConfiguration conf) { exists(ControlFlowNode node | result = node.getBasicBlock() | conf.isAction(node) or - callAlwaysPerformsAction(node, conf) + callAlwaysPerformsAction(node.asCall(), conf) ) } @@ -45,17 +45,17 @@ private predicate callAlwaysPerformsAction(Call call, ActionConfiguration conf) /** Holds if an action dominates the exit of the callable. */ private predicate actionDominatesExit(Callable callable, ActionConfiguration conf) { - exists(BasicBlock exit | - exit.getLastNode() = callable and + exists(ExitBlock exit | + exit.getEnclosingCallable() = callable and actionBlock(conf).bbDominates(exit) ) } /** Gets a `BasicBlock` that contains an action that does not dominate the exit. */ private BasicBlock nonDominatingActionBlock(ActionConfiguration conf) { - exists(BasicBlock exit | + exists(ExitBlock exit | result = actionBlock(conf) and - exit.getLastNode() = result.getEnclosingCallable() and + exit.getEnclosingCallable() = result.getEnclosingCallable() and not result.bbDominates(exit) ) } @@ -80,8 +80,8 @@ private predicate postActionBlock(BasicBlock bb, ActionConfiguration conf) { private predicate callableAlwaysPerformsAction(Callable callable, ActionConfiguration conf) { actionDominatesExit(callable, conf) or - exists(BasicBlock exit | - exit.getLastNode() = callable and + exists(ExitBlock exit | + exit.getEnclosingCallable() = callable and postActionBlock(exit, conf) ) } diff --git a/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll b/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll index f34ace10d314..7bcc732de6a0 100644 --- a/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll +++ b/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll @@ -207,14 +207,12 @@ class UnreachableBasicBlock extends BasicBlock { conditionBlock.controls(this, constant.booleanNot()) ) or - // This block is not reachable in the CFG, and is not a callable, a body of a callable, an - // expression in an annotation, an expression in an assert statement, or a catch clause. + // This block is not reachable in the CFG, and is not the entrypoint in a callable, an + // expression in an assert statement, or a catch clause. forall(BasicBlock bb | bb = this.getABBPredecessor() | bb instanceof UnreachableBasicBlock) and - not exists(Callable c | c.getBody() = this) and - not this instanceof Callable and - not exists(Annotation a | a.getAChildExpr*() = this) and - not this.(Expr).getEnclosingStmt() instanceof AssertStmt and - not this instanceof CatchClause + not exists(Callable c | c.getBody().getControlFlowNode() = this.getFirstNode()) and + not this.getFirstNode().asExpr().getEnclosingStmt() instanceof AssertStmt and + not this.getFirstNode().asStmt() instanceof CatchClause or // Switch statements with a constant comparison expression may have unreachable cases. exists(ConstSwitchStmt constSwitchStmt, BasicBlock unreachableCaseBlock | diff --git a/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll b/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll index 18bdb879c3cb..0bae1b5e9c10 100644 --- a/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll +++ b/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll @@ -227,12 +227,14 @@ class InstanceAccessExt extends TInstanceAccessExt { /** Gets the control flow node associated with this instance access. */ ControlFlowNode getCfgNode() { exists(ExprParent e | e = this.getAssociatedExprOrStmt() | - e instanceof Call and result = e + result.asCall() = e or - e instanceof InstanceAccess and result = e + e.(InstanceAccess).getControlFlowNode() = result or exists(FieldAccess fa | fa = e | - if fa instanceof VarRead then fa = result else result.(AssignExpr).getDest() = fa + if fa instanceof VarRead + then fa.getControlFlowNode() = result + else result.asExpr().(AssignExpr).getDest() = fa ) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll index fb2fc668cf3a..618716629b10 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll @@ -130,8 +130,8 @@ predicate dereference(Expr e) { * The `VarAccess` is included for nicer error reporting. */ private ControlFlowNode varDereference(SsaVariable v, VarAccess va) { - dereference(result) and - result = sameValue(v, va) + dereference(result.asExpr()) and + result.asExpr() = sameValue(v, va) } /** @@ -141,16 +141,16 @@ private ControlFlowNode varDereference(SsaVariable v, VarAccess va) { private ControlFlowNode ensureNotNull(SsaVariable v) { result = varDereference(v, _) or - result.(AssertStmt).getExpr() = nullGuard(v, true, false) + result.asStmt().(AssertStmt).getExpr() = nullGuard(v, true, false) or - exists(AssertTrueMethod m | result = m.getACheck(nullGuard(v, true, false))) + exists(AssertTrueMethod m | result.asCall() = m.getACheck(nullGuard(v, true, false))) or - exists(AssertFalseMethod m | result = m.getACheck(nullGuard(v, false, false))) + exists(AssertFalseMethod m | result.asCall() = m.getACheck(nullGuard(v, false, false))) or - exists(AssertNotNullMethod m | result = m.getACheck(v.getAUse())) + exists(AssertNotNullMethod m | result.asCall() = m.getACheck(v.getAUse())) or exists(AssertThatMethod m, MethodCall ma | - result = m.getACheck(v.getAUse()) and ma.getControlFlowNode() = result + result.asCall() = m.getACheck(v.getAUse()) and ma.getControlFlowNode() = result | ma.getAnArgument().(MethodCall).getMethod().getName() = "notNullValue" ) @@ -279,10 +279,10 @@ private predicate enhancedForEarlyExit(EnhancedForStmt for, ControlFlowNode n1, exists(Expr forExpr | n1.getANormalSuccessor() = n2 and for.getExpr() = forExpr and - forExpr.getAChildExpr*() = n1 and - not forExpr.getAChildExpr*() = n2 and - n1.getANormalSuccessor() = for.getVariable() and - not n2 = for.getVariable() + forExpr.getAChildExpr*() = n1.asExpr() and + not forExpr.getAChildExpr*() = n2.asExpr() and + n1.getANormalSuccessor().asExpr() = for.getVariable() and + not n2.asExpr() = for.getVariable() ) } @@ -343,7 +343,7 @@ private predicate nullVarStep( not impossibleEdge(mid, bb) and not exists(boolean branch | nullGuard(midssa, branch, false).hasBranchEdge(mid, bb, branch)) and not (leavingFinally(mid, bb, true) and midstoredcompletion = true) and - if bb.getFirstNode() = any(TryStmt try | | try.getFinally()) + if bb.getFirstNode().asStmt() = any(TryStmt try | | try.getFinally()) then if bb.getFirstNode() = mid.getLastNode().getANormalSuccessor() then storedcompletion = false diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll index e0055d53f08d..c950963b104a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll +++ b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll @@ -211,9 +211,11 @@ module Sem implements Semantic { BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() } - private predicate id(BasicBlock x, BasicBlock y) { x = y } + private predicate id(ExprParent x, ExprParent y) { x = y } - private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y) + private predicate idOfAst(ExprParent x, int y) = equivalenceRelation(id/2)(x, y) + + private predicate idOf(BasicBlock x, int y) { idOfAst(x.getAstNode(), y) } int getBlockId1(BasicBlock bb) { idOf(bb, result) } diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll index 0fc0da8e8715..ce58e7d58dc1 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll @@ -228,7 +228,7 @@ private module SsaImpl { /** Holds if `n` must update the locally tracked variable `v`. */ cached predicate certainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) { - exists(VariableUpdate a | a = n | getDestVar(a) = v) and + exists(VariableUpdate a | a.getControlFlowNode() = n | getDestVar(a) = v) and b.getNode(i) = n and hasDominanceInformation(b) or @@ -237,8 +237,8 @@ private module SsaImpl { /** Gets the definition point of a nested class in the parent scope. */ private ControlFlowNode parentDef(NestedClass nc) { - nc.(AnonymousClass).getClassInstanceExpr() = result or - nc.(LocalClass).getLocalTypeDeclStmt() = result + nc.(AnonymousClass).getClassInstanceExpr().getControlFlowNode() = result or + nc.(LocalClass).getLocalTypeDeclStmt().getControlFlowNode() = result } /** @@ -276,7 +276,7 @@ private module SsaImpl { /** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */ private predicate variableUse(TrackedVar v, VarRead use, BasicBlock b, int i) { - v.getAnAccess() = use and b.getNode(i) = use + v.getAnAccess() = use and b.getNode(i) = use.getControlFlowNode() } /** Holds if the value of `v` is captured in `b` at index `i`. */ @@ -423,7 +423,7 @@ private module SsaImpl { * `f` has an update somewhere. */ private predicate updateCandidate(TrackedField f, Call call, BasicBlock b, int i) { - b.getNode(i) = call and + b.getNode(i).asCall() = call and call.getEnclosingCallable() = f.getEnclosingCallable() and relevantFieldUpdate(_, f.getField(), _) } @@ -550,7 +550,7 @@ private module SsaImpl { /** Holds if `n` might update the locally tracked variable `v`. */ cached predicate uncertainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) { - exists(Call c | c = n | updatesNamedField(c, v, _)) and + exists(Call c | c = n.asCall() | updatesNamedField(c, v, _)) and b.getNode(i) = n and hasDominanceInformation(b) or @@ -574,12 +574,16 @@ private module SsaImpl { /** Holds if `v` has an implicit definition at the entry, `b`, of the callable. */ cached predicate hasEntryDef(TrackedVar v, BasicBlock b) { - exists(LocalScopeVariable l, Callable c | v = TLocalVar(c, l) and c.getBody() = b | + exists(LocalScopeVariable l, Callable c | + v = TLocalVar(c, l) and c.getBody().getControlFlowNode() = b + | l instanceof Parameter or l.getCallable() != c ) or - v instanceof SsaSourceField and v.getEnclosingCallable().getBody() = b and liveAtEntry(v, b) + v instanceof SsaSourceField and + v.getEnclosingCallable().getBody().getControlFlowNode() = b and + liveAtEntry(v, b) } /** @@ -882,7 +886,7 @@ private newtype TSsaVariable = } or TSsaEntryDef(TrackedVar v, BasicBlock b) { hasEntryDef(v, b) } or TSsaUntracked(SsaSourceField nf, ControlFlowNode n) { - n = nf.getAnAccess().(FieldRead) and not trackField(nf) + n = nf.getAnAccess().(FieldRead).getControlFlowNode() and not trackField(nf) } /** @@ -940,7 +944,7 @@ class SsaVariable extends TSsaVariable { /** Gets an access of this SSA variable. */ VarRead getAUse() { ssaDefReachesUse(_, this, result) or - this = TSsaUntracked(_, result) + this = TSsaUntracked(_, result.getControlFlowNode()) } /** @@ -954,7 +958,7 @@ class SsaVariable extends TSsaVariable { */ VarRead getAFirstUse() { firstUse(this, result) or - this = TSsaUntracked(_, result) + this = TSsaUntracked(_, result.getControlFlowNode()) } /** Holds if this SSA variable is live at the end of `b`. */ @@ -990,7 +994,7 @@ class SsaUpdate extends SsaVariable { class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate { SsaExplicitUpdate() { exists(VariableUpdate upd | - upd = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable() + upd.getControlFlowNode() = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable() ) } @@ -998,7 +1002,8 @@ class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate { /** Gets the `VariableUpdate` defining the SSA variable. */ VariableUpdate getDefiningExpr() { - result = this.getCfgNode() and getDestVar(result) = this.getSourceVariable() + result.getControlFlowNode() = this.getCfgNode() and + getDestVar(result) = this.getSourceVariable() } } @@ -1038,7 +1043,7 @@ class SsaImplicitUpdate extends SsaUpdate { exists(SsaSourceField f, Callable setter | f = this.getSourceVariable() and relevantFieldUpdate(setter, f.getField(), result) and - updatesNamedField(this.getCfgNode(), f, setter) + updatesNamedField(this.getCfgNode().asCall(), f, setter) ) } @@ -1086,7 +1091,7 @@ class SsaImplicitInit extends SsaVariable, TSsaEntryDef { */ predicate isParameterDefinition(Parameter p) { this.getSourceVariable() = TLocalVar(p.getCallable(), p) and - p.getCallable().getBody() = this.getCfgNode() + p.getCallable().getBody().getControlFlowNode() = this.getCfgNode() } } diff --git a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll index 9e05b69db4ad..d29cc1ae5421 100644 --- a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll @@ -252,8 +252,8 @@ private module Input implements TypeFlowInput { downcastSuccessorAux(pragma[only_bind_into](cast), v, t, t1, t2) and t1.getASourceSupertype+() = t2 and va = v.getAUse() and - dominates(cast, va) and - dominates(cast.(ControlFlowNode).getANormalSuccessor(), va) + dominates(cast.getControlFlowNode(), va.getControlFlowNode()) and + dominates(cast.getControlFlowNode().getANormalSuccessor(), va.getControlFlowNode()) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll index 79f12e57f6a2..073d87d9744c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -73,15 +73,15 @@ private module SsaImpl { /** Holds if `n` updates the local variable `v`. */ cached predicate variableUpdate(BaseSsaSourceVariable v, ControlFlowNode n, BasicBlock b, int i) { - exists(VariableUpdate a | a = n | getDestVar(a) = v) and + exists(VariableUpdate a | a.getControlFlowNode() = n | getDestVar(a) = v) and b.getNode(i) = n and hasDominanceInformation(b) } /** Gets the definition point of a nested class in the parent scope. */ private ControlFlowNode parentDef(NestedClass nc) { - nc.(AnonymousClass).getClassInstanceExpr() = result or - nc.(LocalClass).getLocalTypeDeclStmt() = result + nc.(AnonymousClass).getClassInstanceExpr().getControlFlowNode() = result or + nc.(LocalClass).getLocalTypeDeclStmt().getControlFlowNode() = result } /** @@ -121,7 +121,7 @@ private module SsaImpl { /** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */ private predicate variableUse(BaseSsaSourceVariable v, VarRead use, BasicBlock b, int i) { - v.getAnAccess() = use and b.getNode(i) = use + v.getAnAccess() = use and b.getNode(i) = use.getControlFlowNode() } /** Holds if the value of `v` is captured in `b` at index `i`. */ @@ -164,7 +164,9 @@ private module SsaImpl { /** Holds if `v` has an implicit definition at the entry, `b`, of the callable. */ cached predicate hasEntryDef(BaseSsaSourceVariable v, BasicBlock b) { - exists(LocalScopeVariable l, Callable c | v = TLocalVar(c, l) and c.getBody() = b | + exists(LocalScopeVariable l, Callable c | + v = TLocalVar(c, l) and c.getBody().getControlFlowNode() = b + | l instanceof Parameter or l.getCallable() != c ) @@ -537,7 +539,7 @@ class BaseSsaVariable extends TBaseSsaVariable { class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate { BaseSsaUpdate() { exists(VariableUpdate upd | - upd = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable() + upd.getControlFlowNode() = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable() ) } @@ -545,7 +547,8 @@ class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate { /** Gets the `VariableUpdate` defining the SSA variable. */ VariableUpdate getDefiningExpr() { - result = this.getCfgNode() and getDestVar(result) = this.getSourceVariable() + result.getControlFlowNode() = this.getCfgNode() and + getDestVar(result) = this.getSourceVariable() } } @@ -566,7 +569,7 @@ class BaseSsaImplicitInit extends BaseSsaVariable, TSsaEntryDef { */ predicate isParameterDefinition(Parameter p) { this.getSourceVariable() = TLocalVar(p.getCallable(), p) and - p.getCallable().getBody() = this.getCfgNode() + p.getCallable().getBody().getControlFlowNode() = this.getCfgNode() } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 589d75c3635d..704e5714784c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -112,7 +112,7 @@ private module CaptureInput implements VariableCapture::InputSig { Location getLocation() { result = super.getLocation() } - predicate hasCfgNode(BasicBlock bb, int i) { this = bb.(J::BasicBlock).getNode(i) } + predicate hasCfgNode(BasicBlock bb, int i) { this = bb.(J::BasicBlock).getNode(i).asExpr() } } class VariableWrite extends Expr instanceof VariableUpdate { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index bb71ed25c73a..c66af2c78c5c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -17,9 +17,11 @@ import DataFlowNodes::Public /** Holds if `n` is an access to an unqualified `this` at `cfgnode`. */ private predicate thisAccess(Node n, ControlFlowNode cfgnode) { - n.(InstanceParameterNode).getCallable().getBody() = cfgnode + n.(InstanceParameterNode).getCallable().getBody() = cfgnode.asStmt() or - exists(InstanceAccess ia | ia = n.asExpr() and ia = cfgnode and ia.isOwnInstanceAccess()) + exists(InstanceAccess ia | + ia = n.asExpr() and ia.getControlFlowNode() = cfgnode and ia.isOwnInstanceAccess() + ) or n.(ImplicitInstanceAccess).getInstanceAccess().(OwnInstanceAccess).getCfgNode() = cfgnode } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll index 35384874b0d6..c88b9946faad 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll @@ -133,5 +133,5 @@ module Private { predicate ssaUpdateStep = RU::ssaUpdateStep/3; - Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() } + Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode().asExpr() } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll index bcc11e265189..ee2e3bb24123 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll @@ -340,7 +340,7 @@ private module Impl { Field getField(FieldAccess fa) { result = fa.getField() } - Expr getAnExpression(SsaReadPositionBlock bb) { result = bb.getBlock().getANode() } + Expr getAnExpression(SsaReadPositionBlock bb) { result = bb.getBlock().getANode().asExpr() } Guard getComparisonGuard(ComparisonExpr ce) { result = ce } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll index 410dc6b5cfeb..8712ad635f5c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll @@ -15,9 +15,11 @@ class BasicBlock = BB::BasicBlock; /** Gets a basic block in which SSA variable `v` is read. */ BasicBlock getAReadBasicBlock(SsaVariable v) { result = v.getAUse().getBasicBlock() } -private predicate id(BasicBlock x, BasicBlock y) { x = y } +private predicate id(BB::ExprParent x, BB::ExprParent y) { x = y } -private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y) +private predicate idOfAst(BB::ExprParent x, int y) = equivalenceRelation(id/2)(x, y) + +private predicate idOf(BasicBlock x, int y) { idOfAst(x.getAstNode(), y) } private int getId(BasicBlock bb) { idOf(bb, result) } diff --git a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll index 287346b85360..e7f86b9bfd81 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll @@ -109,12 +109,12 @@ predicate assertFail(BasicBlock bb, ControlFlowNode n) { bb = n.getBasicBlock() and ( exists(AssertTrueMethod m | - n = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = false)) + n.asExpr() = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = false)) ) or exists(AssertFalseMethod m | - n = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = true)) + n.asExpr() = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = true)) ) or - exists(AssertFailMethod m | n = m.getACheck()) or - n.(AssertStmt).getExpr().(BooleanLiteral).getBooleanValue() = false + exists(AssertFailMethod m | n.asExpr() = m.getACheck()) or + n.asStmt().(AssertStmt).getExpr().(BooleanLiteral).getBooleanValue() = false ) } diff --git a/java/ql/lib/semmle/code/java/metrics/MetricCallable.qll b/java/ql/lib/semmle/code/java/metrics/MetricCallable.qll index a888050185e2..d3dca781e54b 100644 --- a/java/ql/lib/semmle/code/java/metrics/MetricCallable.qll +++ b/java/ql/lib/semmle/code/java/metrics/MetricCallable.qll @@ -73,14 +73,14 @@ class MetricCallable extends Callable { // so there should be a branching point for each non-default switch // case (ignoring those that just fall through to the next case). private predicate branchingSwitchCase(ConstCase sc) { - not sc.(ControlFlowNode).getASuccessor() instanceof SwitchCase and + not sc.getControlFlowNode().getASuccessor().asStmt() instanceof SwitchCase and not defaultFallThrough(sc) } private predicate defaultFallThrough(ConstCase sc) { - exists(DefaultCase default | default.(ControlFlowNode).getASuccessor() = sc) + exists(DefaultCase default | default.getControlFlowNode().getASuccessor().asStmt() = sc) or - defaultFallThrough(sc.(ControlFlowNode).getAPredecessor()) + defaultFallThrough(sc.getControlFlowNode().getAPredecessor().asStmt()) } /** Holds if `stmt` is a branching statement used for the computation of cyclomatic complexity. */ diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index 77803e3e27dc..e841eb598cc3 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -29,15 +29,19 @@ private module ValidationMethod { */ private predicate validationMethod(Method m, int arg) { exists( - Guard g, SsaImplicitInit var, ControlFlowNode exit, ControlFlowNode normexit, boolean branch + Guard g, SsaImplicitInit var, ControlFlow::ExitNode exit, ControlFlowNode normexit, + boolean branch | validationGuard(g, var.getAUse(), branch) and var.isParameterDefinition(m.getParameter(arg)) and - exit = m and + exit.getEnclosingCallable() = m and normexit.getANormalSuccessor() = exit and 1 = strictcount(ControlFlowNode n | n.getANormalSuccessor() = exit) | - g.(ConditionNode).getABranchSuccessor(branch) = exit or + exists(ConditionNode conditionNode | + g = conditionNode.getCondition() and conditionNode.getABranchSuccessor(branch) = exit + ) + or g.controls(normexit.getBasicBlock(), branch) ) } diff --git a/java/ql/lib/semmle/code/java/security/Validation.qll b/java/ql/lib/semmle/code/java/security/Validation.qll index b8183b10751b..50f0a9aab1b6 100644 --- a/java/ql/lib/semmle/code/java/security/Validation.qll +++ b/java/ql/lib/semmle/code/java/security/Validation.qll @@ -50,7 +50,7 @@ private predicate validatedAccess(VarAccess va) { bb.getNode(i + 1) = node.getANormalSuccessor() | bb.bbStrictlyDominates(va.getBasicBlock()) or - bb.getNode(any(int j | j > i)) = va + bb.getNode(any(int j | j > i)).asExpr() = va ) ) ) diff --git a/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll b/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll index e0029ffeba26..2933ae5305e9 100644 --- a/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll +++ b/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll @@ -30,7 +30,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) { ConditionBlock cb, SsaVariable v, BinaryExpr cond, boolean condIsTrue, int k1, int k2, CompileTimeConstantExpr c1, CompileTimeConstantExpr c2 | - s1 = cond and + s1.getCondition() = cond and cb.getCondition() = cond and cond.hasOperands(v.getAUse(), c1) and c1.getIntValue() = k1 and diff --git a/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql b/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql index 241825c092e6..17b9fc93d211 100644 --- a/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql +++ b/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql @@ -36,7 +36,7 @@ where doubleCheckedLocking(if1, if2, sync, f) and a.getEnclosingStmt().getEnclosingStmt*() = if2.getThen() and se.getEnclosingStmt().getEnclosingStmt*() = sync.getBlock() and - a.(ControlFlowNode).getASuccessor+() = se and + a.getControlFlowNode().getASuccessor+().asExpr() = se and a.getDest().(FieldAccess).getField() = f select a, "Potential race condition. This assignment to $@ is visible to other threads before the subsequent statements are executed.", diff --git a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql index 757da40c6e6e..13f4ef7c451c 100644 --- a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql +++ b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql @@ -64,12 +64,12 @@ class ValidSynchStmt extends Stmt { exists(MethodCall lockAction | lockAction.getQualifier() = lockField.getAnAccess() and lockAction.getMethod().getName() = "lock" and - dominates(lockAction, this) + dominates(lockAction.getControlFlowNode(), this.getControlFlowNode()) ) and exists(MethodCall unlockAction | unlockAction.getQualifier() = lockField.getAnAccess() and unlockAction.getMethod().getName() = "unlock" and - postDominates(unlockAction, this) + postDominates(unlockAction.getControlFlowNode(), this.getControlFlowNode()) ) ) } diff --git a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql index 4efaf4f9820b..d46acc6aee06 100644 --- a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql +++ b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql @@ -59,11 +59,11 @@ class LockType extends RefType { } predicate lockBlock(LockType t, BasicBlock b, int locks) { - locks = strictcount(int i | b.getNode(i) = t.getLockAccess()) + locks = strictcount(int i | b.getNode(i).asExpr() = t.getLockAccess()) } predicate unlockBlock(LockType t, BasicBlock b, int unlocks) { - unlocks = strictcount(int i | b.getNode(i) = t.getUnlockAccess()) + unlocks = strictcount(int i | b.getNode(i).asExpr() = t.getUnlockAccess()) } /** @@ -90,11 +90,11 @@ predicate failedLock(LockType t, BasicBlock lockblock, BasicBlock exblock) { exists(ControlFlowNode lock | lock = lockblock.getLastNode() and ( - lock = t.getLockAccess() + lock.asExpr() = t.getLockAccess() or exists(SsaExplicitUpdate lockbool | // Using the value of `t.getLockAccess()` ensures that it is a `tryLock` call. - lock = lockbool.getAUse() and + lock.asExpr() = lockbool.getAUse() and lockbool.getDefiningExpr().(VariableAssign).getSource() = t.getLockAccess() ) ) and @@ -147,12 +147,12 @@ predicate blockIsLocked(LockType t, BasicBlock src, BasicBlock b, int locks) { ) } -from Callable c, LockType t, BasicBlock src, BasicBlock exit, MethodCall lock +from Callable c, LockType t, BasicBlock src, ExitBlock exit, MethodCall lock where // Restrict results to those methods that actually attempt to unlock. t.getUnlockAccess().getEnclosingCallable() = c and blockIsLocked(t, src, exit, _) and - exit.getLastNode() = c and - lock = src.getANode() and + exit.getEnclosingCallable() = c and + lock = src.getANode().asExpr() and lock = t.getLockAccess() select lock, "This lock might not be unlocked or might be locked more times than it is unlocked." diff --git a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql index 7dc893edaef9..9cf8ab9b61fd 100644 --- a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql +++ b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql @@ -61,7 +61,7 @@ predicate mainLoopCondition(LoopStmt loop, Expr cond) { else loopReentry = cond | last.getEnclosingStmt().getEnclosingStmt*() = loop.getBody() and - last.getASuccessor().(Expr).getParent*() = loopReentry + last.getASuccessor().asExpr().getParent*() = loopReentry ) } @@ -75,7 +75,7 @@ where // None of the ssa variables in `cond` are updated inside the loop. forex(SsaVariable ssa, VarRead use | ssa.getAUse() = use and use.getParent*() = cond | not ssa.getCfgNode().getEnclosingStmt().getEnclosingStmt*() = loop or - ssa.getCfgNode().(Expr).getParent*() = loop.(ForStmt).getAnInit() + ssa.getCfgNode().asExpr().getParent*() = loop.(ForStmt).getAnInit() ) and // And `cond` does not use method calls, field reads, or array reads. not exists(MethodCall ma | ma.getParent*() = cond) and diff --git a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql index 4e9857f3b938..899218838b9a 100644 --- a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql +++ b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql @@ -80,8 +80,8 @@ predicate badReentrantLockOrder(MethodCall first, MethodCall second, MethodCall otherSecond = v1.getLockAction() and second = v2.getLockAction() and otherFirst = v2.getLockAction() and - first.(ControlFlowNode).getASuccessor+() = second and - otherFirst.(ControlFlowNode).getASuccessor+() = otherSecond + first.getControlFlowNode().getASuccessor+() = second.getControlFlowNode() and + otherFirst.getControlFlowNode().getASuccessor+() = otherSecond.getControlFlowNode() | v1 != v2 ) diff --git a/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql b/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql index 312a77878fe6..2fe9d3cc6727 100644 --- a/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql +++ b/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql @@ -17,7 +17,7 @@ import Common from SwitchStmt s, Stmt c where c = s.getACase() and - not c.(ControlFlowNode).getASuccessor() instanceof SwitchCase and + not c.getControlFlowNode().getASuccessor().asStmt() instanceof SwitchCase and not s.(Annotatable).suppressesWarningsAbout("fallthrough") and mayDropThroughWithoutComment(s, c) select c, diff --git a/java/ql/src/Violations of Best Practice/Declarations/Common.qll b/java/ql/src/Violations of Best Practice/Declarations/Common.qll index 0f95df4b5c40..9211c4b0f290 100644 --- a/java/ql/src/Violations of Best Practice/Declarations/Common.qll +++ b/java/ql/src/Violations of Best Practice/Declarations/Common.qll @@ -24,15 +24,15 @@ predicate switchCaseControlFlowPlus(SwitchStmt switch, BasicBlock b1, BasicBlock exists(BasicBlock mid | switchCaseControlFlowPlus(switch, mid, b2) and switchCaseControlFlow(switch, b1, mid) and - not mid.getFirstNode() = switch.getACase() + not mid.getFirstNode().asStmt() = switch.getACase() ) } predicate mayDropThroughWithoutComment(SwitchStmt switch, Stmt switchCase) { switchCase = switch.getACase() and exists(Stmt other, BasicBlock b1, BasicBlock b2 | - b1.getFirstNode() = switchCase and - b2.getFirstNode() = other and + b1.getFirstNode().asStmt() = switchCase and + b2.getFirstNode().asStmt() = other and switchCaseControlFlowPlus(switch, b1, b2) and other = switch.getACase() and not fallThroughCommented(other) diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll index 256947a2dc79..0771db5ee32b 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll @@ -55,7 +55,7 @@ module SpringViewManipulationConfig implements DataFlow::ConfigSig { // a = "redirect:" + taint` // ``` exists(AddExpr e, StringLiteral sl | - node.asExpr() = e.getControlFlowNode().getASuccessor*() and + node.asExpr() = e.getControlFlowNode().getASuccessor*().asExpr() and sl = e.getLeftOperand*() and sl.getValue().matches(["redirect:%", "ajaxredirect:%", "forward:%"]) ) diff --git a/java/ql/test/library-tests/controlflow/basic/bbStmts.expected b/java/ql/test/library-tests/controlflow/basic/bbStmts.expected index e1a8d6b4ade5..0fbf3623f089 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStmts.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbStmts.expected @@ -1,7 +1,7 @@ | Test.java:3:14:3:17 | { ... } | 0 | Test.java:3:14:3:17 | { ... } | | Test.java:3:14:3:17 | { ... } | 1 | Test.java:3:14:3:17 | super(...) | -| Test.java:3:14:3:17 | { ... } | 2 | Test.java:3:14:3:17 | Test | -| Test.java:4:14:4:17 | test | 0 | Test.java:4:14:4:17 | test | +| Test.java:3:14:3:17 | { ... } | 2 | Test.java:3:14:3:17 | Exit | +| Test.java:4:14:4:17 | Exit | 0 | Test.java:4:14:4:17 | Exit | | Test.java:4:21:76:2 | { ... } | 0 | Test.java:4:21:76:2 | { ... } | | Test.java:4:21:76:2 | { ... } | 1 | Test.java:5:3:5:12 | var ...; | | Test.java:4:21:76:2 | { ... } | 2 | Test.java:5:11:5:11 | 0 | diff --git a/java/ql/test/library-tests/controlflow/basic/bbStmts.ql b/java/ql/test/library-tests/controlflow/basic/bbStmts.ql index 89a32acf4482..3b16a3844b56 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStmts.ql +++ b/java/ql/test/library-tests/controlflow/basic/bbStmts.ql @@ -3,5 +3,5 @@ import default from BasicBlock b, ControlFlowNode n, int i where b.getNode(i) = n and - b.getFile().(CompilationUnit).fromSource() + b.getEnclosingCallable().getFile().(CompilationUnit).fromSource() select b, i, n diff --git a/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected b/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected index 13382ba1fba0..8440209d0a45 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected @@ -1,4 +1,4 @@ -| Test.java:4:21:76:2 | { ... } | Test.java:4:14:4:17 | test | +| Test.java:4:21:76:2 | { ... } | Test.java:4:14:4:17 | Exit | | Test.java:4:21:76:2 | { ... } | Test.java:11:14:14:3 | { ... } | | Test.java:4:21:76:2 | { ... } | Test.java:14:10:16:3 | { ... } | | Test.java:4:21:76:2 | { ... } | Test.java:18:3:18:8 | ; | @@ -20,7 +20,7 @@ | Test.java:4:21:76:2 | { ... } | Test.java:60:12:62:5 | { ... } | | Test.java:4:21:76:2 | { ... } | Test.java:63:9:66:4 | { ... } | | Test.java:4:21:76:2 | { ... } | Test.java:70:3:70:9 | ; | -| Test.java:18:3:18:8 | ; | Test.java:4:14:4:17 | test | +| Test.java:18:3:18:8 | ; | Test.java:4:14:4:17 | Exit | | Test.java:18:3:18:8 | ; | Test.java:22:4:22:10 | ; | | Test.java:18:3:18:8 | ; | Test.java:24:4:24:10 | return ... | | Test.java:18:3:18:8 | ; | Test.java:30:15:33:3 | { ... } | diff --git a/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected b/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected index 0cf2c96d0225..0886f784fd9a 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected @@ -6,7 +6,7 @@ | Test.java:18:3:18:8 | ; | Test.java:24:4:24:10 | return ... | | Test.java:22:4:22:10 | ; | Test.java:30:15:33:3 | { ... } | | Test.java:22:4:22:10 | ; | Test.java:35:3:35:9 | ; | -| Test.java:24:4:24:10 | return ... | Test.java:4:14:4:17 | test | +| Test.java:24:4:24:10 | return ... | Test.java:4:14:4:17 | Exit | | Test.java:30:15:33:3 | { ... } | Test.java:35:3:35:9 | ; | | Test.java:35:3:35:9 | ; | Test.java:38:9:38:9 | x | | Test.java:38:9:38:9 | x | Test.java:38:16:41:3 | { ... } | @@ -27,4 +27,4 @@ | Test.java:57:15:60:5 | { ... } | Test.java:70:3:70:9 | ; | | Test.java:60:12:62:5 | { ... } | Test.java:54:26:54:26 | j | | Test.java:63:9:66:4 | { ... } | Test.java:54:26:54:26 | j | -| Test.java:70:3:70:9 | ; | Test.java:4:14:4:17 | test | +| Test.java:70:3:70:9 | ; | Test.java:4:14:4:17 | Exit | diff --git a/java/ql/test/library-tests/controlflow/basic/strictDominance.ql b/java/ql/test/library-tests/controlflow/basic/strictDominance.ql index 2d366a4f3727..10529b6d5c86 100644 --- a/java/ql/test/library-tests/controlflow/basic/strictDominance.ql +++ b/java/ql/test/library-tests/controlflow/basic/strictDominance.ql @@ -2,5 +2,5 @@ import default import semmle.code.java.controlflow.Dominance from Stmt pre, Stmt post -where strictlyDominates(pre, post) +where strictlyDominates(pre.getControlFlowNode(), post.getControlFlowNode()) select pre, post diff --git a/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql b/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql index 9948718fc83b..99268a03c4be 100644 --- a/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql +++ b/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql @@ -2,5 +2,5 @@ import default import semmle.code.java.controlflow.Dominance from Stmt pre, Stmt post -where strictlyPostDominates(post, pre) +where strictlyPostDominates(post.getControlFlowNode(), pre.getControlFlowNode()) select post, pre diff --git a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql index 26d33d9d07bd..41b23313ec8e 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql @@ -4,6 +4,6 @@ import semmle.code.java.controlflow.Dominance from IfStmt i, BlockStmt b where b = i.getThen() and - dominates(i.getThen(), b) and - dominates(i.getElse(), b) + dominates(i.getThen().getControlFlowNode(), b.getControlFlowNode()) and + dominates(i.getElse().getControlFlowNode(), b.getControlFlowNode()) select i, b diff --git a/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql b/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql index 298e0752ee41..5ee23224d5f9 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql @@ -17,5 +17,5 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co from Callable c, ControlFlowNode dom, ControlFlowNode node where (strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and - dominanceCounterExample(c.getBody(), dom, node) + dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node) select c, dom, node diff --git a/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql b/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql index b5bdf6889967..9a0d1b0c4bba 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql @@ -3,14 +3,14 @@ import default import semmle.code.java.controlflow.Dominance ControlFlowNode reachableIn(Method func) { - result = func.getBody() or + result = func.getBody().getControlFlowNode() or result = reachableIn(func).getASuccessor() } from Method func, ControlFlowNode entry, ControlFlowNode node where - func.getBody() = entry and + func.getBody().getControlFlowNode() = entry and reachableIn(func) = node and entry != node and - not strictlyDominates(func.getBody(), node) + not strictlyDominates(func.getBody().getControlFlowNode(), node) select func, node diff --git a/java/ql/test/library-tests/controlflow/dominance/dominator.expected b/java/ql/test/library-tests/controlflow/dominance/dominator.expected index e0f1596e42b1..de43e6721e64 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominator.expected +++ b/java/ql/test/library-tests/controlflow/dominance/dominator.expected @@ -27,7 +27,7 @@ | Test.java:14:18:14:18 | y | Test.java:14:14:14:18 | ... + ... | | Test.java:17:3:17:12 | if (...) | Test.java:17:7:17:7 | x | | Test.java:17:7:17:7 | x | Test.java:17:11:17:11 | 0 | -| Test.java:17:7:17:11 | ... < ... | Test.java:2:6:2:9 | test | +| Test.java:17:7:17:11 | ... < ... | Test.java:2:6:2:9 | Exit | | Test.java:17:7:17:11 | ... < ... | Test.java:18:4:18:10 | ; | | Test.java:17:7:17:11 | ... < ... | Test.java:20:11:20:11 | z | | Test.java:17:11:17:11 | 0 | Test.java:17:7:17:11 | ... < ... | @@ -163,7 +163,7 @@ | Test.java:83:9:83:9 | c | Test.java:83:5:83:9 | ...=... | | Test.java:85:4:85:15 | if (...) | Test.java:85:8:85:8 | a | | Test.java:85:8:85:8 | a | Test.java:85:13:85:14 | 10 | -| Test.java:85:8:85:14 | ... == ... | Test.java:74:6:74:10 | test2 | +| Test.java:85:8:85:14 | ... == ... | Test.java:74:6:74:10 | Exit | | Test.java:85:8:85:14 | ... == ... | Test.java:86:5:86:10 | break | | Test.java:85:8:85:14 | ... == ... | Test.java:87:4:87:15 | if (...) | | Test.java:85:13:85:14 | 10 | Test.java:85:8:85:14 | ... == ... | diff --git a/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql b/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql index 34469a686b14..220e4f275d54 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql @@ -4,13 +4,13 @@ import semmle.code.java.controlflow.Dominance /** transitive dominance */ ControlFlowNode reachableIn(Method func) { - result = func.getBody() or + result = func.getBody().getControlFlowNode() or result = reachableIn(func).getASuccessor() } from Method func, ControlFlowNode node where node = reachableIn(func) and - node != func.getBody() and + node != func.getBody().getControlFlowNode() and not iDominates(_, node) select func, node diff --git a/java/ql/test/library-tests/controlflow/paths/paths.ql b/java/ql/test/library-tests/controlflow/paths/paths.ql index 389c46a48f59..33e51acef784 100644 --- a/java/ql/test/library-tests/controlflow/paths/paths.ql +++ b/java/ql/test/library-tests/controlflow/paths/paths.ql @@ -5,7 +5,7 @@ class PathTestConf extends ActionConfiguration { PathTestConf() { this = "PathTestConf" } override predicate isAction(ControlFlowNode node) { - node.(MethodCall).getMethod().hasName("action") + node.asExpr().(MethodCall).getMethod().hasName("action") } } diff --git a/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected b/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected index 40a8e58c4fea..a849ab5392d5 100644 --- a/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected +++ b/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected @@ -1,4 +1,4 @@ -| MultiCatch.java:6:14:6:23 | super(...) | MultiCatch.java:6:14:6:23 | MultiCatch | +| MultiCatch.java:6:14:6:23 | super(...) | MultiCatch.java:6:14:6:23 | Exit | | MultiCatch.java:6:14:6:23 | { ... } | MultiCatch.java:6:14:6:23 | super(...) | | MultiCatch.java:8:2:20:2 | { ... } | MultiCatch.java:9:3:19:3 | try ... | | MultiCatch.java:9:3:19:3 | try ... | MultiCatch.java:10:3:15:3 | { ... } | @@ -16,7 +16,7 @@ | MultiCatch.java:17:4:17:4 | e | MultiCatch.java:17:4:17:22 | printStackTrace(...) | | MultiCatch.java:17:4:17:22 | printStackTrace(...) | MultiCatch.java:18:10:18:10 | e | | MultiCatch.java:17:4:17:23 | ; | MultiCatch.java:17:4:17:4 | e | -| MultiCatch.java:18:4:18:11 | throw ... | MultiCatch.java:7:14:7:23 | multiCatch | +| MultiCatch.java:18:4:18:11 | throw ... | MultiCatch.java:7:14:7:23 | Exit | | MultiCatch.java:18:10:18:10 | e | MultiCatch.java:18:4:18:11 | throw ... | | MultiCatch.java:23:2:33:2 | { ... } | MultiCatch.java:24:3:32:4 | try ... | | MultiCatch.java:24:3:32:4 | try ... | MultiCatch.java:25:3:31:3 | { ... } | @@ -31,12 +31,12 @@ | MultiCatch.java:28:12:28:12 | c | MultiCatch.java:30:10:30:24 | new Exception(...) | | MultiCatch.java:29:5:29:29 | throw ... | MultiCatch.java:31:5:31:37 | catch (...) | | MultiCatch.java:29:11:29:28 | new SQLException(...) | MultiCatch.java:29:5:29:29 | throw ... | -| MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:22:14:22:24 | multiCatch2 | +| MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:22:14:22:24 | Exit | | MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:31:5:31:37 | catch (...) | | MultiCatch.java:30:10:30:24 | new Exception(...) | MultiCatch.java:30:4:30:25 | throw ... | | MultiCatch.java:31:5:31:37 | catch (...) | MultiCatch.java:31:36:31:36 | e | | MultiCatch.java:31:36:31:36 | e | MultiCatch.java:32:3:32:4 | { ... } | -| MultiCatch.java:32:3:32:4 | { ... } | MultiCatch.java:22:14:22:24 | multiCatch2 | +| MultiCatch.java:32:3:32:4 | { ... } | MultiCatch.java:22:14:22:24 | Exit | | MultiCatch.java:36:2:42:2 | { ... } | MultiCatch.java:37:3:41:4 | try ... | | MultiCatch.java:37:3:41:4 | try ... | MultiCatch.java:38:3:40:3 | { ... } | | MultiCatch.java:38:3:40:3 | { ... } | MultiCatch.java:39:10:39:26 | new IOException(...) | @@ -45,4 +45,4 @@ | MultiCatch.java:39:10:39:26 | new IOException(...) | MultiCatch.java:40:5:40:22 | catch (...) | | MultiCatch.java:40:5:40:22 | catch (...) | MultiCatch.java:40:21:40:21 | e | | MultiCatch.java:40:21:40:21 | e | MultiCatch.java:41:3:41:4 | { ... } | -| MultiCatch.java:41:3:41:4 | { ... } | MultiCatch.java:35:14:35:26 | ordinaryCatch | +| MultiCatch.java:41:3:41:4 | { ... } | MultiCatch.java:35:14:35:26 | Exit | diff --git a/java/ql/test/library-tests/pattern-instanceof/cfg.expected b/java/ql/test/library-tests/pattern-instanceof/cfg.expected index 29de1e4a3a8a..b6caebd532a6 100644 --- a/java/ql/test/library-tests/pattern-instanceof/cfg.expected +++ b/java/ql/test/library-tests/pattern-instanceof/cfg.expected @@ -1,4 +1,4 @@ -| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Test | +| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Exit | | Test.java:1:14:1:17 | { ... } | Test.java:1:14:1:17 | super(...) | | Test.java:3:40:20:3 | { ... } | Test.java:5:5:5:34 | var ...; | | Test.java:5:5:5:34 | var ...; | Test.java:5:26:5:33 | source(...) | @@ -29,7 +29,7 @@ | Test.java:11:12:11:12 | s | Test.java:11:7:11:13 | sink(...) | | Test.java:14:5:14:92 | if (...) | Test.java:14:9:14:9 | o | | Test.java:14:9:14:9 | o | Test.java:14:9:14:91 | ...instanceof... | -| Test.java:14:9:14:91 | ...instanceof... | Test.java:3:22:3:25 | test | +| Test.java:14:9:14:91 | ...instanceof... | Test.java:3:22:3:25 | Exit | | Test.java:14:9:14:91 | ...instanceof... | Test.java:14:41:14:47 | tainted | | Test.java:14:22:14:91 | Outer(...) | Test.java:14:94:18:5 | { ... } | | Test.java:14:28:14:67 | Inner(...) | Test.java:14:77:14:90 | alsoNotTainted | @@ -43,15 +43,15 @@ | Test.java:16:7:16:22 | sink(...) | Test.java:17:7:17:27 | ; | | Test.java:16:7:16:23 | ; | Test.java:16:12:16:21 | notTainted | | Test.java:16:12:16:21 | notTainted | Test.java:16:7:16:22 | sink(...) | -| Test.java:17:7:17:26 | sink(...) | Test.java:3:22:3:25 | test | +| Test.java:17:7:17:26 | sink(...) | Test.java:3:22:3:25 | Exit | | Test.java:17:7:17:27 | ; | Test.java:17:12:17:25 | alsoNotTainted | | Test.java:17:12:17:25 | alsoNotTainted | Test.java:17:7:17:26 | sink(...) | | Test.java:22:33:22:53 | { ... } | Test.java:22:42:22:50 | "tainted" | -| Test.java:22:35:22:51 | return ... | Test.java:22:24:22:29 | source | +| Test.java:22:35:22:51 | return ... | Test.java:22:24:22:29 | Exit | | Test.java:22:42:22:50 | "tainted" | Test.java:22:35:22:51 | return ... | -| Test.java:23:40:23:42 | { ... } | Test.java:23:22:23:25 | sink | +| Test.java:23:40:23:42 | { ... } | Test.java:23:22:23:25 | Exit | | Test.java:27:8:27:12 | ...=... | Test.java:27:8:27:12 | ; | -| Test.java:27:8:27:12 | ...=... | Test.java:27:8:27:12 | Outer | +| Test.java:27:8:27:12 | ...=... | Test.java:27:8:27:12 | Exit | | Test.java:27:8:27:12 | ; | Test.java:27:8:27:12 | this | | Test.java:27:8:27:12 | ; | Test.java:27:8:27:12 | this | | Test.java:27:8:27:12 | i | Test.java:27:8:27:12 | ...=... | @@ -61,7 +61,7 @@ | Test.java:27:8:27:12 | this | Test.java:27:8:27:12 | otherField | | Test.java:27:8:27:12 | { ... } | Test.java:27:8:27:12 | super(...) | | Test.java:28:8:28:12 | ...=... | Test.java:28:8:28:12 | ; | -| Test.java:28:8:28:12 | ...=... | Test.java:28:8:28:12 | Inner | +| Test.java:28:8:28:12 | ...=... | Test.java:28:8:28:12 | Exit | | Test.java:28:8:28:12 | ; | Test.java:28:8:28:12 | this | | Test.java:28:8:28:12 | ; | Test.java:28:8:28:12 | this | | Test.java:28:8:28:12 | nonTaintedField | Test.java:28:8:28:12 | ...=... | diff --git a/java/ql/test/library-tests/pattern-instanceof/cfg.ql b/java/ql/test/library-tests/pattern-instanceof/cfg.ql index 0b07e8c4708a..db2cc49bc0b6 100644 --- a/java/ql/test/library-tests/pattern-instanceof/cfg.ql +++ b/java/ql/test/library-tests/pattern-instanceof/cfg.ql @@ -1,5 +1,5 @@ import java from ControlFlowNode cn -where cn.getFile().getBaseName() = "Test.java" +where cn.getLocation().getFile().getBaseName() = "Test.java" select cn, cn.getASuccessor() diff --git a/java/ql/test/library-tests/pattern-switch/cfg/test.expected b/java/ql/test/library-tests/pattern-switch/cfg/test.expected index a63aa7886683..c29059faf33e 100644 --- a/java/ql/test/library-tests/pattern-switch/cfg/test.expected +++ b/java/ql/test/library-tests/pattern-switch/cfg/test.expected @@ -1,6 +1,6 @@ -| Exhaustive.java:1:14:1:23 | super(...) | Exhaustive.java:1:14:1:23 | Exhaustive | +| Exhaustive.java:1:14:1:23 | super(...) | Exhaustive.java:1:14:1:23 | Exit | | Exhaustive.java:1:14:1:23 | { ... } | Exhaustive.java:1:14:1:23 | super(...) | -| Exhaustive.java:3:8:3:8 | super(...) | Exhaustive.java:3:8:3:8 | E | +| Exhaustive.java:3:8:3:8 | super(...) | Exhaustive.java:3:8:3:8 | Exit | | Exhaustive.java:3:8:3:8 | { ... } | Exhaustive.java:3:8:3:8 | super(...) | | Exhaustive.java:3:8:3:8 | { ... } | Exhaustive.java:3:12:3:12 | ; | | Exhaustive.java:3:12:3:12 | ...=... | Exhaustive.java:3:15:3:15 | ; | @@ -9,12 +9,12 @@ | Exhaustive.java:3:15:3:15 | ...=... | Exhaustive.java:3:18:3:18 | ; | | Exhaustive.java:3:15:3:15 | ; | Exhaustive.java:3:15:3:15 | new E(...) | | Exhaustive.java:3:15:3:15 | new E(...) | Exhaustive.java:3:15:3:15 | ...=... | -| Exhaustive.java:3:18:3:18 | ...=... | Exhaustive.java:3:8:3:8 | | +| Exhaustive.java:3:18:3:18 | ...=... | Exhaustive.java:3:8:3:8 | Exit | | Exhaustive.java:3:18:3:18 | ; | Exhaustive.java:3:18:3:18 | new E(...) | | Exhaustive.java:3:18:3:18 | new E(...) | Exhaustive.java:3:18:3:18 | ...=... | -| Exhaustive.java:5:15:5:15 | super(...) | Exhaustive.java:5:15:5:15 | X | +| Exhaustive.java:5:15:5:15 | super(...) | Exhaustive.java:5:15:5:15 | Exit | | Exhaustive.java:5:15:5:15 | { ... } | Exhaustive.java:5:15:5:15 | super(...) | -| Exhaustive.java:6:15:6:15 | super(...) | Exhaustive.java:6:15:6:15 | Y | +| Exhaustive.java:6:15:6:15 | super(...) | Exhaustive.java:6:15:6:15 | Exit | | Exhaustive.java:6:15:6:15 | { ... } | Exhaustive.java:6:15:6:15 | super(...) | | Exhaustive.java:8:47:35:3 | { ... } | Exhaustive.java:11:5:11:14 | switch (...) | | Exhaustive.java:11:5:11:14 | switch (...) | Exhaustive.java:11:13:11:13 | o | @@ -50,10 +50,10 @@ | Exhaustive.java:30:13:30:13 | i | Exhaustive.java:31:7:31:15 | case | | Exhaustive.java:31:7:31:15 | case | Exhaustive.java:31:14:31:14 | | | Exhaustive.java:31:7:31:15 | case | Exhaustive.java:32:7:32:15 | case | -| Exhaustive.java:31:14:31:14 | | Exhaustive.java:8:22:8:25 | test | +| Exhaustive.java:31:14:31:14 | | Exhaustive.java:8:22:8:25 | Exit | | Exhaustive.java:32:7:32:15 | case | Exhaustive.java:32:14:32:14 | | -| Exhaustive.java:32:14:32:14 | | Exhaustive.java:8:22:8:25 | test | -| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Test | +| Exhaustive.java:32:14:32:14 | | Exhaustive.java:8:22:8:25 | Exit | +| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Exit | | Test.java:1:14:1:17 | { ... } | Test.java:1:14:1:17 | super(...) | | Test.java:3:41:134:3 | { ... } | Test.java:5:6:5:19 | switch (...) | | Test.java:5:6:5:19 | switch (...) | Test.java:5:14:5:18 | thing | @@ -380,9 +380,9 @@ | Test.java:130:8:130:21 | case | Test.java:130:20:130:20 | | | Test.java:130:8:130:21 | case | Test.java:131:8:131:15 | default | | Test.java:130:20:130:20 | | Test.java:131:8:131:15 | default | -| Test.java:131:8:131:15 | default | Test.java:3:22:3:25 | test | +| Test.java:131:8:131:15 | default | Test.java:3:22:3:25 | Exit | | Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | ; | -| Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | A | +| Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | Exit | | Test.java:138:8:138:8 | ; | Test.java:138:8:138:8 | this | | Test.java:138:8:138:8 | ; | Test.java:138:8:138:8 | this | | Test.java:138:8:138:8 | b | Test.java:138:8:138:8 | ...=... | @@ -392,7 +392,7 @@ | Test.java:138:8:138:8 | this | Test.java:138:8:138:8 | field3 | | Test.java:138:8:138:8 | { ... } | Test.java:138:8:138:8 | super(...) | | Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | ; | -| Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | B | +| Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | Exit | | Test.java:139:8:139:8 | ; | Test.java:139:8:139:8 | this | | Test.java:139:8:139:8 | ; | Test.java:139:8:139:8 | this | | Test.java:139:8:139:8 | field1 | Test.java:139:8:139:8 | ...=... | diff --git a/java/ql/test/library-tests/pattern-switch/cfg/test.ql b/java/ql/test/library-tests/pattern-switch/cfg/test.ql index 4511277ee7da..7e0a85af822a 100644 --- a/java/ql/test/library-tests/pattern-switch/cfg/test.ql +++ b/java/ql/test/library-tests/pattern-switch/cfg/test.ql @@ -1,5 +1,5 @@ import java from ControlFlowNode cn -where cn.getFile().getBaseName() = ["Test.java", "Exhaustive.java"] +where cn.getLocation().getFile().getBaseName() = ["Test.java", "Exhaustive.java"] select cn, cn.getASuccessor() diff --git a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected index 63af489090b8..a6f3820334af 100644 --- a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected @@ -1,4 +1,4 @@ -| CloseReaderTest.java:8:14:8:28 | super(...) | CloseReaderTest.java:8:14:8:28 | CloseReaderTest | +| CloseReaderTest.java:8:14:8:28 | super(...) | CloseReaderTest.java:8:14:8:28 | Exit | | CloseReaderTest.java:8:14:8:28 | { ... } | CloseReaderTest.java:8:14:8:28 | super(...) | | CloseReaderTest.java:10:2:24:2 | { ... } | CloseReaderTest.java:12:3:13:42 | ; | | CloseReaderTest.java:12:3:12:12 | System.out | CloseReaderTest.java:12:20:12:40 | "Enter password for " | @@ -19,12 +19,12 @@ | CloseReaderTest.java:16:5:16:13 | System.in | CloseReaderTest.java:15:45:16:14 | new InputStreamReader(...) | | CloseReaderTest.java:17:3:23:3 | try ... | CloseReaderTest.java:18:3:20:3 | { ... } | | CloseReaderTest.java:18:3:20:3 | { ... } | CloseReaderTest.java:19:11:19:15 | stdin | -| CloseReaderTest.java:19:4:19:27 | return ... | CloseReaderTest.java:9:23:9:34 | readPassword | +| CloseReaderTest.java:19:4:19:27 | return ... | CloseReaderTest.java:9:23:9:34 | Exit | | CloseReaderTest.java:19:11:19:15 | stdin | CloseReaderTest.java:19:11:19:26 | readLine(...) | | CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:19:4:19:27 | return ... | | CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:20:5:20:26 | catch (...) | | CloseReaderTest.java:20:5:20:26 | catch (...) | CloseReaderTest.java:20:24:20:25 | ex | | CloseReaderTest.java:20:24:20:25 | ex | CloseReaderTest.java:21:3:23:3 | { ... } | | CloseReaderTest.java:21:3:23:3 | { ... } | CloseReaderTest.java:22:11:22:14 | null | -| CloseReaderTest.java:22:4:22:15 | return ... | CloseReaderTest.java:9:23:9:34 | readPassword | +| CloseReaderTest.java:22:4:22:15 | return ... | CloseReaderTest.java:9:23:9:34 | Exit | | CloseReaderTest.java:22:11:22:14 | null | CloseReaderTest.java:22:4:22:15 | return ... | diff --git a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql index 9de77b3c42b6..6fca436fbfdb 100644 --- a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getLocation().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected index 4598c7e0e32c..dcf2dac3cca1 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected @@ -1,4 +1,4 @@ -| LoopVarReadTest.java:3:14:3:28 | super(...) | LoopVarReadTest.java:3:14:3:28 | LoopVarReadTest | +| LoopVarReadTest.java:3:14:3:28 | super(...) | LoopVarReadTest.java:3:14:3:28 | Exit | | LoopVarReadTest.java:3:14:3:28 | { ... } | LoopVarReadTest.java:3:14:3:28 | super(...) | | LoopVarReadTest.java:5:2:15:2 | { ... } | LoopVarReadTest.java:6:3:6:12 | var ...; | | LoopVarReadTest.java:6:3:6:12 | var ...; | LoopVarReadTest.java:6:11:6:11 | 2 | @@ -23,6 +23,6 @@ | LoopVarReadTest.java:12:7:12:12 | q | LoopVarReadTest.java:14:3:14:28 | ; | | LoopVarReadTest.java:12:11:12:12 | 10 | LoopVarReadTest.java:12:7:12:12 | q | | LoopVarReadTest.java:14:3:14:12 | System.out | LoopVarReadTest.java:14:22:14:26 | "foo" | -| LoopVarReadTest.java:14:3:14:27 | println(...) | LoopVarReadTest.java:4:21:4:28 | testLoop | +| LoopVarReadTest.java:14:3:14:27 | println(...) | LoopVarReadTest.java:4:21:4:28 | Exit | | LoopVarReadTest.java:14:3:14:28 | ; | LoopVarReadTest.java:14:3:14:12 | System.out | | LoopVarReadTest.java:14:22:14:26 | "foo" | LoopVarReadTest.java:14:3:14:27 | println(...) | diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql index 9de77b3c42b6..6fca436fbfdb 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getLocation().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected index 2c6f433af5a4..3c261f67ee15 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected @@ -1,4 +1,4 @@ -| SaveFileTest.java:11:14:11:25 | super(...) | SaveFileTest.java:11:14:11:25 | SaveFileTest | +| SaveFileTest.java:11:14:11:25 | super(...) | SaveFileTest.java:11:14:11:25 | Exit | | SaveFileTest.java:11:14:11:25 | { ... } | SaveFileTest.java:11:14:11:25 | super(...) | | SaveFileTest.java:15:2:55:2 | { ... } | SaveFileTest.java:17:3:17:25 | var ...; | | SaveFileTest.java:17:3:17:25 | var ...; | SaveFileTest.java:17:21:17:24 | path | @@ -95,9 +95,9 @@ | SaveFileTest.java:48:5:48:15 | flush(...) | SaveFileTest.java:50:6:50:30 | catch (...) | | SaveFileTest.java:48:5:48:16 | ; | SaveFileTest.java:48:5:48:7 | bos | | SaveFileTest.java:49:5:49:7 | bos | SaveFileTest.java:49:5:49:15 | close(...) | -| SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:12:14:12:21 | saveFile | +| SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:12:14:12:21 | Exit | | SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:50:6:50:30 | catch (...) | | SaveFileTest.java:49:5:49:16 | ; | SaveFileTest.java:49:5:49:7 | bos | | SaveFileTest.java:50:6:50:30 | catch (...) | SaveFileTest.java:50:23:50:29 | ignored | | SaveFileTest.java:50:23:50:29 | ignored | SaveFileTest.java:51:4:52:4 | { ... } | -| SaveFileTest.java:51:4:52:4 | { ... } | SaveFileTest.java:12:14:12:21 | saveFile | +| SaveFileTest.java:51:4:52:4 | { ... } | SaveFileTest.java:12:14:12:21 | Exit | diff --git a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql index 9de77b3c42b6..6fca436fbfdb 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getLocation().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected b/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected index 9bbb912e6d97..c645abe35072 100644 --- a/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected @@ -1,8 +1,8 @@ -| SchackTest.java:1:14:1:23 | super(...) | SchackTest.java:1:14:1:23 | SchackTest | +| SchackTest.java:1:14:1:23 | super(...) | SchackTest.java:1:14:1:23 | Exit | | SchackTest.java:1:14:1:23 | { ... } | SchackTest.java:1:14:1:23 | super(...) | -| SchackTest.java:2:8:2:10 | super(...) | SchackTest.java:2:8:2:10 | ExA | +| SchackTest.java:2:8:2:10 | super(...) | SchackTest.java:2:8:2:10 | Exit | | SchackTest.java:2:8:2:10 | { ... } | SchackTest.java:2:8:2:10 | super(...) | -| SchackTest.java:3:8:3:10 | super(...) | SchackTest.java:3:8:3:10 | ExB | +| SchackTest.java:3:8:3:10 | super(...) | SchackTest.java:3:8:3:10 | Exit | | SchackTest.java:3:8:3:10 | { ... } | SchackTest.java:3:8:3:10 | super(...) | | SchackTest.java:5:18:24:2 | { ... } | SchackTest.java:6:3:23:3 | try ... | | SchackTest.java:6:3:23:3 | try ... | SchackTest.java:6:7:17:3 | { ... } | @@ -56,7 +56,7 @@ | SchackTest.java:20:23:20:72 | "successor (but neither true nor false successor)" | SchackTest.java:20:4:20:73 | println(...) | | SchackTest.java:21:13:23:3 | { ... } | SchackTest.java:22:4:22:41 | ; | | SchackTest.java:22:4:22:13 | System.out | SchackTest.java:22:23:22:39 | "false successor" | -| SchackTest.java:22:4:22:40 | println(...) | SchackTest.java:5:7:5:9 | foo | +| SchackTest.java:22:4:22:40 | println(...) | SchackTest.java:5:7:5:9 | Exit | | SchackTest.java:22:4:22:41 | ; | SchackTest.java:22:4:22:13 | System.out | | SchackTest.java:22:23:22:39 | "false successor" | SchackTest.java:22:4:22:40 | println(...) | | SchackTest.java:26:35:30:2 | { ... } | SchackTest.java:27:3:27:25 | if (...) | @@ -65,9 +65,9 @@ | SchackTest.java:27:7:27:24 | ... > ... | SchackTest.java:28:10:28:18 | new ExB(...) | | SchackTest.java:27:7:27:24 | ... > ... | SchackTest.java:29:10:29:22 | random(...) | | SchackTest.java:27:23:27:24 | .5 | SchackTest.java:27:7:27:24 | ... > ... | -| SchackTest.java:28:4:28:19 | throw ... | SchackTest.java:26:18:26:20 | bar | +| SchackTest.java:28:4:28:19 | throw ... | SchackTest.java:26:18:26:20 | Exit | | SchackTest.java:28:10:28:18 | new ExB(...) | SchackTest.java:28:4:28:19 | throw ... | -| SchackTest.java:29:3:29:28 | return ... | SchackTest.java:26:18:26:20 | bar | +| SchackTest.java:29:3:29:28 | return ... | SchackTest.java:26:18:26:20 | Exit | | SchackTest.java:29:10:29:22 | random(...) | SchackTest.java:29:26:29:27 | .3 | | SchackTest.java:29:10:29:27 | ... > ... | SchackTest.java:29:3:29:28 | return ... | | SchackTest.java:29:26:29:27 | .3 | SchackTest.java:29:10:29:27 | ... > ... | diff --git a/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql b/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql index 9de77b3c42b6..6fca436fbfdb 100644 --- a/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getLocation().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected index e871d474a814..8dac71ffd45d 100644 --- a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected @@ -1,4 +1,4 @@ -| TestBreak.java:3:14:3:22 | super(...) | TestBreak.java:3:14:3:22 | TestBreak | +| TestBreak.java:3:14:3:22 | super(...) | TestBreak.java:3:14:3:22 | Exit | | TestBreak.java:3:14:3:22 | { ... } | TestBreak.java:3:14:3:22 | super(...) | | TestBreak.java:5:2:85:2 | { ... } | TestBreak.java:7:3:8:11 |