mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge branch 'main' into codeql-spark-run-21760759512
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.27
|
||||
version: 0.4.28-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.19
|
||||
version: 0.6.20-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added remote flow source models for the `winhttp.h` windows header and the Azure SDK core library for C/C++.
|
||||
@@ -24,6 +24,13 @@ extensions:
|
||||
- ["", "", False, "MapViewOfFileNuma2", "", "", "ReturnValue[*]", "local", "manual"]
|
||||
# ntifs.h
|
||||
- ["", "", False, "NtReadFile", "", "", "Argument[*5]", "local", "manual"]
|
||||
# winhttp.h
|
||||
- ["", "", False, "WinHttpReadData", "", "", "Argument[*1]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpReadDataEx", "", "", "Argument[*1]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeaders", "", "", "Argument[*3]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*5]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*6]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[**8]", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
@@ -46,4 +53,6 @@ extensions:
|
||||
- ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
# winternl.h
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
# winhttp.h
|
||||
- ["", "", False, "WinHttpCrackUrl", "", "", "Argument[*0]", "Argument[*3]", "taint", "manual"]
|
||||
41
cpp/ql/lib/ext/azure.core.model.yml
Normal file
41
cpp/ql/lib/ext/azure.core.model.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: sourceModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
|
||||
- ["Azure::Core::Http", "RawResponse", True, "GetHeaders", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "RawResponse", True, "GetBody", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "RawResponse", True, "ExtractBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetHeaders", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetHeader", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["Azure::Core", "Url", True, "Url", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetScheme", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetHost", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetPort", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetQueryParameters", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "AppendPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "AppendQueryParameter", "", "", "Argument[*1]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetHost", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetPath", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetPort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetScheme", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetRelativeUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetAbsoluteUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "Decode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "Encode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "Read", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "ReadToCount", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "ReadToEnd", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "Nullable", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
|
||||
- ["Azure", "Nullable", True, "Value", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator->", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator*", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 7.1.0
|
||||
version: 7.1.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -64,17 +64,27 @@ private string getMultiLocationFilePath(@element e) {
|
||||
overlay[local]
|
||||
private predicate isBase() { not isOverlay() }
|
||||
|
||||
/**
|
||||
* Holds if `path` was extracted in the overlay database.
|
||||
*/
|
||||
overlay[local]
|
||||
private predicate overlayHasFile(string path) {
|
||||
isOverlay() and
|
||||
files(_, path) and
|
||||
path != ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards an element from the base variant if:
|
||||
* - It has a single location in a changed file, or
|
||||
* - All of its locations are in changed files.
|
||||
* - It has a single location in a file extracted in the overlay, or
|
||||
* - All of its locations are in files extracted in the overlay.
|
||||
*/
|
||||
overlay[discard_entity]
|
||||
private predicate discardElement(@element e) {
|
||||
isBase() and
|
||||
(
|
||||
overlayChangedFiles(getSingleLocationFilePath(e))
|
||||
overlayHasFile(getSingleLocationFilePath(e))
|
||||
or
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayChangedFiles(path))
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayHasFile(path))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getChild(this.getChildCount() - 1) }
|
||||
|
||||
private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
|
||||
private int getChildCount() { result = count(int i | exists(this.getDeclarationEntry(i))) }
|
||||
|
||||
IRDeclarationEntry getIRDeclarationEntry(int index) {
|
||||
result.hasIndex(index) and
|
||||
|
||||
@@ -57,3 +57,4 @@ private import implementations.CAtlFile
|
||||
private import implementations.CAtlFileMapping
|
||||
private import implementations.CAtlTemporaryFile
|
||||
private import implementations.CRegKey
|
||||
private import implementations.WinHttp
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
/** The `WINHTTP_HEADER_NAME` class from `winhttp.h`. */
|
||||
class WinHttpHeaderName extends Class {
|
||||
WinHttpHeaderName() { this.hasGlobalName("_WINHTTP_HEADER_NAME") }
|
||||
}
|
||||
|
||||
/** The `WINHTTP_EXTENDED_HEADER` class from `winhttp.h`. */
|
||||
class WinHttpExtendedHeader extends Class {
|
||||
WinHttpExtendedHeader() { this.hasGlobalName("_WINHTTP_EXTENDED_HEADER") }
|
||||
}
|
||||
|
||||
private class WinHttpHeaderNameInheritingContent extends TaintInheritingContent,
|
||||
DataFlow::FieldContent
|
||||
{
|
||||
WinHttpHeaderNameInheritingContent() {
|
||||
this.getIndirectionIndex() = 2 and
|
||||
(
|
||||
this.getAField().getDeclaringType() instanceof WinHttpHeaderName
|
||||
or
|
||||
// The extended header looks like:
|
||||
// struct WINHTTP_EXTENDED_HEADER {
|
||||
// union { [...] };
|
||||
// union { [...] };
|
||||
// };
|
||||
// So the first declaring type is the anonymous unions, and the declaring
|
||||
// type of those anonymous unions is the `WINHTTP_EXTENDED_HEADER` struct.
|
||||
this.getAField().getDeclaringType().getDeclaringType() instanceof WinHttpExtendedHeader
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The `URL_COMPONENTS` class from `winhttp.h`. */
|
||||
class WinHttpUrlComponents extends Class {
|
||||
WinHttpUrlComponents() { this.hasGlobalName("_WINHTTP_URL_COMPONENTS") }
|
||||
}
|
||||
|
||||
private class WinHttpUrlComponentsInheritingContent extends TaintInheritingContent,
|
||||
DataFlow::FieldContent
|
||||
{
|
||||
WinHttpUrlComponentsInheritingContent() {
|
||||
exists(Field f | f = this.getField() and f.getDeclaringType() instanceof WinHttpUrlComponents |
|
||||
if f.getType().getUnspecifiedType() instanceof PointerType
|
||||
then this.getIndirectionIndex() = 2
|
||||
else this.getIndirectionIndex() = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.5.10
|
||||
version: 1.5.11-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
297
cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
Normal file
297
cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
using uint16_t = unsigned short;
|
||||
using int64_t = long long;
|
||||
using size_t = unsigned long;
|
||||
using uint8_t = unsigned char;
|
||||
using int32_t = int;
|
||||
using uint32_t = unsigned int;
|
||||
|
||||
namespace std
|
||||
{
|
||||
class string
|
||||
{
|
||||
public:
|
||||
string();
|
||||
string(const char *);
|
||||
~string();
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class map
|
||||
{
|
||||
public:
|
||||
map();
|
||||
~map();
|
||||
|
||||
V& operator[](const K& key);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class vector
|
||||
{
|
||||
public:
|
||||
vector();
|
||||
~vector();
|
||||
|
||||
T& operator[](size_t);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unique_ptr {
|
||||
public:
|
||||
unique_ptr();
|
||||
~unique_ptr();
|
||||
|
||||
T* get();
|
||||
};
|
||||
}
|
||||
|
||||
namespace Azure
|
||||
{
|
||||
template <typename T>
|
||||
class Nullable
|
||||
{
|
||||
public:
|
||||
Nullable();
|
||||
Nullable(const T);
|
||||
Nullable(const Nullable &);
|
||||
~Nullable();
|
||||
Nullable (Nullable &&);
|
||||
Nullable & operator= (const Nullable &);
|
||||
bool HasValue() const;
|
||||
const T & Value () const;
|
||||
T& Value ();
|
||||
const T * operator-> () const;
|
||||
T * operator-> ();
|
||||
const T & operator* () const;
|
||||
T & operator* ();
|
||||
};
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Url
|
||||
{
|
||||
public:
|
||||
Url();
|
||||
Url(const std::string &);
|
||||
void AppendPath(const std::string &encodedPath);
|
||||
void AppendQueryParameter(const std::string &encodedKey,
|
||||
const std::string &encodedValue);
|
||||
|
||||
static std::string Url::Decode(const std::string &value);
|
||||
static std::string Url::Encode(const std::string &value,
|
||||
const std::string &doNotEncodeSymbols = "");
|
||||
|
||||
std::string Url::GetAbsoluteUrl() const;
|
||||
const std::string &GetHost() const;
|
||||
const std::string &GetPath() const;
|
||||
uint16_t GetPort() const;
|
||||
std::map<std::string, std::string> GetQueryParameters() const;
|
||||
std::string Url::GetRelativeUrl() const;
|
||||
const std::string &GetScheme() const;
|
||||
void RemoveQueryParameter(const std::string &encodedKey);
|
||||
void SetHost(const std::string &encodedHost);
|
||||
void SetPath(const std::string &encodedPath);
|
||||
void SetPort(uint16_t port);
|
||||
void SetQueryParameters(std::map<std::string, std::string> queryParameters);
|
||||
void SetScheme(const std::string &scheme);
|
||||
};
|
||||
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context();
|
||||
};
|
||||
|
||||
namespace IO
|
||||
{
|
||||
class BodyStream
|
||||
{
|
||||
public:
|
||||
virtual ~BodyStream();
|
||||
virtual int64_t Length() const = 0;
|
||||
virtual void Rewind();
|
||||
size_t Read(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
|
||||
size_t ReadToCount(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
|
||||
std::vector<uint8_t> ReadToEnd(Azure::Core::Context const &context = Azure::Core::Context());
|
||||
};
|
||||
}
|
||||
|
||||
enum class HttpStatusCode {
|
||||
None = 0,
|
||||
Continue = 100,
|
||||
SwitchingProtocols = 101,
|
||||
Processing = 102,
|
||||
EarlyHints = 103,
|
||||
OK = 200,
|
||||
Created = 201,
|
||||
Accepted = 202,
|
||||
NonAuthoritativeInformation = 203,
|
||||
NoContent = 204,
|
||||
ResetContent = 205,
|
||||
PartialContent = 206,
|
||||
MultiStatus = 207,
|
||||
AlreadyReported = 208,
|
||||
IMUsed = 226,
|
||||
MultipleChoices = 300,
|
||||
MovedPermanently = 301,
|
||||
Found = 302,
|
||||
SeeOther = 303,
|
||||
NotModified = 304,
|
||||
UseProxy = 305,
|
||||
TemporaryRedirect = 307,
|
||||
PermanentRedirect = 308,
|
||||
BadRequest = 400,
|
||||
Unauthorized = 401,
|
||||
PaymentRequired = 402,
|
||||
Forbidden = 403,
|
||||
NotFound = 404,
|
||||
MethodNotAllowed = 405,
|
||||
NotAcceptable = 406,
|
||||
ProxyAuthenticationRequired = 407,
|
||||
RequestTimeout = 408,
|
||||
Conflict = 409,
|
||||
Gone = 410,
|
||||
LengthRequired = 411,
|
||||
PreconditionFailed = 412,
|
||||
PayloadTooLarge = 413,
|
||||
URITooLong = 414,
|
||||
UnsupportedMediaType = 415,
|
||||
RangeNotSatisfiable = 416,
|
||||
ExpectationFailed = 417,
|
||||
MisdirectedRequest = 421,
|
||||
UnprocessableEntity = 422,
|
||||
Locked = 423,
|
||||
FailedDependency = 424,
|
||||
TooEarly = 425,
|
||||
UpgradeRequired = 426,
|
||||
PreconditionRequired = 428,
|
||||
TooManyRequests = 429,
|
||||
RequestHeaderFieldsTooLarge = 431,
|
||||
UnavailableForLegalReasons = 451,
|
||||
InternalServerError = 500,
|
||||
NotImplemented = 501,
|
||||
BadGateway = 502,
|
||||
ServiceUnavailable = 503,
|
||||
GatewayTimeout = 504,
|
||||
HTTPVersionNotSupported = 505,
|
||||
VariantAlsoNegotiates = 506,
|
||||
InsufficientStorage = 507,
|
||||
LoopDetected = 508,
|
||||
NotExtended = 510,
|
||||
NetworkAuthenticationRequired = 511
|
||||
};
|
||||
|
||||
namespace Http
|
||||
{
|
||||
class HttpMethod
|
||||
{
|
||||
public:
|
||||
HttpMethod(std::string value);
|
||||
bool operator==(const HttpMethod &other) const;
|
||||
bool operator!=(const HttpMethod &other) const;
|
||||
const std::string &ToString() const;
|
||||
};
|
||||
|
||||
extern const HttpMethod Get;
|
||||
extern const HttpMethod Head;
|
||||
extern const HttpMethod Post;
|
||||
extern const HttpMethod Put;
|
||||
extern const HttpMethod Delete;
|
||||
extern const HttpMethod Patch;
|
||||
extern const HttpMethod Options;
|
||||
|
||||
class Request
|
||||
{
|
||||
public:
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
bool shouldBufferResponse);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
IO::BodyStream *bodyStream);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
IO::BodyStream *bodyStream,
|
||||
bool shouldBufferResponse);
|
||||
std::map<std::string, std::string> GetHeaders () const;
|
||||
Azure::Nullable<std::string> GetHeader(std::string const &name);
|
||||
IO::BodyStream * GetBodyStream();
|
||||
Azure::Core::IO::BodyStream const* GetBodyStream () const;
|
||||
};
|
||||
|
||||
class RawResponse {
|
||||
public:
|
||||
RawResponse (int32_t majorVersion, int32_t minorVersion, HttpStatusCode statusCode, std::string const &reasonPhrase);
|
||||
RawResponse (RawResponse const &response);
|
||||
RawResponse (RawResponse &&response);
|
||||
~RawResponse ();
|
||||
void SetHeader (std::string const &name, std::string const &value);
|
||||
void SetBodyStream (std::unique_ptr< Azure::Core::IO::BodyStream > stream);
|
||||
void SetBody (std::vector< uint8_t > body);
|
||||
uint32_t GetMajorVersion () const;
|
||||
uint32_t GetMinorVersion () const;
|
||||
HttpStatusCode GetStatusCode () const;
|
||||
std::string const & GetReasonPhrase () const;
|
||||
std::map<std::string, std::string>& GetHeaders () const;
|
||||
std::unique_ptr<Azure::Core::IO::BodyStream> ExtractBodyStream ();
|
||||
std::vector<uint8_t> & GetBody ();
|
||||
std::vector<uint8_t> const& GetBody() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sink(char);
|
||||
void sink(std::string);
|
||||
void sink(std::vector<uint8_t>);
|
||||
void sink(Azure::Nullable<std::string>);
|
||||
|
||||
void test_BodyStream() {
|
||||
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
|
||||
Azure::Core::IO::BodyStream * resp = request.GetBodyStream();
|
||||
|
||||
{
|
||||
unsigned char buffer[1024];
|
||||
resp->Read(buffer, sizeof(buffer));
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
unsigned char buffer[1024];
|
||||
resp->ReadToCount(buffer, sizeof(buffer));
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
std::vector<unsigned char> vec = resp->ReadToEnd();
|
||||
sink(vec); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
void test_RawResponse(Azure::Core::Http::RawResponse& resp) {
|
||||
{
|
||||
std::map<std::string, std::string> body = resp.GetHeaders();
|
||||
sink(body["Content-Type"]); // $ ir
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> body = resp.GetBody();
|
||||
sink(body); // $ ir
|
||||
}
|
||||
{
|
||||
std::unique_ptr<Azure::Core::IO::BodyStream> bodyStream = resp.ExtractBodyStream();
|
||||
sink(bodyStream.get()->ReadToEnd()); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
void test_GetHeader() {
|
||||
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
|
||||
{
|
||||
auto headerValue = request.GetHeader("Content-Type").Value();
|
||||
sink(headerValue); // $ ir
|
||||
}
|
||||
{
|
||||
std::map<std::string, std::string> headers = request.GetHeaders();
|
||||
std::string contentType = headers["Content-Type"];
|
||||
sink(contentType); // $ ir
|
||||
}
|
||||
}
|
||||
@@ -14,45 +14,111 @@ models
|
||||
| 13 | Source: ; ; false; NtReadFile; ; ; Argument[*5]; local; manual |
|
||||
| 14 | Source: ; ; false; ReadFile; ; ; Argument[*1]; local; manual |
|
||||
| 15 | Source: ; ; false; ReadFileEx; ; ; Argument[*1]; local; manual |
|
||||
| 16 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
|
||||
| 17 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
|
||||
| 18 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
|
||||
| 19 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 20 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 21 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 22 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 23 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 24 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 25 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 26 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 27 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 28 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 29 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 30 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 31 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
|
||||
| 32 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
|
||||
| 33 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 34 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 35 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 36 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 37 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
| 16 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
|
||||
| 17 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
|
||||
| 18 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
|
||||
| 19 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
|
||||
| 20 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
|
||||
| 21 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
|
||||
| 22 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
|
||||
| 23 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
|
||||
| 24 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
|
||||
| 25 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
|
||||
| 26 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
|
||||
| 27 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
|
||||
| 28 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
|
||||
| 29 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
|
||||
| 30 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
|
||||
| 31 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 32 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 33 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 34 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 35 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 36 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 37 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 38 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 39 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 40 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 41 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 42 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 43 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
|
||||
| 44 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
|
||||
| 45 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
|
||||
| 46 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 47 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 48 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 49 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 50 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 51 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 52 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||
| 53 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||
| 54 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
edges
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:37 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:17 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:17 Sink:MaD:2 |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:54 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:29 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:29 Sink:MaD:2 |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:100:64:100:71 | *send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||
| 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:37 |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:35 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:34 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:36 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:54 |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:53 |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:50 |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:51 |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:52 |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:26 |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:50 |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:51 |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:52 |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:273:62:273:64 | call to GetHeaders | provenance | Src:MaD:25 |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:10:274:29 | call to operator[] | provenance | |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:14:274:29 | call to operator[] | provenance | |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:277:45:277:47 | call to GetBody | provenance | Src:MaD:24 |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:23 |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:52 |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:53 |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:27 |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:290:10:290:20 | headerValue | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:293:58:293:67 | call to GetHeaders | provenance | Src:MaD:28 |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:294:38:294:53 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| azure.cpp:295:10:295:20 | contentType | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:48 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:47 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:49 |
|
||||
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
|
||||
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | |
|
||||
@@ -61,15 +127,15 @@ edges
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:35 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:48 |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:34 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:47 |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:36 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:49 |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
|
||||
@@ -77,16 +143,16 @@ edges
|
||||
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
|
||||
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
|
||||
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:33 |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:46 |
|
||||
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
|
||||
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
|
||||
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:16 |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:22 |
|
||||
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
|
||||
@@ -95,7 +161,7 @@ edges
|
||||
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
|
||||
@@ -104,28 +170,28 @@ edges
|
||||
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:32 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:45 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:118:44:118:44 | *x | provenance | |
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:32 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:18 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:45 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:30 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
|
||||
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | |
|
||||
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:30:8:30:15 | * ... | provenance | |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | provenance | |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:18 |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:30 |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:4 |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:36:10:36:13 | * ... | provenance | |
|
||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:5 |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:34 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:34 |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | |
|
||||
@@ -173,11 +239,11 @@ edges
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:12 |
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
|
||||
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:21 |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:33 |
|
||||
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:19 |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:31 |
|
||||
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:20 |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:32 |
|
||||
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:403:26:403:36 | *lpParameter [x] | windows.cpp:405:10:405:25 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:405:10:405:25 | *lpParameter [x] | windows.cpp:406:8:406:8 | *s [x] | provenance | |
|
||||
@@ -196,17 +262,17 @@ edges
|
||||
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | |
|
||||
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | |
|
||||
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:27 |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:23 |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:24 |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:25 |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:39 |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:35 |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:36 |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:37 |
|
||||
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:26 |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:38 |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:29 |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:30 |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:28 |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:41 |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:42 |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:40 |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
|
||||
@@ -218,37 +284,51 @@ edges
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | |
|
||||
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:27 |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:39 |
|
||||
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:23 |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:35 |
|
||||
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:24 |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:36 |
|
||||
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:25 |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:37 |
|
||||
| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | |
|
||||
| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:28 |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:40 |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | |
|
||||
| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:26 |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:38 |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | |
|
||||
| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:29 |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:41 |
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:30 |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:42 |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:20 |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:21 |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:16 |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:18 |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:19 |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:17 |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | provenance | MaD:43 |
|
||||
| windows.cpp:728:5:728:28 | ... = ... | windows.cpp:729:35:729:35 | *x | provenance | |
|
||||
| windows.cpp:728:12:728:28 | call to source | windows.cpp:728:5:728:28 | ... = ... | provenance | |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | provenance | |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:43 |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:731:10:731:36 | * ... | provenance | |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:733:10:733:35 | * ... | provenance | |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:735:10:735:37 | * ... | provenance | |
|
||||
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 |
|
||||
@@ -262,6 +342,59 @@ nodes
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | semmle.label | *send_str |
|
||||
| asio_streams.cpp:101:7:101:17 | send_buffer | semmle.label | send_buffer |
|
||||
| asio_streams.cpp:103:29:103:39 | *send_buffer | semmle.label | *send_buffer |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | semmle.label | [summary param] this in Value |
|
||||
| azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | semmle.label | [summary] to write: ReturnValue[*] in Value |
|
||||
| azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | semmle.label | [summary param] *0 in Read [Return] |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | semmle.label | [summary param] this in Read |
|
||||
| azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | semmle.label | [summary param] *0 in ReadToCount [Return] |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | semmle.label | [summary param] this in ReadToCount |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | semmle.label | [summary param] this in ReadToEnd |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | semmle.label | [summary] to write: ReturnValue in ReadToEnd [element] |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | semmle.label | [summary] to write: ReturnValue.Element in ReadToEnd |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
|
||||
| azure.cpp:257:5:257:8 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | semmle.label | Read output argument |
|
||||
| azure.cpp:258:10:258:16 | * ... | semmle.label | * ... |
|
||||
| azure.cpp:262:5:262:8 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | semmle.label | ReadToCount output argument |
|
||||
| azure.cpp:263:10:263:16 | * ... | semmle.label | * ... |
|
||||
| azure.cpp:266:38:266:41 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:267:10:267:12 | vec | semmle.label | vec |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | semmle.label | vec [element] |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:274:10:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
|
||||
| azure.cpp:282:10:282:38 | call to ReadToEnd | semmle.label | call to ReadToEnd |
|
||||
| azure.cpp:282:21:282:23 | *call to get | semmle.label | *call to get |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
|
||||
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | semmle.label | [summary param] 0 in ymlStepManual |
|
||||
| test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | semmle.label | [summary] to write: ReturnValue in ymlStepManual |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | semmle.label | [summary param] 0 in ymlStepGenerated |
|
||||
@@ -482,8 +615,34 @@ nodes
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | semmle.label | RtlMoveVolatileMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:574:10:574:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | semmle.label | WinHttpReadData output argument |
|
||||
| windows.cpp:647:10:647:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | semmle.label | WinHttpReadDataEx output argument |
|
||||
| windows.cpp:654:10:654:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | semmle.label | WinHttpQueryHeaders output argument |
|
||||
| windows.cpp:661:10:661:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:671:10:671:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:673:10:673:29 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:675:10:675:27 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | semmle.label | [summary param] *0 in WinHttpCrackUrl |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | semmle.label | [summary param] *3 in WinHttpCrackUrl [Return] |
|
||||
| windows.cpp:728:5:728:28 | ... = ... | semmle.label | ... = ... |
|
||||
| windows.cpp:728:12:728:28 | call to source | semmle.label | call to source |
|
||||
| windows.cpp:729:35:729:35 | *x | semmle.label | *x |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | semmle.label | WinHttpCrackUrl output argument |
|
||||
| windows.cpp:731:10:731:36 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:733:10:733:35 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:735:10:735:37 | * ... | semmle.label | * ... |
|
||||
subpaths
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | azure.cpp:257:16:257:21 | Read output argument |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | azure.cpp:262:23:262:28 | ReadToCount output argument |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | azure.cpp:289:63:289:65 | call to Value |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
@@ -498,4 +657,5 @@ subpaths
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | windows.cpp:568:19:568:29 | RtlMoveMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
|
||||
testFailures
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | remote |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | remote |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | remote |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | remote |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | remote |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | remote |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | remote |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | local |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
||||
@@ -20,3 +26,9 @@
|
||||
| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | local |
|
||||
| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | local |
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | local |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | remote |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | remote |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | remote |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | remote |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | remote |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | remote |
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| azure.cpp:252:79:252:98 | call to string | azure.cpp:252:62:252:99 | call to Url |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument |
|
||||
| azure.cpp:287:79:287:98 | call to string | azure.cpp:287:62:287:99 | call to Url |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
| test.cpp:28:35:28:35 | 0 | test.cpp:28:11:28:33 | call to ymlStepManual_with_body |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
|
||||
|
||||
@@ -5586,3 +5586,6 @@
|
||||
| Unrecognized output specification "Field[***hEvent]" in summary model. |
|
||||
| Unrecognized output specification "Parameter[***0]" in summary model. |
|
||||
| Unrecognized output specification "Parameter[****0]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[*****]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[****]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[***]" in summary model. |
|
||||
|
||||
@@ -573,4 +573,165 @@ void test_copy_and_move_memory() {
|
||||
RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
using HINTERNET = void*;
|
||||
using ULONGLONG = unsigned long long;
|
||||
using UINT = unsigned int;
|
||||
using PDWORD = DWORD*;
|
||||
using PCSTR = const char*;
|
||||
typedef union _WINHTTP_HEADER_NAME {
|
||||
PCWSTR pwszName;
|
||||
PCSTR pszName;
|
||||
} WINHTTP_HEADER_NAME, *PWINHTTP_HEADER_NAME;
|
||||
typedef struct _WINHTTP_EXTENDED_HEADER {
|
||||
union {
|
||||
PCWSTR pwszName;
|
||||
PCSTR pszName;
|
||||
};
|
||||
union {
|
||||
PCWSTR pwszValue;
|
||||
PCSTR pszValue;
|
||||
};
|
||||
} WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER;
|
||||
|
||||
BOOL WinHttpReadData(
|
||||
HINTERNET hRequest,
|
||||
LPVOID lpBuffer,
|
||||
DWORD dwNumberOfBytesToRead,
|
||||
LPDWORD lpdwNumberOfBytesRead
|
||||
);
|
||||
|
||||
DWORD WinHttpReadDataEx(
|
||||
HINTERNET hRequest,
|
||||
LPVOID lpBuffer,
|
||||
DWORD dwNumberOfBytesToRead,
|
||||
LPDWORD lpdwNumberOfBytesRead,
|
||||
ULONGLONG ullFlags,
|
||||
DWORD cbProperty,
|
||||
PVOID pvProperty
|
||||
);
|
||||
|
||||
using LPCWSTR = const wchar_t*;
|
||||
|
||||
BOOL WinHttpQueryHeaders(
|
||||
HINTERNET hRequest,
|
||||
DWORD dwInfoLevel,
|
||||
LPCWSTR pwszName,
|
||||
LPVOID lpBuffer,
|
||||
LPDWORD lpdwBufferLength,
|
||||
LPDWORD lpdwIndex
|
||||
);
|
||||
|
||||
DWORD WinHttpQueryHeadersEx(
|
||||
HINTERNET hRequest,
|
||||
DWORD dwInfoLevel,
|
||||
ULONGLONG ullFlags,
|
||||
UINT uiCodePage,
|
||||
PDWORD pdwIndex,
|
||||
PWINHTTP_HEADER_NAME pHeaderName,
|
||||
PVOID pBuffer,
|
||||
PDWORD pdwBufferLength,
|
||||
PWINHTTP_EXTENDED_HEADER *ppHeaders,
|
||||
PDWORD pdwHeadersCount
|
||||
);
|
||||
|
||||
void sink(PCSTR);
|
||||
|
||||
void test_winhttp(HINTERNET hRequest) {
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
BOOL result = WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
DWORD result = WinHttpReadDataEx(hRequest, buffer, sizeof(buffer), &bytesRead, 0, 0, nullptr);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bufferLength = sizeof(buffer);
|
||||
WinHttpQueryHeaders(hRequest, 0, nullptr, buffer, &bufferLength, nullptr);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bufferLength = sizeof(buffer);
|
||||
PWINHTTP_EXTENDED_HEADER headers;
|
||||
DWORD headersCount;
|
||||
PWINHTTP_HEADER_NAME headerName;
|
||||
DWORD result = WinHttpQueryHeadersEx(hRequest, 0, 0, 0, nullptr, headerName, buffer, &bufferLength, &headers, &headersCount);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
sink(headerName->pszName);
|
||||
sink(*headerName->pszName); // $ ir
|
||||
sink(headers->pszValue);
|
||||
sink(*headers->pszValue); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
using LPWSTR = wchar_t*;
|
||||
using INTERNET_SCHEME = enum {
|
||||
INTERNET_SCHEME_INVALID = -1,
|
||||
INTERNET_SCHEME_UNKNOWN = 0,
|
||||
INTERNET_SCHEME_HTTP = 1,
|
||||
INTERNET_SCHEME_HTTPS = 2,
|
||||
INTERNET_SCHEME_FTP = 3,
|
||||
INTERNET_SCHEME_FILE = 4,
|
||||
INTERNET_SCHEME_NEWS = 5,
|
||||
INTERNET_SCHEME_MAILTO = 6,
|
||||
INTERNET_SCHEME_SNEWS = 7,
|
||||
INTERNET_SCHEME_SOCKS = 8,
|
||||
INTERNET_SCHEME_WAIS = 9,
|
||||
INTERNET_SCHEME_LAST = 10
|
||||
};
|
||||
using INTERNET_PORT = unsigned short;
|
||||
|
||||
typedef struct _WINHTTP_URL_COMPONENTS {
|
||||
DWORD dwStructSize;
|
||||
LPWSTR lpszScheme;
|
||||
DWORD dwSchemeLength;
|
||||
INTERNET_SCHEME nScheme;
|
||||
LPWSTR lpszHostName;
|
||||
DWORD dwHostNameLength;
|
||||
INTERNET_PORT nPort;
|
||||
LPWSTR lpszUserName;
|
||||
DWORD dwUserNameLength;
|
||||
LPWSTR lpszPassword;
|
||||
DWORD dwPasswordLength;
|
||||
LPWSTR lpszUrlPath;
|
||||
DWORD dwUrlPathLength;
|
||||
LPWSTR lpszExtraInfo;
|
||||
DWORD dwExtraInfoLength;
|
||||
} URL_COMPONENTS, *LPURL_COMPONENTS;
|
||||
|
||||
BOOL WinHttpCrackUrl(
|
||||
LPCWSTR pwszUrl,
|
||||
DWORD dwUrlLength,
|
||||
DWORD dwFlags,
|
||||
LPURL_COMPONENTS lpUrlComponents
|
||||
);
|
||||
|
||||
void sink(LPWSTR);
|
||||
|
||||
void test_winhttp_crack_url() {
|
||||
{
|
||||
URL_COMPONENTS urlComponents;
|
||||
urlComponents.dwStructSize = sizeof(URL_COMPONENTS);
|
||||
wchar_t x[256];
|
||||
x[0] = (wchar_t)source();
|
||||
BOOL result = WinHttpCrackUrl(x, 0, 0, &urlComponents);
|
||||
sink(urlComponents.lpszHostName);
|
||||
sink(*urlComponents.lpszHostName); // $ ir
|
||||
sink(urlComponents.lpszUrlPath);
|
||||
sink(*urlComponents.lpszUrlPath); // $ ir
|
||||
sink(urlComponents.lpszExtraInfo);
|
||||
sink(*urlComponents.lpszExtraInfo); // $ ir
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.58
|
||||
version: 1.7.59-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.58
|
||||
version: 1.7.59-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 5.4.6
|
||||
version: 5.4.7-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -54,12 +54,12 @@ predicate hasGlobalAntiForgeryFilter() {
|
||||
predicate isUnvalidatedPostMethod(Class c, Method m) {
|
||||
c.(Controller).getAPostActionMethod() = m and
|
||||
not m.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute and
|
||||
not c.getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute
|
||||
not c.getABaseType*().getAnAttribute() instanceof ValidateAntiForgeryTokenAttribute
|
||||
or
|
||||
c.(AspNetCore::MicrosoftAspNetCoreMvcController).getAnActionMethod() = m and
|
||||
m.getAnAttribute() instanceof AspNetCore::MicrosoftAspNetCoreMvcHttpPostAttribute and
|
||||
not m.getAnAttribute() instanceof AspNetCore::ValidateAntiForgeryAttribute and
|
||||
not c.getAnAttribute() instanceof AspNetCore::ValidateAntiForgeryAttribute
|
||||
not c.getABaseType*().getAnAttribute() instanceof AspNetCore::ValidateAntiForgeryAttribute
|
||||
}
|
||||
|
||||
Element getAValidatedElement() {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The `cs/web/missing-token-validation` ("Missing cross-site request forgery token validation") query now recognizes antiforgery attributes on base controller classes, fixing false positives when `[ValidateAntiForgeryToken]` or `[AutoValidateAntiforgeryToken]` is applied to a parent class.
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 1.6.1
|
||||
version: 1.6.2-dev
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -29,3 +29,34 @@ public class HomeController : Controller
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: Base class has AutoValidateAntiforgeryToken attribute
|
||||
[AutoValidateAntiforgeryToken]
|
||||
public abstract class BaseController : Controller
|
||||
{
|
||||
}
|
||||
|
||||
public class DerivedController : BaseController
|
||||
{
|
||||
// GOOD: Inherits antiforgery validation from base class
|
||||
[HttpPost]
|
||||
public ActionResult InheritedValidation()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: Base class without antiforgery attribute
|
||||
public abstract class UnprotectedBaseController : Controller
|
||||
{
|
||||
}
|
||||
|
||||
public class DerivedUnprotectedController : UnprotectedBaseController
|
||||
{
|
||||
// BAD: No antiforgery validation on this or any base class
|
||||
[HttpPost]
|
||||
public ActionResult NoInheritedValidation()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
| MissingAntiForgeryTokenValidation.cs:7:25:7:29 | Login | Method 'Login' handles a POST request without performing CSRF token validation. |
|
||||
| MissingAntiForgeryTokenValidation.cs:58:25:58:45 | NoInheritedValidation | Method 'NoInheritedValidation' handles a POST request without performing CSRF token validation. |
|
||||
|
||||
@@ -29,3 +29,34 @@ public class HomeController : Controller
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: Base class has ValidateAntiForgeryToken attribute
|
||||
[ValidateAntiForgeryToken]
|
||||
public abstract class BaseController : Controller
|
||||
{
|
||||
}
|
||||
|
||||
public class DerivedController : BaseController
|
||||
{
|
||||
// GOOD: Inherits antiforgery validation from base class
|
||||
[HttpPost]
|
||||
public ActionResult InheritedValidation()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: Base class without antiforgery attribute
|
||||
public abstract class UnprotectedBaseController : Controller
|
||||
{
|
||||
}
|
||||
|
||||
public class DerivedUnprotectedController : UnprotectedBaseController
|
||||
{
|
||||
// BAD: No antiforgery validation on this or any base class
|
||||
[HttpPost]
|
||||
public ActionResult NoInheritedValidation()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
| MissingAntiForgeryTokenValidation.cs:7:25:7:29 | Login | Method 'Login' handles a POST request without performing CSRF token validation. |
|
||||
| MissingAntiForgeryTokenValidation.cs:58:25:58:45 | NoInheritedValidation | Method 'NoInheritedValidation' handles a POST request without performing CSRF token validation. |
|
||||
|
||||
@@ -568,3 +568,25 @@ func EmitExtractionFailedForProjects(path []string) {
|
||||
noLocation,
|
||||
)
|
||||
}
|
||||
|
||||
func EmitPrivateRegistryUsed(writer DiagnosticsWriter, configs []string) {
|
||||
n := len(configs)
|
||||
lines := make([]string, n)
|
||||
|
||||
for i := range configs {
|
||||
lines[i] = fmt.Sprintf("* %s", configs[i])
|
||||
}
|
||||
|
||||
emitDiagnosticTo(
|
||||
writer,
|
||||
"go/autobuilder/analysis-using-private-registries",
|
||||
"Go extraction used private package registries",
|
||||
fmt.Sprintf(
|
||||
"Go was extracted using the following private package registr%s:\n\n%s\n",
|
||||
plural(n, "y", "ies"),
|
||||
strings.Join(lines, "\n")),
|
||||
severityNote,
|
||||
fullVisibility,
|
||||
noLocation,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -83,3 +83,46 @@ func Test_EmitCannotFindPackages_Actions(t *testing.T) {
|
||||
// Custom build command suggestion
|
||||
assert.Contains(t, d.MarkdownMessage, "If any of the packages are already present in the repository")
|
||||
}
|
||||
|
||||
func Test_EmitPrivateRegistryUsed_Single(t *testing.T) {
|
||||
writer := newMemoryDiagnosticsWriter()
|
||||
|
||||
testItems := []string{
|
||||
"https://github.com/github/example (Git Source)",
|
||||
}
|
||||
|
||||
EmitPrivateRegistryUsed(writer, testItems)
|
||||
|
||||
assert.Len(t, writer.diagnostics, 1, "Expected one diagnostic to be emitted")
|
||||
|
||||
d := writer.diagnostics[0]
|
||||
assert.Equal(t, d.Source.Id, "go/autobuilder/analysis-using-private-registries")
|
||||
assert.Equal(t, d.Severity, string(severityNote))
|
||||
assert.Contains(t, d.MarkdownMessage, "following private package registry")
|
||||
|
||||
for i := range testItems {
|
||||
assert.Contains(t, d.MarkdownMessage, testItems[i])
|
||||
}
|
||||
}
|
||||
|
||||
func Test_EmitPrivateRegistryUsed_Multiple(t *testing.T) {
|
||||
writer := newMemoryDiagnosticsWriter()
|
||||
|
||||
testItems := []string{
|
||||
"https://github.com/github/example (Git Source)",
|
||||
"https://example.com/goproxy (GOPROXY Server)",
|
||||
}
|
||||
|
||||
EmitPrivateRegistryUsed(writer, testItems)
|
||||
|
||||
assert.Len(t, writer.diagnostics, 1, "Expected one diagnostic to be emitted")
|
||||
|
||||
d := writer.diagnostics[0]
|
||||
assert.Equal(t, d.Source.Id, "go/autobuilder/analysis-using-private-registries")
|
||||
assert.Equal(t, d.Severity, string(severityNote))
|
||||
assert.Contains(t, d.MarkdownMessage, "following private package registries")
|
||||
|
||||
for i := range testItems {
|
||||
assert.Contains(t, d.MarkdownMessage, testItems[i])
|
||||
}
|
||||
}
|
||||
|
||||
17
go/extractor/registries/BUILD.bazel
generated
Normal file
17
go/extractor/registries/BUILD.bazel
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
# generated running `bazel run //go/gazelle`, do not edit
|
||||
|
||||
load("@rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "registries",
|
||||
srcs = ["registryproxy.go"],
|
||||
importpath = "github.com/github/codeql-go/extractor/registries",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//go/extractor/diagnostics"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "registries_test",
|
||||
srcs = ["registryproxy_test.go"],
|
||||
embed = [":registries"],
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package registries
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/github/codeql-go/extractor/diagnostics"
|
||||
)
|
||||
|
||||
const PROXY_HOST = "CODEQL_PROXY_HOST"
|
||||
@@ -22,6 +24,19 @@ type RegistryConfig struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (config *RegistryConfig) Pretty() string {
|
||||
pretty_type := "other"
|
||||
|
||||
switch config.Type {
|
||||
case GIT_SOURCE:
|
||||
pretty_type = "Git Source"
|
||||
case GOPROXY_SERVER:
|
||||
pretty_type = "GOPROXY Server"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("`%s` (%s)", config.URL, pretty_type)
|
||||
}
|
||||
|
||||
// The address of the proxy including protocol and port (e.g. http://localhost:1234)
|
||||
var proxy_address string
|
||||
|
||||
@@ -97,24 +112,40 @@ func getEnvVars() []string {
|
||||
if err != nil {
|
||||
slog.Error("Unable to parse proxy configurations", slog.String("error", err.Error()))
|
||||
} else {
|
||||
activeConfigs := make([]RegistryConfig, 0, len(val))
|
||||
|
||||
// We only care about private registry configurations that are relevant to Go and
|
||||
// filter others out at this point.
|
||||
for _, cfg := range val {
|
||||
if cfg.Type == GOPROXY_SERVER {
|
||||
goproxy_servers = append(goproxy_servers, cfg.URL)
|
||||
slog.Info("Found GOPROXY server", slog.String("url", cfg.URL))
|
||||
activeConfigs = append(activeConfigs, cfg)
|
||||
} else if cfg.Type == GIT_SOURCE {
|
||||
parsed, err := url.Parse(cfg.URL)
|
||||
if err == nil && parsed.Hostname() != "" {
|
||||
git_source := parsed.Hostname() + parsed.Path + "*"
|
||||
git_sources = append(git_sources, git_source)
|
||||
slog.Info("Found Git source", slog.String("source", git_source))
|
||||
activeConfigs = append(activeConfigs, cfg)
|
||||
} else {
|
||||
slog.Warn("Not a valid URL for Git source", slog.String("url", cfg.URL))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit a diagnostic to make it easy for users to see that private registry
|
||||
// configurations were picked up by the Go analysis.
|
||||
if len(activeConfigs) > 0 {
|
||||
prettyConfigs := []string{}
|
||||
for i := range activeConfigs {
|
||||
prettyConfigs = append(prettyConfigs, activeConfigs[i].Pretty())
|
||||
}
|
||||
|
||||
diagnostics.EmitPrivateRegistryUsed(diagnostics.DefaultWriter, prettyConfigs)
|
||||
}
|
||||
|
||||
// Assemble environment variables for Go.
|
||||
goprivate := []string{}
|
||||
|
||||
if len(goproxy_servers) > 0 {
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package registries
|
||||
|
||||
import (
|
||||
"testing"
|
||||
5
go/extractor/toolchain/BUILD.bazel
generated
5
go/extractor/toolchain/BUILD.bazel
generated
@@ -7,7 +7,10 @@ go_library(
|
||||
srcs = ["toolchain.go"],
|
||||
importpath = "github.com/github/codeql-go/extractor/toolchain",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//go/extractor/util"],
|
||||
deps = [
|
||||
"//go/extractor/registries",
|
||||
"//go/extractor/util",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/github/codeql-go/extractor/registries"
|
||||
"github.com/github/codeql-go/extractor/util"
|
||||
)
|
||||
|
||||
@@ -140,7 +141,7 @@ func SupportsWorkspaces() bool {
|
||||
// Constructs a `*exec.Cmd` for `go` with the specified arguments.
|
||||
func GoCommand(arg ...string) *exec.Cmd {
|
||||
cmd := exec.Command("go", arg...)
|
||||
util.ApplyProxyEnvVars(cmd)
|
||||
registries.ApplyProxyEnvVars(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
2
go/extractor/util/BUILD.bazel
generated
2
go/extractor/util/BUILD.bazel
generated
@@ -8,7 +8,6 @@ go_library(
|
||||
"extractvendordirs.go",
|
||||
"logging.go",
|
||||
"overlays.go",
|
||||
"registryproxy.go",
|
||||
"semver.go",
|
||||
"util.go",
|
||||
],
|
||||
@@ -21,7 +20,6 @@ go_test(
|
||||
name = "util_test",
|
||||
srcs = [
|
||||
"logging_test.go",
|
||||
"registryproxy_test.go",
|
||||
"semver_test.go",
|
||||
"util_test.go",
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql-go-consistency-queries
|
||||
version: 1.0.41
|
||||
version: 1.0.42-dev
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The `BasicBlock` class is now defined using the shared basic blocks library. `BasicBlock.getRoot` has been replaced by `BasicBlock.getScope`. `BasicBlock.getAPredecessor` and `BasicBlock.getASuccessor` now take a `SuccessorType` argument. `ReachableJoinBlock.inDominanceFrontierOf` has been removed, so use `BasicBlock.inDominanceFrontier` instead, swapping the receiver and the argument.
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-all
|
||||
version: 6.0.1
|
||||
version: 6.0.2-dev
|
||||
groups: go
|
||||
dbscheme: go.dbscheme
|
||||
extractor: go
|
||||
@@ -7,6 +7,7 @@ library: true
|
||||
upgrades: upgrades
|
||||
dependencies:
|
||||
codeql/concepts: ${workspace}
|
||||
codeql/controlflow: ${workspace}
|
||||
codeql/dataflow: ${workspace}
|
||||
codeql/mad: ${workspace}
|
||||
codeql/threat-models: ${workspace}
|
||||
|
||||
@@ -4,140 +4,53 @@
|
||||
|
||||
import go
|
||||
private import ControlFlowGraphImpl
|
||||
private import codeql.controlflow.BasicBlock as BB
|
||||
private import codeql.controlflow.SuccessorType
|
||||
|
||||
/**
|
||||
* Holds if `nd` starts a new basic block.
|
||||
*/
|
||||
private predicate startsBB(ControlFlow::Node nd) {
|
||||
count(nd.getAPredecessor()) != 1
|
||||
private module Input implements BB::InputSig<Location> {
|
||||
/** A delineated part of the AST with its own CFG. */
|
||||
class CfgScope = ControlFlow::Root;
|
||||
|
||||
/** The class of control flow nodes. */
|
||||
class Node = ControlFlowNode;
|
||||
|
||||
/** Gets the CFG scope in which this node occurs. */
|
||||
CfgScope nodeGetCfgScope(Node node) { node.getRoot() = result }
|
||||
|
||||
/** Gets an immediate successor of this node. */
|
||||
Node nodeGetASuccessor(Node node, SuccessorType t) {
|
||||
result = node.getASuccessor() and
|
||||
(
|
||||
not result instanceof ControlFlow::ConditionGuardNode and t instanceof DirectSuccessor
|
||||
or
|
||||
t.(BooleanSuccessor).getValue() = result.(ControlFlow::ConditionGuardNode).getOutcome()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` represents an entry node to be used when calculating
|
||||
* dominance.
|
||||
*/
|
||||
predicate nodeIsDominanceEntry(Node node) { node instanceof EntryNode }
|
||||
|
||||
/**
|
||||
* Holds if `node` represents an exit node to be used when calculating
|
||||
* post dominance.
|
||||
*/
|
||||
predicate nodeIsPostDominanceExit(Node node) { node instanceof ExitNode }
|
||||
}
|
||||
|
||||
private module BbImpl = BB::Make<Location, Input>;
|
||||
|
||||
class BasicBlock = BbImpl::BasicBlock;
|
||||
|
||||
class EntryBasicBlock = BbImpl::EntryBasicBlock;
|
||||
|
||||
cached
|
||||
private predicate reachableBB(BasicBlock bb) {
|
||||
bb instanceof EntryBasicBlock
|
||||
or
|
||||
nd.getAPredecessor().isBranch()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the first node of basic block `succ` is a control flow
|
||||
* successor of the last node of basic block `bb`.
|
||||
*/
|
||||
private predicate succBB(BasicBlock bb, BasicBlock succ) { succ = bb.getLastNode().getASuccessor() }
|
||||
|
||||
/**
|
||||
* Holds if the first node of basic block `bb` is a control flow
|
||||
* successor of the last node of basic block `pre`.
|
||||
*/
|
||||
private predicate predBB(BasicBlock bb, BasicBlock pre) { succBB(pre, bb) }
|
||||
|
||||
/** Holds if `bb` is an entry basic block. */
|
||||
private predicate entryBB(BasicBlock bb) { bb.getFirstNode().isEntryNode() }
|
||||
|
||||
/** Holds if `bb` is an exit basic block. */
|
||||
private predicate exitBB(BasicBlock bb) { bb.getLastNode().isExitNode() }
|
||||
|
||||
cached
|
||||
private module Internal {
|
||||
/**
|
||||
* Holds if `succ` is a control flow successor of `nd` within the same basic block.
|
||||
*/
|
||||
private predicate intraBBSucc(ControlFlow::Node nd, ControlFlow::Node succ) {
|
||||
succ = nd.getASuccessor() and
|
||||
not startsBB(succ)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nd` is the `i`th node in basic block `bb`.
|
||||
*
|
||||
* In other words, `i` is the shortest distance from a node `bb`
|
||||
* that starts a basic block to `nd` along the `intraBBSucc` relation.
|
||||
*/
|
||||
cached
|
||||
predicate bbIndex(BasicBlock bb, ControlFlow::Node nd, int i) =
|
||||
shortestDistances(startsBB/1, intraBBSucc/2)(bb, nd, i)
|
||||
|
||||
cached
|
||||
int bbLength(BasicBlock bb) { result = strictcount(ControlFlow::Node nd | bbIndex(bb, nd, _)) }
|
||||
|
||||
cached
|
||||
predicate reachableBB(BasicBlock bb) {
|
||||
entryBB(bb)
|
||||
or
|
||||
exists(BasicBlock predBB | succBB(predBB, bb) | reachableBB(predBB))
|
||||
}
|
||||
}
|
||||
|
||||
private import Internal
|
||||
|
||||
/** Holds if `dom` is an immediate dominator of `bb`. */
|
||||
cached
|
||||
private predicate bbIDominates(BasicBlock dom, BasicBlock bb) =
|
||||
idominance(entryBB/1, succBB/2)(_, dom, bb)
|
||||
|
||||
/** Holds if `dom` is an immediate post-dominator of `bb`. */
|
||||
cached
|
||||
private predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) =
|
||||
idominance(exitBB/1, predBB/2)(_, dom, bb)
|
||||
|
||||
/**
|
||||
* A basic block, that is, a maximal straight-line sequence of control flow nodes
|
||||
* without branches or joins.
|
||||
*
|
||||
* At the database level, a basic block is represented by its first control flow node.
|
||||
*/
|
||||
class BasicBlock extends TControlFlowNode {
|
||||
BasicBlock() { startsBB(this) }
|
||||
|
||||
/** Gets a basic block succeeding this one. */
|
||||
BasicBlock getASuccessor() { succBB(this, result) }
|
||||
|
||||
/** Gets a basic block preceding this one. */
|
||||
BasicBlock getAPredecessor() { result.getASuccessor() = this }
|
||||
|
||||
/** Gets a node in this block. */
|
||||
ControlFlow::Node getANode() { result = this.getNode(_) }
|
||||
|
||||
/** Gets the node at the given position in this block. */
|
||||
ControlFlow::Node getNode(int pos) { bbIndex(this, result, pos) }
|
||||
|
||||
/** Gets the first node in this block. */
|
||||
ControlFlow::Node getFirstNode() { result = this }
|
||||
|
||||
/** Gets the last node in this block. */
|
||||
ControlFlow::Node getLastNode() { result = this.getNode(this.length() - 1) }
|
||||
|
||||
/** Gets the length of this block. */
|
||||
int length() { result = bbLength(this) }
|
||||
|
||||
/** Gets the basic block that immediately dominates this basic block. */
|
||||
ReachableBasicBlock getImmediateDominator() { bbIDominates(result, this) }
|
||||
|
||||
/** Gets the innermost function or file to which this basic block belongs. */
|
||||
ControlFlow::Root getRoot() { result = this.getFirstNode().getRoot() }
|
||||
|
||||
/** Gets a textual representation of this basic block. */
|
||||
string toString() { result = "basic block" }
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() { result = this.getFirstNode().getLocation() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getLocation()` instead.
|
||||
*
|
||||
* Holds if this basic block is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
deprecated predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An entry basic block, that is, a basic block whose first node is an entry node.
|
||||
*/
|
||||
class EntryBasicBlock extends BasicBlock {
|
||||
EntryBasicBlock() { entryBB(this) }
|
||||
exists(BasicBlock predBB | predBB.getASuccessor(_) = bb | reachableBB(predBB))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,38 +58,6 @@ class EntryBasicBlock extends BasicBlock {
|
||||
*/
|
||||
class ReachableBasicBlock extends BasicBlock {
|
||||
ReachableBasicBlock() { reachableBB(this) }
|
||||
|
||||
/**
|
||||
* Holds if this basic block strictly dominates `bb`.
|
||||
*/
|
||||
cached
|
||||
predicate strictlyDominates(ReachableBasicBlock bb) { bbIDominates+(this, bb) }
|
||||
|
||||
/**
|
||||
* Holds if this basic block dominates `bb`.
|
||||
*
|
||||
* This predicate is reflexive: each reachable basic block dominates itself.
|
||||
*/
|
||||
predicate dominates(ReachableBasicBlock bb) {
|
||||
bb = this or
|
||||
this.strictlyDominates(bb)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this basic block strictly post-dominates `bb`.
|
||||
*/
|
||||
cached
|
||||
predicate strictlyPostDominates(ReachableBasicBlock bb) { bbIPostDominates+(this, bb) }
|
||||
|
||||
/**
|
||||
* Holds if this basic block post-dominates `bb`.
|
||||
*
|
||||
* This predicate is reflexive: each reachable basic block post-dominates itself.
|
||||
*/
|
||||
predicate postDominates(ReachableBasicBlock bb) {
|
||||
bb = this or
|
||||
this.strictlyPostDominates(bb)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,21 +65,4 @@ class ReachableBasicBlock extends BasicBlock {
|
||||
*/
|
||||
class ReachableJoinBlock extends ReachableBasicBlock {
|
||||
ReachableJoinBlock() { this.getFirstNode().isJoin() }
|
||||
|
||||
/**
|
||||
* Holds if this basic block belongs to the dominance frontier of `b`, that is
|
||||
* `b` dominates a predecessor of this block, but not this block itself.
|
||||
*
|
||||
* Algorithm from Cooper et al., "A Simple, Fast Dominance Algorithm" (Figure 5),
|
||||
* who in turn attribute it to Ferrante et al., "The program dependence graph and
|
||||
* its use in optimization".
|
||||
*/
|
||||
predicate inDominanceFrontierOf(ReachableBasicBlock b) {
|
||||
b = this.getAPredecessor() and not b = this.getImmediateDominator()
|
||||
or
|
||||
exists(ReachableBasicBlock prev | this.inDominanceFrontierOf(prev) |
|
||||
b = prev.getImmediateDominator() and
|
||||
not b = this.getImmediateDominator()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +313,9 @@ module ControlFlow {
|
||||
*/
|
||||
Expr getCondition() { result = cond }
|
||||
|
||||
/** Gets the value of the condition that this node corresponds to. */
|
||||
boolean getOutcome() { result = outcome }
|
||||
|
||||
override Root getRoot() { result.isRootOf(cond) }
|
||||
|
||||
override string toString() { result = cond + " is " + outcome }
|
||||
@@ -350,4 +353,6 @@ module ControlFlow {
|
||||
}
|
||||
}
|
||||
|
||||
class ControlFlowNode = ControlFlow::Node;
|
||||
|
||||
class Write = ControlFlow::WriteNode;
|
||||
|
||||
@@ -144,7 +144,7 @@ class SsaDefinition extends TSsaDefinition {
|
||||
abstract string prettyPrintRef();
|
||||
|
||||
/** Gets the innermost function or file to which this SSA definition belongs. */
|
||||
ControlFlow::Root getRoot() { result = this.getBasicBlock().getRoot() }
|
||||
ControlFlow::Root getRoot() { result = this.getBasicBlock().getScope() }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.prettyPrintDef() }
|
||||
@@ -285,7 +285,7 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
|
||||
*/
|
||||
class SsaPhiNode extends SsaPseudoDefinition, TPhi {
|
||||
override SsaVariable getAnInput() {
|
||||
result = getDefReachingEndOf(this.getBasicBlock().getAPredecessor(), this.getSourceVariable())
|
||||
result = getDefReachingEndOf(this.getBasicBlock().getAPredecessor(_), this.getSourceVariable())
|
||||
}
|
||||
|
||||
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
|
||||
|
||||
@@ -71,7 +71,7 @@ private module Internal {
|
||||
private predicate inDefDominanceFrontier(ReachableJoinBlock bb, SsaSourceVariable v) {
|
||||
exists(ReachableBasicBlock defbb, SsaDefinition def |
|
||||
def.definesAt(defbb, _, v) and
|
||||
bb.inDominanceFrontierOf(defbb)
|
||||
defbb.inDominanceFrontier(bb)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ private module Internal {
|
||||
|
||||
/** Holds if the `i`th node of `bb` in function `f` is an entry node. */
|
||||
private predicate entryNode(FuncDef f, ReachableBasicBlock bb, int i) {
|
||||
f = bb.getRoot() and
|
||||
f = bb.getScope() and
|
||||
bb.getNode(i).isEntryNode()
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ private module Internal {
|
||||
* Holds if the `i`th node of `bb` in function `f` is a function call.
|
||||
*/
|
||||
private predicate callNode(FuncDef f, ReachableBasicBlock bb, int i) {
|
||||
f = bb.getRoot() and
|
||||
f = bb.getScope() and
|
||||
bb.getNode(i).(IR::EvalInstruction).getExpr() instanceof CallExpr
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ private module Internal {
|
||||
* Holds if `v` is live at the beginning of any successor of basic block `bb`.
|
||||
*/
|
||||
private predicate liveAtSuccEntry(ReachableBasicBlock bb, SsaSourceVariable v) {
|
||||
liveAtEntry(bb.getASuccessor(), v)
|
||||
liveAtEntry(bb.getASuccessor(_), v)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +317,7 @@ private module Internal {
|
||||
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2
|
||||
) {
|
||||
varOccursInBlock(v, b1) and
|
||||
b2 = b1.getASuccessor()
|
||||
b2 = b1.getASuccessor(_)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,7 +335,7 @@ private module Internal {
|
||||
) {
|
||||
varBlockReaches(v, b1, mid) and
|
||||
not varOccursInBlock(v, mid) and
|
||||
b2 = mid.getASuccessor()
|
||||
b2 = mid.getASuccessor(_)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,7 +45,7 @@ predicate writesHttpError(ReachableBasicBlock b) {
|
||||
predicate onlyErrors(BasicBlock block) {
|
||||
writesHttpError(block)
|
||||
or
|
||||
forex(ReachableBasicBlock pred | pred = block.getAPredecessor() | onlyErrors(pred))
|
||||
forex(ReachableBasicBlock pred | pred = block.getAPredecessor(_) | onlyErrors(pred))
|
||||
}
|
||||
|
||||
/** Gets a node that refers to a handler that is considered to return an HTTP error. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-queries
|
||||
version: 1.5.5
|
||||
version: 1.5.6-dev
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -2,7 +2,7 @@ import java
|
||||
|
||||
from UnaryExpr ue
|
||||
where
|
||||
not exists(ue.getExpr())
|
||||
not exists(ue.getOperand())
|
||||
or
|
||||
exists(Expr e, int i | e.isNthChildOf(ue, i) and i != 0)
|
||||
select ue
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
import java
|
||||
|
||||
from ReturnStmt r
|
||||
where r.getResult() instanceof NullLiteral
|
||||
where r.getExpr() instanceof NullLiteral
|
||||
select r
|
||||
|
||||
@@ -11,7 +11,7 @@ import java
|
||||
|
||||
from ConditionalExpr e
|
||||
where
|
||||
e.getTrueExpr().getType() != e.getFalseExpr().getType() and
|
||||
not e.getTrueExpr().getType() instanceof NullType and
|
||||
not e.getFalseExpr().getType() instanceof NullType
|
||||
e.getThen().getType() != e.getElse().getType() and
|
||||
not e.getThen().getType() instanceof NullType and
|
||||
not e.getElse().getType() instanceof NullType
|
||||
select e
|
||||
|
||||
12
java/ql/lib/change-notes/2026-02-04-renames.md
Normal file
12
java/ql/lib/change-notes/2026-02-04-renames.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* Renamed the following predicates to increase uniformity across languages. The `getBody` predicate already existed on `LoopStmt`, but is now properly inherited.
|
||||
- `UnaryExpr.getExpr` to `getOperand`.
|
||||
- `ConditionalExpr.getTrueExpr` to `getThen`.
|
||||
- `ConditionalExpr.getFalseExpr` to `getElse`.
|
||||
- `ReturnStmt.getResult` to `getExpr`.
|
||||
- `WhileStmt.getStmt` to `getBody`.
|
||||
- `DoStmt.getStmt` to `getBody`.
|
||||
- `ForStmt.getStmt` to `getBody`.
|
||||
- `EnhancedForStmt.getStmt` to `getBody`.
|
||||
45
java/ql/lib/printCfg.ql
Normal file
45
java/ql/lib/printCfg.ql
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @name Print CFG
|
||||
* @description Produces a representation of a file's Control Flow Graph.
|
||||
* This query is used by the VS Code extension.
|
||||
* @id java/print-cfg
|
||||
* @kind graph
|
||||
* @tags ide-contextual-queries/print-cfg
|
||||
*/
|
||||
|
||||
import java
|
||||
|
||||
external string selectedSourceFile();
|
||||
|
||||
private predicate selectedSourceFileAlias = selectedSourceFile/0;
|
||||
|
||||
external int selectedSourceLine();
|
||||
|
||||
private predicate selectedSourceLineAlias = selectedSourceLine/0;
|
||||
|
||||
external int selectedSourceColumn();
|
||||
|
||||
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
|
||||
|
||||
module ViewCfgQueryInput implements ViewCfgQueryInputSig<File> {
|
||||
predicate selectedSourceFile = selectedSourceFileAlias/0;
|
||||
|
||||
predicate selectedSourceLine = selectedSourceLineAlias/0;
|
||||
|
||||
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
|
||||
|
||||
predicate cfgScopeSpan(
|
||||
Callable callable, File file, int startLine, int startColumn, int endLine, int endColumn
|
||||
) {
|
||||
file = callable.getFile() and
|
||||
callable.getLocation().getStartLine() = startLine and
|
||||
callable.getLocation().getStartColumn() = startColumn and
|
||||
exists(Location loc |
|
||||
loc.getEndLine() = endLine and
|
||||
loc.getEndColumn() = endColumn and
|
||||
loc = callable.getBody().getLocation()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import ViewCfgQuery<File, ViewCfgQueryInput>
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-all
|
||||
version: 8.0.0
|
||||
version: 8.0.1-dev
|
||||
groups: java
|
||||
dbscheme: config/semmlecode.dbscheme
|
||||
extractor: java
|
||||
|
||||
@@ -22,7 +22,7 @@ module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal>
|
||||
boolean calculateBooleanValue(Expr e) {
|
||||
// No casts relevant to booleans.
|
||||
// `!` is the only unary operator that evaluates to a boolean.
|
||||
result = getBoolVal(e.(LogNotExpr).getExpr()).booleanNot()
|
||||
result = getBoolVal(e.(LogNotExpr).getOperand()).booleanNot()
|
||||
or
|
||||
// Handle binary expressions that have integer operands and a boolean result.
|
||||
exists(BinaryExpr b, int left, int right |
|
||||
@@ -115,11 +115,11 @@ module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal>
|
||||
else result = val
|
||||
)
|
||||
or
|
||||
result = getIntVal(e.(PlusExpr).getExpr())
|
||||
result = getIntVal(e.(PlusExpr).getOperand())
|
||||
or
|
||||
result = -getIntVal(e.(MinusExpr).getExpr())
|
||||
result = -getIntVal(e.(MinusExpr).getOperand())
|
||||
or
|
||||
result = getIntVal(e.(BitNotExpr).getExpr()).bitNot()
|
||||
result = getIntVal(e.(BitNotExpr).getOperand()).bitNot()
|
||||
or
|
||||
// No `int` value for `LogNotExpr`.
|
||||
exists(BinaryExpr b, int v1, int v2 |
|
||||
|
||||
@@ -827,7 +827,7 @@ private module ControlFlowGraphImpl {
|
||||
index = 1 and result = e.getRightOperand()
|
||||
)
|
||||
or
|
||||
index = 0 and result = this.(UnaryExpr).getExpr()
|
||||
index = 0 and result = this.(UnaryExpr).getOperand()
|
||||
or
|
||||
index = 0 and result = this.(CastingExpr).getExpr()
|
||||
or
|
||||
@@ -849,7 +849,7 @@ private module ControlFlowGraphImpl {
|
||||
or
|
||||
index = 0 and result = this.(ClassExpr).getExpr()
|
||||
or
|
||||
index = 0 and result = this.(ReturnStmt).getResult()
|
||||
index = 0 and result = this.(ReturnStmt).getExpr()
|
||||
or
|
||||
index = 0 and result = this.(ThrowStmt).getExpr()
|
||||
or
|
||||
@@ -1044,7 +1044,7 @@ private module ControlFlowGraphImpl {
|
||||
or
|
||||
// The last node of a `LogNotExpr` is in its sub-expression with an inverted boolean completion
|
||||
// (or a `normalCompletion`).
|
||||
exists(Completion subcompletion | last(n.(LogNotExpr).getExpr(), last, subcompletion) |
|
||||
exists(Completion subcompletion | last(n.(LogNotExpr).getOperand(), last, subcompletion) |
|
||||
subcompletion = NormalCompletion() and
|
||||
completion = NormalCompletion() and
|
||||
not inBooleanContext(n)
|
||||
@@ -1356,7 +1356,7 @@ private module ControlFlowGraphImpl {
|
||||
(
|
||||
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().(LogNotExpr).getOperand()) or
|
||||
result = first(n.asExpr().(ConditionalExpr).getCondition())
|
||||
)
|
||||
or
|
||||
@@ -1427,7 +1427,7 @@ private module ControlFlowGraphImpl {
|
||||
condentry = first(for.getCondition())
|
||||
or
|
||||
// ...or the body if the for doesn't include a condition.
|
||||
not exists(for.getCondition()) and condentry = first(for.getStmt())
|
||||
not exists(for.getCondition()) and condentry = first(for.getBody())
|
||||
|
|
||||
// From the entry point, which is the for statement itself, control goes to either the first init expression...
|
||||
n.asStmt() = for and result = first(for.getInit(0)) and completion = NormalCompletion()
|
||||
@@ -1448,7 +1448,7 @@ private module ControlFlowGraphImpl {
|
||||
// The true-successor of the condition is the body of the for loop.
|
||||
last(for.getCondition(), n, completion) and
|
||||
completion = BooleanCompletion(true, _) and
|
||||
result = first(for.getStmt())
|
||||
result = first(for.getBody())
|
||||
or
|
||||
// The updates execute sequentially, after which control is transferred to the condition.
|
||||
exists(int i | last(for.getUpdate(i), n, completion) and completion = NormalCompletion() |
|
||||
@@ -1458,7 +1458,7 @@ private module ControlFlowGraphImpl {
|
||||
)
|
||||
or
|
||||
// The back edge of the loop: control goes to either the first update or the condition if no updates exist.
|
||||
last(for.getStmt(), n, completion) and
|
||||
last(for.getBody(), n, completion) and
|
||||
continues(completion, for) and
|
||||
(
|
||||
result = first(for.getUpdate(0))
|
||||
@@ -1479,11 +1479,11 @@ private module ControlFlowGraphImpl {
|
||||
or
|
||||
// ...and then control goes to the body of the loop.
|
||||
n.asExpr() = for.getVariable() and
|
||||
result = first(for.getStmt()) and
|
||||
result = first(for.getBody()) and
|
||||
completion = NormalCompletion()
|
||||
or
|
||||
// Finally, the back edge of the loop goes to reassign the variable.
|
||||
last(for.getStmt(), n, completion) and
|
||||
last(for.getBody(), n, completion) and
|
||||
continues(completion, for) and
|
||||
result.asExpr() = for.getVariable()
|
||||
)
|
||||
@@ -1492,7 +1492,7 @@ private module ControlFlowGraphImpl {
|
||||
result = first(n.asStmt().(WhileStmt).getCondition()) and completion = NormalCompletion()
|
||||
or
|
||||
// ...and do-while loops start at the body.
|
||||
result = first(n.asStmt().(DoStmt).getStmt()) and completion = NormalCompletion()
|
||||
result = first(n.asStmt().(DoStmt).getBody()) 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...
|
||||
@@ -1775,3 +1775,17 @@ class ConditionNode extends ControlFlow::Node {
|
||||
/** Gets the condition of this `ConditionNode`. */
|
||||
ExprParent getCondition() { result = this.asExpr() or result = this.asStmt() }
|
||||
}
|
||||
|
||||
private import codeql.controlflow.PrintGraph as PrintGraph
|
||||
|
||||
private module PrintGraphInput implements PrintGraph::InputSig<Location> {
|
||||
private import java as J
|
||||
|
||||
class Callable = J::Callable;
|
||||
|
||||
class ControlFlowNode = J::ControlFlowNode;
|
||||
|
||||
ControlFlowNode getASuccessor(ControlFlowNode n, SuccessorType t) { result = n.getASuccessor(t) }
|
||||
}
|
||||
|
||||
import PrintGraph::PrintGraph<Location, PrintGraphInput>
|
||||
|
||||
@@ -69,7 +69,7 @@ class AssignmentConversionContext extends ConversionSite {
|
||||
class ReturnConversionSite extends ConversionSite {
|
||||
ReturnStmt r;
|
||||
|
||||
ReturnConversionSite() { this = r.getResult() }
|
||||
ReturnConversionSite() { this = r.getExpr() }
|
||||
|
||||
override Type getConversionTarget() { result = r.getEnclosingCallable().getReturnType() }
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ class Expr extends ExprParent, @expr {
|
||||
if this instanceof CastingExpr or this instanceof NotNullExpr
|
||||
then
|
||||
result = this.(CastingExpr).getExpr().getUnderlyingExpr() or
|
||||
result = this.(NotNullExpr).getExpr().getUnderlyingExpr()
|
||||
result = this.(NotNullExpr).getOperand().getUnderlyingExpr()
|
||||
else result = this
|
||||
}
|
||||
}
|
||||
@@ -144,13 +144,13 @@ class CompileTimeConstantExpr extends Expr {
|
||||
this.(CastingExpr).getExpr().isCompileTimeConstant()
|
||||
or
|
||||
// The unary operators `+`, `-`, `~`, and `!` (but not `++` or `--`).
|
||||
this.(PlusExpr).getExpr().isCompileTimeConstant()
|
||||
this.(PlusExpr).getOperand().isCompileTimeConstant()
|
||||
or
|
||||
this.(MinusExpr).getExpr().isCompileTimeConstant()
|
||||
this.(MinusExpr).getOperand().isCompileTimeConstant()
|
||||
or
|
||||
this.(BitNotExpr).getExpr().isCompileTimeConstant()
|
||||
this.(BitNotExpr).getOperand().isCompileTimeConstant()
|
||||
or
|
||||
this.(LogNotExpr).getExpr().isCompileTimeConstant()
|
||||
this.(LogNotExpr).getOperand().isCompileTimeConstant()
|
||||
or
|
||||
// The multiplicative operators `*`, `/`, and `%`,
|
||||
// the additive operators `+` and `-`,
|
||||
@@ -166,8 +166,8 @@ class CompileTimeConstantExpr extends Expr {
|
||||
// The ternary conditional operator ` ? : `.
|
||||
exists(ConditionalExpr e | this = e |
|
||||
e.getCondition().isCompileTimeConstant() and
|
||||
e.getTrueExpr().isCompileTimeConstant() and
|
||||
e.getFalseExpr().isCompileTimeConstant()
|
||||
e.getThen().isCompileTimeConstant() and
|
||||
e.getElse().isCompileTimeConstant()
|
||||
)
|
||||
or
|
||||
// Access to a final variable initialized by a compile-time constant.
|
||||
@@ -943,7 +943,7 @@ class LogicExpr extends Expr {
|
||||
/** Gets an operand of this logical expression. */
|
||||
Expr getAnOperand() {
|
||||
this.(BinaryExpr).getAnOperand() = result or
|
||||
this.(UnaryExpr).getExpr() = result
|
||||
this.(UnaryExpr).getOperand() = result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1039,8 +1039,15 @@ class ReferenceEqualityTest extends EqualityTest {
|
||||
|
||||
/** A common super-class that represents unary operator expressions. */
|
||||
class UnaryExpr extends Expr, @unaryexpr {
|
||||
/**
|
||||
* DEPRECATED: Use `getOperand()` instead.
|
||||
*
|
||||
* Gets the operand expression.
|
||||
*/
|
||||
deprecated Expr getExpr() { result.getParent() = this }
|
||||
|
||||
/** Gets the operand expression. */
|
||||
Expr getExpr() { result.getParent() = this }
|
||||
Expr getOperand() { result.getParent() = this }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1305,7 +1312,7 @@ class LambdaExpr extends FunctionalExpr, @lambdaexpr {
|
||||
|
||||
/** Gets the body of this lambda expression, if it is an expression. */
|
||||
Expr getExprBody() {
|
||||
this.hasExprBody() and result = this.asMethod().getBody().getAChild().(ReturnStmt).getResult()
|
||||
this.hasExprBody() and result = this.asMethod().getBody().getAChild().(ReturnStmt).getExpr()
|
||||
}
|
||||
|
||||
/** Gets the body of this lambda expression, if it is a statement. */
|
||||
@@ -1340,7 +1347,7 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
|
||||
exists(Stmt stmt |
|
||||
stmt = this.asMethod().getBody().(SingletonBlock).getStmt() and
|
||||
(
|
||||
result = stmt.(ReturnStmt).getResult()
|
||||
result = stmt.(ReturnStmt).getExpr()
|
||||
or
|
||||
// Note: Currently never an ExprStmt, but might change once https://github.com/github/codeql/issues/3605 is fixed
|
||||
result = stmt.(ExprStmt).getExpr()
|
||||
@@ -1457,26 +1464,42 @@ class ConditionalExpr extends Expr, @conditionalexpr {
|
||||
Expr getCondition() { result.isNthChildOf(this, 0) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getThen()` instead.
|
||||
*
|
||||
* Gets the expression that is evaluated if the condition of this
|
||||
* conditional expression evaluates to `true`.
|
||||
*/
|
||||
Expr getTrueExpr() { result.isNthChildOf(this, 1) }
|
||||
deprecated Expr getTrueExpr() { result.isNthChildOf(this, 1) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getElse()` instead.
|
||||
*
|
||||
* Gets the expression that is evaluated if the condition of this
|
||||
* conditional expression evaluates to `false`.
|
||||
*/
|
||||
deprecated Expr getFalseExpr() { result.isNthChildOf(this, 2) }
|
||||
|
||||
/**
|
||||
* Gets the expression that is evaluated if the condition of this
|
||||
* conditional expression evaluates to `true`.
|
||||
*/
|
||||
Expr getThen() { result.isNthChildOf(this, 1) }
|
||||
|
||||
/**
|
||||
* Gets the expression that is evaluated if the condition of this
|
||||
* conditional expression evaluates to `false`.
|
||||
*/
|
||||
Expr getFalseExpr() { result.isNthChildOf(this, 2) }
|
||||
Expr getElse() { result.isNthChildOf(this, 2) }
|
||||
|
||||
/**
|
||||
* Gets the expression that is evaluated by the specific branch of this
|
||||
* conditional expression. If `true` that is `getTrueExpr()`, if `false`
|
||||
* it is `getFalseExpr()`.
|
||||
* conditional expression. If `true` that is `getThen()`, if `false`
|
||||
* it is `getElse()`.
|
||||
*/
|
||||
Expr getBranchExpr(boolean branch) {
|
||||
branch = true and result = this.getTrueExpr()
|
||||
branch = true and result = this.getThen()
|
||||
or
|
||||
branch = false and result = this.getFalseExpr()
|
||||
branch = false and result = this.getElse()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1773,14 +1796,14 @@ class VariableUpdate extends Expr {
|
||||
VariableUpdate() {
|
||||
this.(Assignment).getDest() instanceof VarAccess or
|
||||
this instanceof LocalVariableDeclExpr or
|
||||
this.(UnaryAssignExpr).getExpr() instanceof VarAccess
|
||||
this.(UnaryAssignExpr).getOperand() instanceof VarAccess
|
||||
}
|
||||
|
||||
/** Gets the destination of this variable update. */
|
||||
Variable getDestVar() {
|
||||
result.getAnAccess() = this.(Assignment).getDest() or
|
||||
result = this.(LocalVariableDeclExpr).getVariable() or
|
||||
result.getAnAccess() = this.(UnaryAssignExpr).getExpr()
|
||||
result.getAnAccess() = this.(UnaryAssignExpr).getOperand()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1970,7 +1993,7 @@ class VarAccess extends Expr, @varaccess {
|
||||
*/
|
||||
predicate isVarWrite() {
|
||||
exists(Assignment a | a.getDest() = this) or
|
||||
exists(UnaryAssignExpr e | e.getExpr() = this)
|
||||
exists(UnaryAssignExpr e | e.getOperand() = this)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -680,13 +680,13 @@ class GetterMethod extends Method {
|
||||
GetterMethod() {
|
||||
this.hasNoParameters() and
|
||||
exists(ReturnStmt s, Field f | s = this.getBody().(SingletonBlock).getStmt() |
|
||||
s.getResult() = f.getAnAccess()
|
||||
s.getExpr() = f.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the field whose value is returned by this getter method. */
|
||||
Field getField() {
|
||||
exists(ReturnStmt r | r.getEnclosingCallable() = this | r.getResult() = result.getAnAccess())
|
||||
exists(ReturnStmt r | r.getEnclosingCallable() = this | r.getExpr() = result.getAnAccess())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ private class PpUnaryExpr extends PpAst, UnaryExpr {
|
||||
i = 2 and result = "--" and this instanceof PostDecExpr
|
||||
}
|
||||
|
||||
override PpAst getChild(int i) { i = 1 and result = this.getExpr() }
|
||||
override PpAst getChild(int i) { i = 1 and result = this.getOperand() }
|
||||
}
|
||||
|
||||
private class PpCastExpr extends PpAst, CastExpr {
|
||||
@@ -351,9 +351,9 @@ private class PpConditionalExpr extends PpAst, ConditionalExpr {
|
||||
override PpAst getChild(int i) {
|
||||
i = 0 and result = this.getCondition()
|
||||
or
|
||||
i = 2 and result = this.getTrueExpr()
|
||||
i = 2 and result = this.getThen()
|
||||
or
|
||||
i = 4 and result = this.getFalseExpr()
|
||||
i = 4 and result = this.getElse()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,7 +577,7 @@ private class PpForStmt extends PpAst, ForStmt {
|
||||
or
|
||||
i = 1 + this.lastUpdateIndex() and result = ")"
|
||||
or
|
||||
i = 2 + this.lastUpdateIndex() and result = " " and this.getStmt() instanceof BlockStmt
|
||||
i = 2 + this.lastUpdateIndex() and result = " " and this.getBody() instanceof BlockStmt
|
||||
}
|
||||
|
||||
private int lastInitIndex() { result = 3 + 2 * max(int j | exists(this.getInit(j))) }
|
||||
@@ -587,7 +587,7 @@ private class PpForStmt extends PpAst, ForStmt {
|
||||
}
|
||||
|
||||
override predicate newline(int i) {
|
||||
i = 2 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
|
||||
i = 2 + this.lastUpdateIndex() and not this.getBody() instanceof BlockStmt
|
||||
}
|
||||
|
||||
override PpAst getChild(int i) {
|
||||
@@ -599,11 +599,11 @@ private class PpForStmt extends PpAst, ForStmt {
|
||||
or
|
||||
exists(int j | result = this.getUpdate(j) and i = 4 + this.lastInitIndex() + 2 * j)
|
||||
or
|
||||
i = 3 + this.lastUpdateIndex() and result = this.getStmt()
|
||||
i = 3 + this.lastUpdateIndex() and result = this.getBody()
|
||||
}
|
||||
|
||||
override predicate indents(int i) {
|
||||
i = 3 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
|
||||
i = 3 + this.lastUpdateIndex() and not this.getBody() instanceof BlockStmt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt {
|
||||
i = 4 and result = " : "
|
||||
or
|
||||
i = 6 and
|
||||
if this.getStmt() instanceof BlockStmt then result = ") " else result = ")"
|
||||
if this.getBody() instanceof BlockStmt then result = ") " else result = ")"
|
||||
}
|
||||
|
||||
override PpAst getChild(int i) {
|
||||
@@ -626,10 +626,10 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt {
|
||||
or
|
||||
i = 5 and result = this.getExpr()
|
||||
or
|
||||
i = 7 and result = this.getStmt()
|
||||
i = 7 and result = this.getBody()
|
||||
}
|
||||
|
||||
override predicate indents(int i) { i = 7 and not this.getStmt() instanceof BlockStmt }
|
||||
override predicate indents(int i) { i = 7 and not this.getBody() instanceof BlockStmt }
|
||||
}
|
||||
|
||||
private class PpWhileStmt extends PpAst, WhileStmt {
|
||||
@@ -638,40 +638,40 @@ private class PpWhileStmt extends PpAst, WhileStmt {
|
||||
or
|
||||
i = 2 and result = ")"
|
||||
or
|
||||
i = 3 and result = " " and this.getStmt() instanceof BlockStmt
|
||||
i = 3 and result = " " and this.getBody() instanceof BlockStmt
|
||||
}
|
||||
|
||||
override predicate newline(int i) { i = 3 and not this.getStmt() instanceof BlockStmt }
|
||||
override predicate newline(int i) { i = 3 and not this.getBody() instanceof BlockStmt }
|
||||
|
||||
override PpAst getChild(int i) {
|
||||
i = 1 and result = this.getCondition()
|
||||
or
|
||||
i = 4 and result = this.getStmt()
|
||||
i = 4 and result = this.getBody()
|
||||
}
|
||||
|
||||
override predicate indents(int i) { i = 4 and not this.getStmt() instanceof BlockStmt }
|
||||
override predicate indents(int i) { i = 4 and not this.getBody() instanceof BlockStmt }
|
||||
}
|
||||
|
||||
private class PpDoStmt extends PpAst, DoStmt {
|
||||
override string getPart(int i) {
|
||||
i = 0 and result = "do"
|
||||
or
|
||||
i in [1, 3] and result = " " and this.getStmt() instanceof BlockStmt
|
||||
i in [1, 3] and result = " " and this.getBody() instanceof BlockStmt
|
||||
or
|
||||
i = 4 and result = "while ("
|
||||
or
|
||||
i = 6 and result = ");"
|
||||
}
|
||||
|
||||
override predicate newline(int i) { i in [1, 3] and not this.getStmt() instanceof BlockStmt }
|
||||
override predicate newline(int i) { i in [1, 3] and not this.getBody() instanceof BlockStmt }
|
||||
|
||||
override PpAst getChild(int i) {
|
||||
i = 2 and result = this.getStmt()
|
||||
i = 2 and result = this.getBody()
|
||||
or
|
||||
i = 5 and result = this.getCondition()
|
||||
}
|
||||
|
||||
override predicate indents(int i) { i = 2 and not this.getStmt() instanceof BlockStmt }
|
||||
override predicate indents(int i) { i = 2 and not this.getBody() instanceof BlockStmt }
|
||||
}
|
||||
|
||||
private class PpTryStmt extends PpAst, TryStmt {
|
||||
@@ -854,7 +854,7 @@ private class PpSynchronizedStmt extends PpAst, SynchronizedStmt {
|
||||
|
||||
private class PpReturnStmt extends PpAst, ReturnStmt {
|
||||
override string getPart(int i) {
|
||||
if exists(this.getResult())
|
||||
if exists(this.getExpr())
|
||||
then
|
||||
i = 0 and result = "return "
|
||||
or
|
||||
@@ -864,7 +864,7 @@ private class PpReturnStmt extends PpAst, ReturnStmt {
|
||||
)
|
||||
}
|
||||
|
||||
override PpAst getChild(int i) { i = 1 and result = this.getResult() }
|
||||
override PpAst getChild(int i) { i = 1 and result = this.getExpr() }
|
||||
}
|
||||
|
||||
private class PpThrowStmt extends PpAst, ThrowStmt {
|
||||
|
||||
@@ -140,7 +140,7 @@ class IfStmt extends ConditionalStmt, @ifstmt {
|
||||
}
|
||||
|
||||
/** A `for` loop. */
|
||||
class ForStmt extends ConditionalStmt, @forstmt {
|
||||
class ForStmt extends ConditionalStmt, LoopStmtImpl, @forstmt {
|
||||
/**
|
||||
* Gets an initializer expression of the loop.
|
||||
*
|
||||
@@ -167,8 +167,15 @@ class ForStmt extends ConditionalStmt, @forstmt {
|
||||
index = result.getIndex() - 3
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getBody()` instead.
|
||||
*
|
||||
* Gets the body of this `for` loop.
|
||||
*/
|
||||
deprecated Stmt getStmt() { result.getParent() = this and result.getIndex() = 2 }
|
||||
|
||||
/** Gets the body of this `for` loop. */
|
||||
Stmt getStmt() { result.getParent() = this and result.getIndex() = 2 }
|
||||
override Stmt getBody() { result.getParent() = this and result.getIndex() = 2 }
|
||||
|
||||
/**
|
||||
* Gets a variable that is used as an iteration variable: it is defined,
|
||||
@@ -184,14 +191,14 @@ class ForStmt extends ConditionalStmt, @forstmt {
|
||||
Variable getAnIterationVariable() {
|
||||
// Check that the variable is assigned to, incremented or decremented in the update expression, and...
|
||||
exists(Expr update | update = this.getAnUpdate().getAChildExpr*() |
|
||||
update.(UnaryAssignExpr).getExpr() = result.getAnAccess() or
|
||||
update.(UnaryAssignExpr).getOperand() = result.getAnAccess() or
|
||||
update = result.getAnAssignedValue()
|
||||
) and
|
||||
// ...that it is checked or used in the condition.
|
||||
this.getCondition().getAChildExpr*() = result.getAnAccess()
|
||||
}
|
||||
|
||||
override string pp() { result = "for (...;...;...) " + this.getStmt().pp() }
|
||||
override string pp() { result = "for (...;...;...) " + this.getBody().pp() }
|
||||
|
||||
override string toString() { result = "for (...;...;...)" }
|
||||
|
||||
@@ -201,17 +208,24 @@ class ForStmt extends ConditionalStmt, @forstmt {
|
||||
}
|
||||
|
||||
/** An enhanced `for` loop. (Introduced in Java 5.) */
|
||||
class EnhancedForStmt extends Stmt, @enhancedforstmt {
|
||||
class EnhancedForStmt extends LoopStmtImpl, @enhancedforstmt {
|
||||
/** Gets the local variable declaration expression of this enhanced `for` loop. */
|
||||
LocalVariableDeclExpr getVariable() { result.getParent() = this }
|
||||
|
||||
/** Gets the expression over which this enhanced `for` loop iterates. */
|
||||
Expr getExpr() { result.isNthChildOf(this, 1) }
|
||||
|
||||
/** Gets the body of this enhanced `for` loop. */
|
||||
Stmt getStmt() { result.getParent() = this }
|
||||
/**
|
||||
* DEPRECATED: Use `getBody()` instead.
|
||||
*
|
||||
* Gets the body of this enhanced `for` loop.
|
||||
*/
|
||||
deprecated Stmt getStmt() { result.getParent() = this }
|
||||
|
||||
override string pp() { result = "for (... : ...) " + this.getStmt().pp() }
|
||||
/** Gets the body of this enhanced `for` loop. */
|
||||
override Stmt getBody() { result.getParent() = this }
|
||||
|
||||
override string pp() { result = "for (... : ...) " + this.getBody().pp() }
|
||||
|
||||
override string toString() { result = "for (... : ...)" }
|
||||
|
||||
@@ -221,14 +235,21 @@ class EnhancedForStmt extends Stmt, @enhancedforstmt {
|
||||
}
|
||||
|
||||
/** A `while` loop. */
|
||||
class WhileStmt extends ConditionalStmt, @whilestmt {
|
||||
class WhileStmt extends ConditionalStmt, LoopStmtImpl, @whilestmt {
|
||||
/** Gets the boolean condition of this `while` loop. */
|
||||
override Expr getCondition() { result.getParent() = this }
|
||||
|
||||
/** Gets the body of this `while` loop. */
|
||||
Stmt getStmt() { result.getParent() = this }
|
||||
/**
|
||||
* DEPRECATED: Use `getBody()` instead.
|
||||
*
|
||||
* Gets the body of this `while` loop.
|
||||
*/
|
||||
deprecated Stmt getStmt() { result.getParent() = this }
|
||||
|
||||
override string pp() { result = "while (...) " + this.getStmt().pp() }
|
||||
/** Gets the body of this `while` loop. */
|
||||
override Stmt getBody() { result.getParent() = this }
|
||||
|
||||
override string pp() { result = "while (...) " + this.getBody().pp() }
|
||||
|
||||
override string toString() { result = "while (...)" }
|
||||
|
||||
@@ -238,14 +259,21 @@ class WhileStmt extends ConditionalStmt, @whilestmt {
|
||||
}
|
||||
|
||||
/** A `do` loop. */
|
||||
class DoStmt extends ConditionalStmt, @dostmt {
|
||||
class DoStmt extends ConditionalStmt, LoopStmtImpl, @dostmt {
|
||||
/** Gets the condition of this `do` loop. */
|
||||
override Expr getCondition() { result.getParent() = this }
|
||||
|
||||
/** Gets the body of this `do` loop. */
|
||||
Stmt getStmt() { result.getParent() = this }
|
||||
/**
|
||||
* DEPRECATED: Use `getBody()` instead.
|
||||
*
|
||||
* Gets the body of this `do` loop.
|
||||
*/
|
||||
deprecated Stmt getStmt() { result.getParent() = this }
|
||||
|
||||
override string pp() { result = "do " + this.getStmt().pp() + " while (...)" }
|
||||
/** Gets the body of this `do` loop. */
|
||||
override Stmt getBody() { result.getParent() = this }
|
||||
|
||||
override string pp() { result = "do " + this.getBody().pp() + " while (...)" }
|
||||
|
||||
override string toString() { result = "do ... while (...)" }
|
||||
|
||||
@@ -258,30 +286,16 @@ class DoStmt extends ConditionalStmt, @dostmt {
|
||||
* A loop statement, including `for`, enhanced `for`,
|
||||
* `while` and `do` statements.
|
||||
*/
|
||||
class LoopStmt extends Stmt {
|
||||
LoopStmt() {
|
||||
this instanceof ForStmt or
|
||||
this instanceof EnhancedForStmt or
|
||||
this instanceof WhileStmt or
|
||||
this instanceof DoStmt
|
||||
}
|
||||
|
||||
abstract private class LoopStmtImpl extends Stmt {
|
||||
/** Gets the body of this loop statement. */
|
||||
Stmt getBody() {
|
||||
result = this.(ForStmt).getStmt() or
|
||||
result = this.(EnhancedForStmt).getStmt() or
|
||||
result = this.(WhileStmt).getStmt() or
|
||||
result = this.(DoStmt).getStmt()
|
||||
}
|
||||
abstract Stmt getBody();
|
||||
|
||||
/** Gets the boolean condition of this loop statement. */
|
||||
Expr getCondition() {
|
||||
result = this.(ForStmt).getCondition() or
|
||||
result = this.(WhileStmt).getCondition() or
|
||||
result = this.(DoStmt).getCondition()
|
||||
}
|
||||
Expr getCondition() { none() }
|
||||
}
|
||||
|
||||
final class LoopStmt = LoopStmtImpl;
|
||||
|
||||
/** A `try` statement. */
|
||||
class TryStmt extends Stmt, @trystmt {
|
||||
/** Gets the block of the `try` statement. */
|
||||
@@ -627,9 +641,16 @@ class SynchronizedStmt extends Stmt, @synchronizedstmt {
|
||||
|
||||
/** A `return` statement. */
|
||||
class ReturnStmt extends Stmt, @returnstmt {
|
||||
/** Gets the expression returned by this `return` statement, if any. */
|
||||
/**
|
||||
* DEPRECATED: Use `getExpr()` instead.
|
||||
*
|
||||
* Gets the expression returned by this `return` statement, if any.
|
||||
*/
|
||||
Expr getResult() { result.getParent() = this }
|
||||
|
||||
/** Gets the expression returned by this `return` statement, if any. */
|
||||
Expr getExpr() { result.getParent() = this }
|
||||
|
||||
override string pp() { result = "return ..." }
|
||||
|
||||
override string toString() { result = "return ..." }
|
||||
|
||||
@@ -93,7 +93,7 @@ class ArithExpr extends Expr {
|
||||
) and
|
||||
forall(Expr e |
|
||||
e = this.(BinaryExpr).getAnOperand() or
|
||||
e = this.(UnaryAssignExpr).getExpr() or
|
||||
e = this.(UnaryAssignExpr).getOperand() or
|
||||
e = this.(AssignOp).getSource()
|
||||
|
|
||||
e.getType() instanceof NumType
|
||||
@@ -114,7 +114,7 @@ class ArithExpr extends Expr {
|
||||
*/
|
||||
Expr getLeftOperand() {
|
||||
result = this.(BinaryExpr).getLeftOperand() or
|
||||
result = this.(UnaryAssignExpr).getExpr() or
|
||||
result = this.(UnaryAssignExpr).getOperand() or
|
||||
result = this.(AssignOp).getDest()
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ class ArithExpr extends Expr {
|
||||
/** Gets an operand of this arithmetic expression. */
|
||||
Expr getAnOperand() {
|
||||
result = this.(BinaryExpr).getAnOperand() or
|
||||
result = this.(UnaryAssignExpr).getExpr() or
|
||||
result = this.(UnaryAssignExpr).getOperand() or
|
||||
result = this.(AssignOp).getSource()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import java
|
||||
* Used as basis for the transitive closure in `exprImplies`.
|
||||
*/
|
||||
private predicate exprImpliesStep(Expr e1, boolean b1, Expr e2, boolean b2) {
|
||||
e1.(LogNotExpr).getExpr() = e2 and
|
||||
e1.(LogNotExpr).getOperand() = e2 and
|
||||
b2 = b1.booleanNot() and
|
||||
(b1 = true or b1 = false)
|
||||
or
|
||||
|
||||
@@ -279,9 +279,7 @@ private module GuardsInput implements SharedGuards::InputSig<Location, ControlFl
|
||||
}
|
||||
}
|
||||
|
||||
class NotExpr extends Expr instanceof J::LogNotExpr {
|
||||
Expr getOperand() { result = this.(J::LogNotExpr).getExpr() }
|
||||
}
|
||||
class NotExpr = J::LogNotExpr;
|
||||
|
||||
class IdExpr extends Expr {
|
||||
IdExpr() { this instanceof AssignExpr or this instanceof CastExpr }
|
||||
@@ -317,13 +315,7 @@ private module GuardsInput implements SharedGuards::InputSig<Location, ControlFl
|
||||
)
|
||||
}
|
||||
|
||||
class ConditionalExpr extends Expr instanceof J::ConditionalExpr {
|
||||
Expr getCondition() { result = super.getCondition() }
|
||||
|
||||
Expr getThen() { result = super.getTrueExpr() }
|
||||
|
||||
Expr getElse() { result = super.getFalseExpr() }
|
||||
}
|
||||
class ConditionalExpr = J::ConditionalExpr;
|
||||
|
||||
class Parameter = J::Parameter;
|
||||
|
||||
@@ -357,7 +349,7 @@ private module GuardsInput implements SharedGuards::InputSig<Location, ControlFl
|
||||
GuardsInput::Expr getAReturnExpr() {
|
||||
exists(ReturnStmt ret |
|
||||
this = ret.getEnclosingCallable() and
|
||||
ret.getResult() = result
|
||||
ret.getExpr() = result
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,9 +49,7 @@ class ConstantMethod extends Method {
|
||||
// Just one return statement
|
||||
count(ReturnStmt rs | rs.getEnclosingCallable() = this) = 1 and
|
||||
// Which returns a constant expr
|
||||
exists(ReturnStmt rs | rs.getEnclosingCallable() = this |
|
||||
rs.getResult() instanceof ConstantExpr
|
||||
) and
|
||||
exists(ReturnStmt rs | rs.getEnclosingCallable() = this | rs.getExpr() instanceof ConstantExpr) and
|
||||
// And this method is not overridden
|
||||
not exists(Method m | m.overrides(this))
|
||||
}
|
||||
@@ -61,7 +59,7 @@ class ConstantMethod extends Method {
|
||||
*/
|
||||
ConstantExpr getConstantValue() {
|
||||
exists(ReturnStmt returnStmt | returnStmt.getEnclosingCallable() = this |
|
||||
result = returnStmt.getResult()
|
||||
result = returnStmt.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ Expr clearlyNotNullExpr(Expr reason) {
|
||||
or
|
||||
exists(ConditionalExpr c, Expr r1, Expr r2 |
|
||||
c = result and
|
||||
c.getTrueExpr() = clearlyNotNullExpr(r1) and
|
||||
c.getFalseExpr() = clearlyNotNullExpr(r2) and
|
||||
c.getThen() = clearlyNotNullExpr(r1) and
|
||||
c.getElse() = clearlyNotNullExpr(r2) and
|
||||
(reason = r1 or reason = r2)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -64,7 +64,7 @@ private predicate unboxed(Expr e) {
|
||||
bin.getType() instanceof PrimitiveType
|
||||
)
|
||||
or
|
||||
exists(UnaryExpr un | un.getExpr() = e)
|
||||
exists(UnaryExpr un | un.getOperand() = e)
|
||||
or
|
||||
exists(ChooseExpr cond | cond.getType() instanceof PrimitiveType | cond.getAResultExpr() = e)
|
||||
or
|
||||
@@ -73,7 +73,7 @@ private predicate unboxed(Expr e) {
|
||||
exists(Parameter p | p.getType() instanceof PrimitiveType and p.getAnArgument() = e)
|
||||
or
|
||||
exists(ReturnStmt ret |
|
||||
ret.getEnclosingCallable().getReturnType() instanceof PrimitiveType and ret.getResult() = e
|
||||
ret.getEnclosingCallable().getReturnType() instanceof PrimitiveType and ret.getExpr() = e
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -173,23 +173,23 @@ module Sem implements Semantic<Location> {
|
||||
}
|
||||
|
||||
class NegateExpr extends UnaryExpr instanceof MinusExpr {
|
||||
override Expr getOperand() { result = super.getExpr() }
|
||||
override Expr getOperand() { result = MinusExpr.super.getOperand() }
|
||||
}
|
||||
|
||||
class PreIncExpr extends UnaryExpr instanceof J::PreIncExpr {
|
||||
override Expr getOperand() { result = super.getExpr() }
|
||||
override Expr getOperand() { result = J::PreIncExpr.super.getOperand() }
|
||||
}
|
||||
|
||||
class PreDecExpr extends UnaryExpr instanceof J::PreDecExpr {
|
||||
override Expr getOperand() { result = super.getExpr() }
|
||||
override Expr getOperand() { result = J::PreDecExpr.super.getOperand() }
|
||||
}
|
||||
|
||||
class PostIncExpr extends UnaryExpr instanceof J::PostIncExpr {
|
||||
override Expr getOperand() { result = super.getExpr() }
|
||||
override Expr getOperand() { result = J::PostIncExpr.super.getOperand() }
|
||||
}
|
||||
|
||||
class PostDecExpr extends UnaryExpr instanceof J::PostDecExpr {
|
||||
override Expr getOperand() { result = super.getExpr() }
|
||||
override Expr getOperand() { result = J::PostDecExpr.super.getOperand() }
|
||||
}
|
||||
|
||||
class CopyValueExpr extends UnaryExpr {
|
||||
@@ -200,7 +200,7 @@ module Sem implements Semantic<Location> {
|
||||
}
|
||||
|
||||
override Expr getOperand() {
|
||||
result = this.(J::PlusExpr).getExpr() or
|
||||
result = this.(J::PlusExpr).getOperand() or
|
||||
result = this.(J::AssignExpr).getSource() or
|
||||
result = this.(J::LocalVariableDeclExpr).getInit()
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
n2.asSsa().(Base::SsaPhiDefinition).getAnUltimateDefinition() = n1.asSsa()
|
||||
or
|
||||
exists(ReturnStmt ret |
|
||||
n2.asMethod() = ret.getEnclosingCallable() and ret.getResult() = n1.asExpr()
|
||||
n2.asMethod() = ret.getEnclosingCallable() and ret.getExpr() = n1.asExpr()
|
||||
)
|
||||
or
|
||||
viableImpl_v1(n2.asExpr()) = n1.asMethod()
|
||||
@@ -137,7 +137,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
or
|
||||
n2.asSsa().(Base::SsaCapturedDefinition).captures(n1.asSsa())
|
||||
or
|
||||
n2.asExpr().(NotNullExpr).getExpr() = n1.asExpr()
|
||||
n2.asExpr().(NotNullExpr).getOperand() = n1.asExpr()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -87,7 +87,7 @@ private module BaseSsaImpl {
|
||||
result = TLocalVar(v.getCallable(), v)
|
||||
)
|
||||
or
|
||||
result.getAnAccess() = upd.(UnaryAssignExpr).getExpr()
|
||||
result.getAnAccess() = upd.(UnaryAssignExpr).getOperand()
|
||||
}
|
||||
|
||||
/** Holds if `n` updates the local variable `v`. */
|
||||
|
||||
@@ -510,7 +510,7 @@ module Private {
|
||||
/** A data flow node that occurs as the result of a `ReturnStmt`. */
|
||||
class ReturnNode extends Node {
|
||||
ReturnNode() {
|
||||
exists(ReturnStmt ret | this.asExpr() = ret.getResult()) or
|
||||
exists(ReturnStmt ret | this.asExpr() = ret.getExpr()) or
|
||||
this.(FlowSummaryNode).isReturn()
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ predicate simpleAstFlowStep(Expr e1, Expr e2) {
|
||||
or
|
||||
e2 = any(StmtExpr stmtExpr | e1 = stmtExpr.getResultExpr())
|
||||
or
|
||||
e2 = any(NotNullExpr nne | e1 = nne.getExpr())
|
||||
e2 = any(NotNullExpr nne | e1 = nne.getOperand())
|
||||
or
|
||||
e2.(WhenExpr).getBranch(_).getAResult() = e1
|
||||
or
|
||||
|
||||
@@ -302,7 +302,7 @@ private module Cached {
|
||||
result = TLocalVar(v.getCallable(), v)
|
||||
)
|
||||
or
|
||||
result.getAnAccess() = upd.(UnaryAssignExpr).getExpr()
|
||||
result.getAnAccess() = upd.(UnaryAssignExpr).getOperand()
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -69,10 +69,10 @@ module Private {
|
||||
|
||||
/** Returns the operand of this expression. */
|
||||
Expr getOperand() {
|
||||
result = this.(J::PreIncExpr).getExpr() or
|
||||
result = this.(J::PreDecExpr).getExpr() or
|
||||
result = this.(J::MinusExpr).getExpr() or
|
||||
result = this.(J::BitNotExpr).getExpr()
|
||||
result = this.(J::PreIncExpr).getOperand() or
|
||||
result = this.(J::PreDecExpr).getOperand() or
|
||||
result = this.(J::MinusExpr).getOperand() or
|
||||
result = this.(J::BitNotExpr).getOperand()
|
||||
}
|
||||
|
||||
/** Returns the operation representing this expression. */
|
||||
@@ -258,12 +258,12 @@ private module Impl {
|
||||
|
||||
/** Returns the operand of the operation if `e` is a decrement. */
|
||||
Expr getDecrementOperand(Element e) {
|
||||
result = e.(PostDecExpr).getExpr() or result = e.(PreDecExpr).getExpr()
|
||||
result = e.(PostDecExpr).getOperand() or result = e.(PreDecExpr).getOperand()
|
||||
}
|
||||
|
||||
/** Returns the operand of the operation if `e` is an increment. */
|
||||
Expr getIncrementOperand(Element e) {
|
||||
result = e.(PostIncExpr).getExpr() or result = e.(PreIncExpr).getExpr()
|
||||
result = e.(PostIncExpr).getOperand() or result = e.(PreIncExpr).getOperand()
|
||||
}
|
||||
|
||||
/** Gets the variable underlying the implicit SSA variable `v`. */
|
||||
@@ -287,14 +287,14 @@ private module Impl {
|
||||
|
||||
/** Holds if `f` is accessed in an increment operation. */
|
||||
predicate fieldIncrementOperationOperand(Field f) {
|
||||
any(PostIncExpr inc).getExpr() = f.getAnAccess() or
|
||||
any(PreIncExpr inc).getExpr() = f.getAnAccess()
|
||||
any(PostIncExpr inc).getOperand() = f.getAnAccess() or
|
||||
any(PreIncExpr inc).getOperand() = f.getAnAccess()
|
||||
}
|
||||
|
||||
/** Holds if `f` is accessed in a decrement operation. */
|
||||
predicate fieldDecrementOperationOperand(Field f) {
|
||||
any(PostDecExpr dec).getExpr() = f.getAnAccess() or
|
||||
any(PreDecExpr dec).getExpr() = f.getAnAccess()
|
||||
any(PostDecExpr dec).getOperand() = f.getAnAccess() or
|
||||
any(PreDecExpr dec).getOperand() = f.getAnAccess()
|
||||
}
|
||||
|
||||
/** Returns possible signs of `f` based on the declaration. */
|
||||
@@ -316,9 +316,9 @@ private module Impl {
|
||||
/** Returns a sub expression of `e` for expression types where the sign depends on the child. */
|
||||
Expr getASubExprWithSameSign(Expr e) {
|
||||
result = e.(AssignExpr).getSource() or
|
||||
result = e.(PlusExpr).getExpr() or
|
||||
result = e.(PostIncExpr).getExpr() or
|
||||
result = e.(PostDecExpr).getExpr() or
|
||||
result = e.(PlusExpr).getOperand() or
|
||||
result = e.(PostIncExpr).getOperand() or
|
||||
result = e.(PostDecExpr).getOperand() or
|
||||
result = e.(ChooseExpr).getAResultExpr() or
|
||||
result = e.(CastingExpr).getExpr()
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ VarAccess valueAccess(EnumConstant e) {
|
||||
or
|
||||
exists(Assignment a | a.getSource() = valueFlow+(result))
|
||||
or
|
||||
exists(ReturnStmt r | r.getResult() = valueFlow+(result))
|
||||
exists(ReturnStmt r | r.getExpr() = valueFlow+(result))
|
||||
or
|
||||
exists(LocalVariableDeclExpr v | v.getInit() = valueFlow+(result))
|
||||
or
|
||||
|
||||
@@ -354,7 +354,7 @@ private module TrackLambda<methodDispatchSig/1 lambdaDispatch0> {
|
||||
predicate returnStep(Node n1, LocalSourceNode n2) {
|
||||
exists(ReturnStmt ret, Method m |
|
||||
ret.getEnclosingCallable() = m and
|
||||
ret.getResult() = n1.asExpr() and
|
||||
ret.getExpr() = n1.asExpr() and
|
||||
m = dispatch(n2.asExpr())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ private predicate viableArgParam(ArgumentNode arg, ParameterNode p) {
|
||||
private predicate returnStep(Node n1, Node n2) {
|
||||
exists(ReturnStmt ret, Method m |
|
||||
ret.getEnclosingCallable() = m and
|
||||
ret.getResult() = n1.asExpr() and
|
||||
ret.getExpr() = n1.asExpr() and
|
||||
pragma[only_bind_out](m) = dispatchCand(n2.asExpr())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -424,7 +424,7 @@ private class JaxRSXssSink extends XssSink {
|
||||
exists(JaxRsResourceMethod resourceMethod, ReturnStmt rs |
|
||||
resourceMethod = any(JaxRsResourceClass resourceClass).getAResourceMethod() and
|
||||
rs.getEnclosingCallable() = resourceMethod and
|
||||
this.asExpr() = rs.getResult()
|
||||
this.asExpr() = rs.getExpr()
|
||||
|
|
||||
not exists(resourceMethod.getProducesAnnotation())
|
||||
or
|
||||
|
||||
@@ -386,7 +386,7 @@ class MockitoMockedObject extends Expr {
|
||||
or
|
||||
exists(ReturnStmt ret |
|
||||
this.(MethodCall).getMethod() = ret.getEnclosingCallable() and
|
||||
ret.getResult() instanceof MockitoMockedObject
|
||||
ret.getExpr() instanceof MockitoMockedObject
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ class MyBatisInjectionSink extends DataFlow::Node {
|
||||
a.getType() instanceof MyBatisProvider and
|
||||
m.getDeclaringType() = a.getValue(["type", "value"]).(TypeLiteral).getTypeName().getType() and
|
||||
m.hasName(a.getValue("method").(StringLiteral).getValue()) and
|
||||
exists(ReturnStmt ret | this.asExpr() = ret.getResult() and ret.getEnclosingCallable() = m)
|
||||
exists(ReturnStmt ret | this.asExpr() = ret.getExpr() and ret.getEnclosingCallable() = m)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ private predicate threadLocalInitialValue(ClassInstanceExpr cie, Method initialV
|
||||
exists(RefType t, ReturnStmt ret |
|
||||
cie.getConstructedType().getSourceDeclaration() = t and
|
||||
t.getASourceSupertype+().hasQualifiedName("java.lang", "ThreadLocal") and
|
||||
ret.getResult() = init and
|
||||
ret.getExpr() = init and
|
||||
ret.getEnclosingCallable() = initialValue and
|
||||
initialValue.hasName("initialValue") and
|
||||
initialValue.getDeclaringType() = t
|
||||
|
||||
@@ -37,7 +37,7 @@ private class AsyncTaskOnPostExecuteAdditionalValueStep extends AdditionalValueS
|
||||
|
|
||||
onPostExecute.getDeclaringType() = runInBackground.getDeclaringType()
|
||||
|
|
||||
node1.asExpr() = any(ReturnStmt r | r.getEnclosingCallable() = runInBackground).getResult() and
|
||||
node1.asExpr() = any(ReturnStmt r | r.getEnclosingCallable() = runInBackground).getExpr() and
|
||||
node2.asParameter() = onPostExecute.getParameter(0)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class LiveLiteralMethod extends Method {
|
||||
|
||||
private predicate methodReturns(Method m, Expr res) {
|
||||
exists(ReturnStmt r |
|
||||
r.getResult() = res and
|
||||
r.getExpr() = res and
|
||||
r.getEnclosingCallable() = m
|
||||
)
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ private predicate reaches(Expr src, Argument arg) {
|
||||
or
|
||||
exists(StmtExpr e | e.getResultExpr() = src | reaches(e, arg))
|
||||
or
|
||||
exists(NotNullExpr e | e.getExpr() = src | reaches(e, arg))
|
||||
exists(NotNullExpr e | e.getOperand() = src | reaches(e, arg))
|
||||
or
|
||||
exists(WhenExpr e | e.getBranch(_).getAResult() = src | reaches(e, arg))
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ ThisAccess forbiddenThisUse(Callable c) {
|
||||
result.getEnclosingCallable() = c and
|
||||
(
|
||||
exists(MethodCall ma | ma.getAnArgument() = result) or
|
||||
exists(ReturnStmt rs | rs.getResult() = result)
|
||||
exists(ReturnStmt rs | rs.getExpr() = result)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ private class SpringXssSink extends XSS::XssSink {
|
||||
SpringXssSink() {
|
||||
exists(SpringRequestMappingMethod requestMappingMethod, ReturnStmt rs |
|
||||
requestMappingMethod = rs.getEnclosingCallable() and
|
||||
this.asExpr() = rs.getResult() and
|
||||
this.asExpr() = rs.getExpr() and
|
||||
(
|
||||
not specifiesContentType(requestMappingMethod) or
|
||||
isXssVulnerableContentTypeExpr(requestMappingMethod.getAProducesExpr())
|
||||
|
||||
@@ -58,9 +58,9 @@ private class HttpResponseGetDescriptionStep extends AdditionalValueStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(ReturnStmt s, GenerateResponseMethod m |
|
||||
s.getEnclosingCallable() instanceof HudsonWebMethod and
|
||||
boundOrStaticType(s.getResult(), m.getDeclaringType().getADescendant())
|
||||
boundOrStaticType(s.getExpr(), m.getDeclaringType().getADescendant())
|
||||
|
|
||||
n1.asExpr() = s.getResult() and
|
||||
n1.asExpr() = s.getExpr() and
|
||||
n2.(DataFlow::InstanceParameterNode).getCallable() = m
|
||||
)
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ predicate upcastToWiderType(Expr e) {
|
||||
or
|
||||
exists(CastingExpr c | c.getExpr() = e and t2 = c.getType())
|
||||
or
|
||||
exists(ReturnStmt ret | ret.getResult() = e and t2 = ret.getEnclosingCallable().getReturnType())
|
||||
exists(ReturnStmt ret | ret.getExpr() = e and t2 = ret.getEnclosingCallable().getReturnType())
|
||||
or
|
||||
exists(Parameter p | p.getAnArgument() = e and t2 = p.getType())
|
||||
or
|
||||
|
||||
@@ -25,7 +25,7 @@ class IsValidFragmentMethod extends Method {
|
||||
predicate isUnsafe() {
|
||||
this.getDeclaringType().(AndroidActivity).isExported() and
|
||||
forex(ReturnStmt retStmt | retStmt.getEnclosingCallable() = this |
|
||||
retStmt.getResult().(BooleanLiteral).getBooleanValue() = true
|
||||
retStmt.getExpr().(BooleanLiteral).getBooleanValue() = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ module InsecureRandomnessConfig implements DataFlow::ConfigSig {
|
||||
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
n1.asExpr() = n2.asExpr().(BinaryExpr).getAnOperand()
|
||||
or
|
||||
n1.asExpr() = n2.asExpr().(UnaryExpr).getExpr()
|
||||
n1.asExpr() = n2.asExpr().(UnaryExpr).getOperand()
|
||||
or
|
||||
exists(MethodCall mc, string methodName |
|
||||
mc.getMethod().hasQualifiedName("org.owasp.esapi", "Encoder", methodName) and
|
||||
|
||||
@@ -107,7 +107,7 @@ private class StaticInitializationVectorSource extends DataFlow::Node {
|
||||
// Reduce FPs from utility methods that return an empty array in an exceptional case
|
||||
not exists(ReturnStmt ret |
|
||||
array.getADimension().(CompileTimeConstantExpr).getIntValue() = 0 and
|
||||
DataFlow::localExprFlow(array, ret.getResult())
|
||||
DataFlow::localExprFlow(array, ret.getExpr())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ private module SafeKryoConfig implements DataFlow::ConfigSig {
|
||||
) {
|
||||
exists(ConstructorCall cc, FunctionalExpr fe |
|
||||
cc.getConstructedType() instanceof KryoPoolBuilder and
|
||||
fe.asMethod().getBody().getAStmt().(ReturnStmt).getResult() = node1.asExpr() and
|
||||
fe.asMethod().getBody().getAStmt().(ReturnStmt).getExpr() = node1.asExpr() and
|
||||
node2.asExpr() = cc and
|
||||
cc.getArgument(0) = fe
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ private import semmle.code.java.dataflow.ExternalFlow
|
||||
*/
|
||||
private predicate alwaysReturnsTrue(HostnameVerifierVerify m) {
|
||||
forex(ReturnStmt rs | rs.getEnclosingCallable() = m |
|
||||
rs.getResult().(CompileTimeConstantExpr).getBooleanValue() = true
|
||||
rs.getExpr().(CompileTimeConstantExpr).getBooleanValue() = true
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class PointlessLoop extends WhileStmt {
|
||||
this.getCondition().(BooleanLiteral).getBooleanValue() = true and
|
||||
// The only `break` must be the last statement.
|
||||
forall(BreakStmt break | break.getTarget() = this |
|
||||
this.getStmt().(BlockStmt).getLastStmt() = break
|
||||
this.getBody().(BlockStmt).getLastStmt() = break
|
||||
) and
|
||||
// No `continue` statements.
|
||||
not exists(ContinueStmt continue | continue.getTarget() = this)
|
||||
|
||||
@@ -32,7 +32,7 @@ class AnyAssignment extends Expr {
|
||||
/** The expression modified by this assignment. */
|
||||
Expr getDest() {
|
||||
this.(Assignment).getDest() = result or
|
||||
this.(UnaryAssignExpr).getExpr() = result
|
||||
this.(UnaryAssignExpr).getOperand() = result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class Iterable extends Class {
|
||||
exists(Method m |
|
||||
m.getDeclaringType().getSourceDeclaration() = this and
|
||||
m.getName() = "iterator" and
|
||||
m.getBody().(SingletonBlock).getStmt().(ReturnStmt).getResult() = result
|
||||
m.getBody().(SingletonBlock).getStmt().(ReturnStmt).getExpr() = result
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ class EmptyIterableIterator extends IterableIterator {
|
||||
.(SingletonBlock)
|
||||
.getStmt()
|
||||
.(ReturnStmt)
|
||||
.getResult()
|
||||
.getExpr()
|
||||
.(BooleanLiteral)
|
||||
.getBooleanValue() = false
|
||||
)
|
||||
|
||||
@@ -25,5 +25,5 @@ where
|
||||
t instanceof PrimitiveType and
|
||||
not t instanceof CharType
|
||||
)
|
||||
select ce, "Mismatch between types of branches: $@ and $@.", ce.getTrueExpr(),
|
||||
ce.getTrueExpr().getType().getName(), ce.getFalseExpr(), ce.getFalseExpr().getType().getName()
|
||||
select ce, "Mismatch between types of branches: $@ and $@.", ce.getThen(),
|
||||
ce.getThen().getType().getName(), ce.getElse(), ce.getElse().getType().getName()
|
||||
|
||||
@@ -39,7 +39,7 @@ predicate containsSpecialCollection(Expr e, SpecialCollectionCreation origin) {
|
||||
or
|
||||
exists(Call c, ReturnStmt r | e = c |
|
||||
r.getEnclosingCallable() = c.getCallee().getSourceDeclaration() and
|
||||
containsSpecialCollection(r.getResult(), origin)
|
||||
containsSpecialCollection(r.getExpr(), origin)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ predicate iterOfSpecialCollection(Expr e, SpecialCollectionCreation origin) {
|
||||
or
|
||||
exists(Call c, ReturnStmt r | e = c |
|
||||
r.getEnclosingCallable() = c.getCallee().getSourceDeclaration() and
|
||||
iterOfSpecialCollection(r.getResult(), origin)
|
||||
iterOfSpecialCollection(r.getExpr(), origin)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ where
|
||||
exists(AssignExpr assgn | va = assgn.getDest() | assgn.getSource() instanceof FreshContainer)
|
||||
or
|
||||
// ...a return (but only if `v` is a local variable)
|
||||
v instanceof LocalVariableDecl and exists(ReturnStmt ret | ret.getResult() = va)
|
||||
v instanceof LocalVariableDecl and exists(ReturnStmt ret | ret.getExpr() = va)
|
||||
or
|
||||
// ...or a call to a query method on `v`.
|
||||
exists(MethodCall ma | va = ma.getQualifier() | ma.getMethod() instanceof ContainerQueryMethod)
|
||||
|
||||
@@ -32,13 +32,13 @@ predicate checksReferenceEquality(EqualsMethod em) {
|
||||
eq.getAnOperand().(VarAccess).getVariable() = em.getParameter(0) and
|
||||
(
|
||||
// `{ return (ojb==this); }`
|
||||
eq = blk.getStmt().(ReturnStmt).getResult()
|
||||
eq = blk.getStmt().(ReturnStmt).getExpr()
|
||||
or
|
||||
// `{ if (ojb==this) return true; else return false; }`
|
||||
exists(IfStmt ifStmt | ifStmt = blk.getStmt() |
|
||||
eq = ifStmt.getCondition() and
|
||||
ifStmt.getThen().(ReturnStmt).getResult().(BooleanLiteral).getBooleanValue() = true and
|
||||
ifStmt.getElse().(ReturnStmt).getResult().(BooleanLiteral).getBooleanValue() = false
|
||||
ifStmt.getThen().(ReturnStmt).getExpr().(BooleanLiteral).getBooleanValue() = true and
|
||||
ifStmt.getElse().(ReturnStmt).getExpr().(BooleanLiteral).getBooleanValue() = false
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -47,7 +47,7 @@ predicate checksReferenceEquality(EqualsMethod em) {
|
||||
// More precisely, we check whether the body of `em` is of the form `return super.equals(o);`,
|
||||
// where `o` is the (only) parameter of `em`, and the invoked method is a reference equality check.
|
||||
exists(SuperMethodCall sup |
|
||||
sup = em.getBody().(SingletonBlock).getStmt().(ReturnStmt).getResult() and
|
||||
sup = em.getBody().(SingletonBlock).getStmt().(ReturnStmt).getExpr() and
|
||||
sup.getArgument(0) = em.getParameter(0).getAnAccess() and
|
||||
checksReferenceEquality(sup.getCallee())
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ class RefiningEquals extends EqualsMethod {
|
||||
// ... on the (only) parameter of this method ...
|
||||
sup.getArgument(0).(VarAccess).getVariable() = this.getAParameter() and
|
||||
// ... and its result is implied by the result of `ret`.
|
||||
exprImplies(ret.getResult(), true, sup, true)
|
||||
exprImplies(ret.getExpr(), true, sup, true)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class ReferenceEquals extends EqualsMethod {
|
||||
exists(BlockStmt b, ReturnStmt ret, EQExpr eq |
|
||||
this.getBody() = b and
|
||||
b.getStmt(0) = ret and
|
||||
ret.getResult() = eq and
|
||||
ret.getExpr() = eq and
|
||||
eq.getAnOperand() = this.getAParameter().getAnAccess() and
|
||||
(eq.getAnOperand() instanceof ThisAccess or eq.getAnOperand() instanceof FieldAccess)
|
||||
)
|
||||
|
||||
@@ -27,8 +27,8 @@ class StringValue extends Expr {
|
||||
)
|
||||
or
|
||||
// Ternary conditional operator.
|
||||
this.(ConditionalExpr).getTrueExpr().(StringValue).isInterned() and
|
||||
this.(ConditionalExpr).getFalseExpr().(StringValue).isInterned()
|
||||
this.(ConditionalExpr).getThen().(StringValue).isInterned() and
|
||||
this.(ConditionalExpr).getElse().(StringValue).isInterned()
|
||||
or
|
||||
// Values of type `String` that are compile-time constant expressions (JLS 15.28).
|
||||
this instanceof CompileTimeConstantExpr
|
||||
@@ -38,7 +38,7 @@ class StringValue extends Expr {
|
||||
or
|
||||
// Method accesses whose results are all interned.
|
||||
forex(ReturnStmt rs | rs.getEnclosingCallable() = this.(MethodCall).getMethod() |
|
||||
rs.getResult().(StringValue).isInterned()
|
||||
rs.getExpr().(StringValue).isInterned()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user