Merge branch 'main' into sitedocs/2.17.0

This commit is contained in:
Pierre
2024-04-05 09:39:18 +02:00
committed by GitHub
364 changed files with 33089 additions and 17983 deletions

View File

@@ -251,12 +251,6 @@
"cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll",
"cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll"
],
"XML": [
"cpp/ql/lib/semmle/code/cpp/XML.qll",
"csharp/ql/lib/semmle/code/csharp/XML.qll",
"java/ql/lib/semmle/code/xml/XML.qll",
"python/ql/lib/semmle/python/xml/XML.qll"
],
"DuplicationProblems.inc.qhelp": [
"cpp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp",
"javascript/ql/src/Metrics/DuplicationProblems.inc.qhelp",

View File

@@ -203,6 +203,8 @@ namespace Semmle.Autobuild.Cpp.Tests
public IList<DiagnosticMessage> Diagnostics { get; } = new List<DiagnosticMessage>();
public void AddEntry(DiagnosticMessage message) => this.Diagnostics.Add(message);
public void Dispose() { }
}
/// <summary>
@@ -250,12 +252,7 @@ namespace Semmle.Autobuild.Cpp.Tests
EndCallbackIn.Add(s);
}
CppAutobuilder CreateAutoBuilder(bool isWindows,
string? buildless = null, string? solution = null, string? buildCommand = null, string? ignoreErrors = null,
string? msBuildArguments = null, string? msBuildPlatform = null, string? msBuildConfiguration = null, string? msBuildTarget = null,
string? dotnetArguments = null, string? dotnetVersion = null, string? vsToolsVersion = null,
string? nugetRestore = null, string? allSolutions = null,
string cwd = @"C:\Project")
CppAutobuilder CreateAutoBuilder(bool isWindows, string? dotnetVersion = null, string cwd = @"C:\Project")
{
string codeqlUpperLanguage = Language.Cpp.UpperCaseName;
Actions.GetEnvironmentVariable[$"CODEQL_AUTOBUILDER_{codeqlUpperLanguage}_NO_INDEXING"] = "false";
@@ -265,22 +262,7 @@ namespace Semmle.Autobuild.Cpp.Tests
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_DIAGNOSTIC_DIR"] = "";
Actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
Actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = "win64";
Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa";
Actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java";
Actions.GetEnvironmentVariable["SEMMLE_PLATFORM_TOOLS"] = @"C:\odasa\tools";
Actions.GetEnvironmentVariable["LGTM_INDEX_VSTOOLS_VERSION"] = vsToolsVersion;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_ARGUMENTS"] = msBuildArguments;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_PLATFORM"] = msBuildPlatform;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_CONFIGURATION"] = msBuildConfiguration;
Actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_TARGET"] = msBuildTarget;
Actions.GetEnvironmentVariable["LGTM_INDEX_DOTNET_ARGUMENTS"] = dotnetArguments;
Actions.GetEnvironmentVariable["LGTM_INDEX_DOTNET_VERSION"] = dotnetVersion;
Actions.GetEnvironmentVariable["LGTM_INDEX_BUILD_COMMAND"] = buildCommand;
Actions.GetEnvironmentVariable["LGTM_INDEX_SOLUTION"] = solution;
Actions.GetEnvironmentVariable["LGTM_INDEX_IGNORE_ERRORS"] = ignoreErrors;
Actions.GetEnvironmentVariable["LGTM_INDEX_BUILDLESS"] = buildless;
Actions.GetEnvironmentVariable["LGTM_INDEX_ALL_SOLUTIONS"] = allSolutions;
Actions.GetEnvironmentVariable["LGTM_INDEX_NUGET_RESTORE"] = nugetRestore;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_OPTION_DOTNET_VERSION"] = dotnetVersion;
Actions.GetEnvironmentVariable["ProgramFiles(x86)"] = isWindows ? @"C:\Program Files (x86)" : null;
Actions.GetCurrentDirectory = cwd;
Actions.IsWindows = isWindows;

View File

@@ -26,9 +26,6 @@ namespace Semmle.Autobuild.Cpp
public override BuildScript GetBuildScript()
{
if (Options.BuildCommand != null)
return new BuildCommandRule((_, f) => f(null)).Analyse(this, false);
return
// First try MSBuild
new MsBuildRule().Analyse(this, true) |

View File

@@ -17,7 +17,7 @@ namespace Semmle.Autobuild.Cpp
try
{
Console.WriteLine("CodeQL C++ autobuilder");
var builder = new CppAutobuilder(actions, options);
using var builder = new CppAutobuilder(actions, options);
return builder.AttemptBuild();
}
catch (InvalidEnvironmentException ex)

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.12.10
version: 0.12.11-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
@@ -11,4 +11,5 @@ dependencies:
codeql/ssa: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}
codeql/xml: ${workspace}
warnOnImplicitThis: true

View File

@@ -862,7 +862,7 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
or
expr.(DeleteOrDeleteArrayExpr).getDestructorCall() = ele and pred = "getDestructorCall()"
or
expr.(DeleteOrDeleteArrayExpr).getExpr() = ele and pred = "getExpr()"
expr.(DeleteOrDeleteArrayExpr).getExprWithReuse() = ele and pred = "getExprWithReuse()"
or
expr.(DestructorFieldDestruction).getExpr() = ele and pred = "getExpr()"
or

View File

@@ -3,305 +3,67 @@
*/
import semmle.files.FileSystem
private import codeql.xml.Xml
private class TXmlLocatable =
@xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters;
private module Input implements InputSig<File, Location> {
class XmlLocatableBase = @xmllocatable or @xmlnamespaceable;
/** An XML element that has a location. */
class XmlLocatable extends @xmllocatable, TXmlLocatable {
/** Gets the source location for this element. */
Location getLocation() { xmllocations(this, result) }
predicate xmllocations_(XmlLocatableBase e, Location loc) { xmllocations(e, loc) }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
class XmlParentBase = @xmlparent;
class XmlNamespaceableBase = @xmlnamespaceable;
class XmlElementBase = @xmlelement;
class XmlFileBase = File;
predicate xmlEncoding_(XmlFileBase f, string enc) { xmlEncoding(f, enc) }
class XmlDtdBase = @xmldtd;
predicate xmlDTDs_(XmlDtdBase e, string root, string publicId, string systemId, XmlFileBase file) {
xmlDTDs(e, root, publicId, systemId, file)
}
predicate xmlElements_(
XmlElementBase e, string name, XmlParentBase parent, int idx, XmlFileBase file
) {
exists(File f, Location l | l = this.getLocation() |
locations_default(l, f, startline, startcolumn, endline, endcolumn) and
filepath = f.getAbsolutePath()
)
xmlElements(e, name, parent, idx, file)
}
/** Gets a textual representation of this element. */
string toString() { none() } // overridden in subclasses
}
class XmlAttributeBase = @xmlattribute;
/**
* An `XmlParent` is either an `XmlElement` or an `XmlFile`,
* both of which can contain other elements.
*/
class XmlParent extends @xmlparent {
XmlParent() {
// explicitly restrict `this` to be either an `XmlElement` or an `XmlFile`;
// the type `@xmlparent` currently also includes non-XML files
this instanceof @xmlelement or xmlEncoding(this, _)
predicate xmlAttrs_(
XmlAttributeBase e, XmlElementBase elementid, string name, string value, int idx,
XmlFileBase file
) {
xmlAttrs(e, elementid, name, value, idx, file)
}
/**
* Gets a printable representation of this XML parent.
* (Intended to be overridden in subclasses.)
*/
string getName() { none() } // overridden in subclasses
class XmlNamespaceBase = @xmlnamespace;
/** Gets the file to which this XML parent belongs. */
XmlFile getFile() { result = this or xmlElements(this, _, _, _, result) }
/** Gets the child element at a specified index of this XML parent. */
XmlElement getChild(int index) { xmlElements(result, _, this, index, _) }
/** Gets a child element of this XML parent. */
XmlElement getAChild() { xmlElements(result, _, this, _, _) }
/** Gets a child element of this XML parent with the given `name`. */
XmlElement getAChild(string name) { xmlElements(result, _, this, _, _) and result.hasName(name) }
/** Gets a comment that is a child of this XML parent. */
XmlComment getAComment() { xmlComments(result, _, this, _) }
/** Gets a character sequence that is a child of this XML parent. */
XmlCharacters getACharactersSet() { xmlChars(result, _, this, _, _, _) }
/** Gets the depth in the tree. (Overridden in XmlElement.) */
int getDepth() { result = 0 }
/** Gets the number of child XML elements of this XML parent. */
int getNumberOfChildren() { result = count(XmlElement e | xmlElements(e, _, this, _, _)) }
/** Gets the number of places in the body of this XML parent where text occurs. */
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
/**
* Gets the result of appending all the character sequences of this XML parent from
* left to right, separated by a space.
*/
string allCharactersString() {
result =
concat(string chars, int pos | xmlChars(_, chars, this, pos, _, _) | chars, " " order by pos)
predicate xmlNs_(XmlNamespaceBase e, string prefixName, string uri, XmlFileBase file) {
xmlNs(e, prefixName, uri, file)
}
/** Gets the text value contained in this XML parent. */
string getTextValue() { result = this.allCharactersString() }
predicate xmlHasNs_(XmlNamespaceableBase e, XmlNamespaceBase ns, XmlFileBase file) {
xmlHasNs(e, ns, file)
}
/** Gets a printable representation of this XML parent. */
string toString() { result = this.getName() }
}
class XmlCommentBase = @xmlcomment;
/** An XML file. */
class XmlFile extends XmlParent, File {
XmlFile() { xmlEncoding(this, _) }
predicate xmlComments_(XmlCommentBase e, string text, XmlParentBase parent, XmlFileBase file) {
xmlComments(e, text, parent, file)
}
/** Gets a printable representation of this XML file. */
override string toString() { result = this.getName() }
class XmlCharactersBase = @xmlcharacters;
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }
/** Gets the XML file itself. */
override XmlFile getFile() { result = this }
/** Gets a top-most element in an XML file. */
XmlElement getARootElement() { result = this.getAChild() }
/** Gets a DTD associated with this XML file. */
XmlDtd getADtd() { xmlDTDs(result, _, _, _, this) }
}
/**
* An XML document type definition (DTD).
*
* Example:
*
* ```
* <!ELEMENT person (firstName, lastName?)>
* <!ELEMENT firstName (#PCDATA)>
* <!ELEMENT lastName (#PCDATA)>
* ```
*/
class XmlDtd extends XmlLocatable, @xmldtd {
/** Gets the name of the root element of this DTD. */
string getRoot() { xmlDTDs(this, result, _, _, _) }
/** Gets the public ID of this DTD. */
string getPublicId() { xmlDTDs(this, _, result, _, _) }
/** Gets the system ID of this DTD. */
string getSystemId() { xmlDTDs(this, _, _, result, _) }
/** Holds if this DTD is public. */
predicate isPublic() { not xmlDTDs(this, _, "", _, _) }
/** Gets the parent of this DTD. */
XmlParent getParent() { xmlDTDs(this, _, _, _, result) }
override string toString() {
this.isPublic() and
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
or
not this.isPublic() and
result = this.getRoot() + " SYSTEM '" + this.getSystemId() + "'"
predicate xmlChars_(
XmlCharactersBase e, string text, XmlParentBase parent, int idx, int isCDATA, XmlFileBase file
) {
xmlChars(e, text, parent, idx, isCDATA, file)
}
}
/**
* An XML element in an XML file.
*
* Example:
*
* ```
* <manifest xmlns:android="http://schemas.android.com/apk/res/android"
* package="com.example.exampleapp" android:versionCode="1">
* </manifest>
* ```
*/
class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
/** Holds if this XML element has the given `name`. */
predicate hasName(string name) { name = this.getName() }
/** Gets the name of this XML element. */
override string getName() { xmlElements(this, result, _, _, _) }
/** Gets the XML file in which this XML element occurs. */
override XmlFile getFile() { xmlElements(this, _, _, _, result) }
/** Gets the parent of this XML element. */
XmlParent getParent() { xmlElements(this, _, result, _, _) }
/** Gets the index of this XML element among its parent's children. */
int getIndex() { xmlElements(this, _, _, result, _) }
/** Holds if this XML element has a namespace. */
predicate hasNamespace() { xmlHasNs(this, _, _) }
/** Gets the namespace of this XML element, if any. */
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
/** Gets the index of this XML element among its parent's children. */
int getElementPositionIndex() { xmlElements(this, _, _, result, _) }
/** Gets the depth of this element within the XML file tree structure. */
override int getDepth() { result = this.getParent().getDepth() + 1 }
/** Gets an XML attribute of this XML element. */
XmlAttribute getAnAttribute() { result.getElement() = this }
/** Gets the attribute with the specified `name`, if any. */
XmlAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
/** Holds if this XML element has an attribute with the specified `name`. */
predicate hasAttribute(string name) { exists(this.getAttribute(name)) }
/** Gets the value of the attribute with the specified `name`, if any. */
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
/** Gets a printable representation of this XML element. */
override string toString() { result = this.getName() }
}
/**
* An attribute that occurs inside an XML element.
*
* Examples:
*
* ```
* package="com.example.exampleapp"
* android:versionCode="1"
* ```
*/
class XmlAttribute extends @xmlattribute, XmlLocatable {
/** Gets the name of this attribute. */
string getName() { xmlAttrs(this, _, result, _, _, _) }
/** Gets the XML element to which this attribute belongs. */
XmlElement getElement() { xmlAttrs(this, result, _, _, _, _) }
/** Holds if this attribute has a namespace. */
predicate hasNamespace() { xmlHasNs(this, _, _) }
/** Gets the namespace of this attribute, if any. */
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
/** Gets the value of this attribute. */
string getValue() { xmlAttrs(this, _, _, result, _, _) }
/** Gets a printable representation of this XML attribute. */
override string toString() { result = this.getName() + "=" + this.getValue() }
}
/**
* A namespace used in an XML file.
*
* Example:
*
* ```
* xmlns:android="http://schemas.android.com/apk/res/android"
* ```
*/
class XmlNamespace extends XmlLocatable, @xmlnamespace {
/** Gets the prefix of this namespace. */
string getPrefix() { xmlNs(this, result, _, _) }
/** Gets the URI of this namespace. */
string getUri() { xmlNs(this, _, result, _) }
/** Holds if this namespace has no prefix. */
predicate isDefault() { this.getPrefix() = "" }
override string toString() {
this.isDefault() and result = this.getUri()
or
not this.isDefault() and result = this.getPrefix() + ":" + this.getUri()
}
}
/**
* A comment in an XML file.
*
* Example:
*
* ```
* <!-- This is a comment. -->
* ```
*/
class XmlComment extends @xmlcomment, XmlLocatable {
/** Gets the text content of this XML comment. */
string getText() { xmlComments(this, result, _, _) }
/** Gets the parent of this XML comment. */
XmlParent getParent() { xmlComments(this, _, result, _) }
/** Gets a printable representation of this XML comment. */
override string toString() { result = this.getText() }
}
/**
* A sequence of characters that occurs between opening and
* closing tags of an XML element, excluding other elements.
*
* Example:
*
* ```
* <content>This is a sequence of characters.</content>
* ```
*/
class XmlCharacters extends @xmlcharacters, XmlLocatable {
/** Gets the content of this character sequence. */
string getCharacters() { xmlChars(this, result, _, _, _, _) }
/** Gets the parent of this character sequence. */
XmlParent getParent() { xmlChars(this, _, result, _, _, _) }
/** Holds if this character sequence is CDATA. */
predicate isCDATA() { xmlChars(this, _, _, _, 1, _) }
/** Gets a printable representation of this XML character sequence. */
override string toString() { result = this.getCharacters() }
}
import Make<File, Location, Input>

View File

@@ -1015,8 +1015,33 @@ class DeleteOrDeleteArrayExpr extends Expr, TDeleteOrDeleteArrayExpr {
Expr getExpr() {
// If there is a destructor call, the object being deleted is the qualifier
// otherwise it is the third child.
result = this.getChild(3) or result = this.getDestructorCall().getQualifier()
exists(Expr exprWithReuse | exprWithReuse = this.getExprWithReuse() |
if not exprWithReuse instanceof ReuseExpr
then result = exprWithReuse
else result = this.getDestructorCall().getQualifier()
)
}
/**
* Gets the object or array being deleted, and gets a `ReuseExpr` when there
* is a destructor call and the object is also the qualifier of the call.
*
* For example, given:
* ```
* struct HasDestructor { ~HasDestructor(); };
* struct PlainOldData { int x, char y; };
*
* void f(HasDestructor* hasDestructor, PlainOldData* pod) {
* delete hasDestructor;
* delete pod;
* }
* ```
* This predicate yields a `ReuseExpr` for `delete hasDestructor`, as the
* the deleted expression has a destructor, and that expression is also
* the qualifier of the destructor call. In the case of `delete pod` the
* predicate does not yield a `ReuseExpr`, as there is no destructor call.
*/
Expr getExprWithReuse() { result = this.getChild(3) }
}
/**
@@ -1340,7 +1365,17 @@ class ReuseExpr extends Expr, @reuseexpr {
/**
* Gets the expression that is being re-used.
*/
Expr getReusedExpr() { expr_reuse(underlyingElement(this), unresolveElement(result), _) }
Expr getReusedExpr() {
// In the case of a prvalue, the extractor outputs the expression
// before conversion, but the converted expression is intended.
if this.isPRValueCategory()
then result = this.getBaseReusedExpr().getFullyConverted()
else result = this.getBaseReusedExpr()
}
private Expr getBaseReusedExpr() {
expr_reuse(underlyingElement(this), unresolveElement(result), _)
}
override Type getType() { result = this.getReusedExpr().getType() }

View File

@@ -150,11 +150,6 @@ private predicate ignoreExprOnly(Expr expr) {
or
not translateFunction(getEnclosingFunction(expr)) and
not Raw::varHasIRFunc(getEnclosingVariable(expr))
or
exists(DeleteOrDeleteArrayExpr deleteExpr |
// Ignore the destructor call, because the duplicated qualifier breaks control flow.
deleteExpr.getDestructorCall() = expr
)
}
/**

View File

@@ -2245,7 +2245,11 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans
final override Type getCallResultType() { result = expr.getType() }
final override TranslatedExpr getQualifier() { none() }
final override TranslatedExpr getQualifier() {
result = getTranslatedExpr(expr.getDestructorCall())
}
final override Instruction getQualifierResult() { none() }
final override predicate hasArguments() {
// All deallocator calls have at least one argument.
@@ -2260,7 +2264,7 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans
final override TranslatedExpr getArgument(int index) {
// The only argument we define is the pointer to be deallocated.
index = 0 and
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
result = getTranslatedExpr(expr.getExprWithReuse().getFullyConverted())
}
final override predicate mayThrowException() {

View File

@@ -37,6 +37,5 @@ where
DoubleFree::flowPath(source, sink) and
isFree(source.getNode(), _, _, dealloc) and
isFree(sink.getNode(), e2)
select sink.getNode(), source, sink,
"Memory pointed to by '" + e2.toString() + "' may already have been freed by $@.", dealloc,
dealloc.toString()
select sink.getNode(), source, sink, "Memory pointed to by $@ may already have been freed by $@.",
e2, e2.toString(), dealloc, dealloc.toString()

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.9.9
version: 0.9.10-dev
groups:
- cpp
- queries

View File

@@ -426,11 +426,14 @@ DestructorCall.cpp:
# 12| getQualifier(): [VariableAccess] c
# 12| Type = [PointerType] C *
# 12| ValueCategory = prvalue(load)
# 12| getExprWithReuse(): [ReuseExpr] reuse of c
# 12| Type = [PointerType] C *
# 12| ValueCategory = prvalue
# 13| getStmt(1): [ExprStmt] ExprStmt
# 13| getExpr(): [DeleteExpr] delete
# 13| Type = [VoidType] void
# 13| ValueCategory = prvalue
# 13| getExpr(): [VariableAccess] d
# 13| getExprWithReuse(): [VariableAccess] d
# 13| Type = [PointerType] D *
# 13| ValueCategory = prvalue(load)
# 14| getStmt(2): [ReturnStmt] return ...

View File

@@ -14,6 +14,7 @@
| cpp.cpp:10:7:10:7 | operator= | Function |
| cpp.cpp:10:7:10:7 | ~MyClass | Function |
| cpp.cpp:15:5:15:12 | call to ~MyClass | Expr |
| cpp.cpp:15:12:15:12 | reuse of m | Expr |
| cpp.cpp:16:1:16:1 | return ... | Stmt |
| file://:0:0:0:0 | operator delete | Function |
| file://:0:0:0:0 | operator new | Function |

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1933,6 +1933,20 @@ namespace missing_declaration_entries {
Bar2<int> b;
b.two_missing_variable_declaration_entries();
}
template<typename T> struct Bar3 {
int two_more_missing_variable_declaration_entries() {
extern int g;
int z(float);
return g;
}
};
void test3() {
Bar3<int> b;
b.two_more_missing_variable_declaration_entries();
}
}
template<typename T> T global_template = 42;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -41,16 +41,16 @@ nodes
| test_free.cpp:302:12:302:14 | buf | semmle.label | buf |
subpaths
#select
| test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:14:10:14:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
| test_free.cpp:31:27:31:27 | a | test_free.cpp:30:10:30:10 | pointer to free output argument | test_free.cpp:31:27:31:27 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:30:5:30:8 | call to free | call to free |
| test_free.cpp:37:27:37:27 | a | test_free.cpp:35:10:35:10 | pointer to free output argument | test_free.cpp:37:27:37:27 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:35:5:35:8 | call to free | call to free |
| test_free.cpp:46:10:46:10 | a | test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free |
| test_free.cpp:46:10:46:10 | a | test_free.cpp:44:27:44:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:44:22:44:25 | call to free | call to free |
| test_free.cpp:51:10:51:10 | a | test_free.cpp:50:27:50:27 | pointer to free output argument | test_free.cpp:51:10:51:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:50:22:50:25 | call to free | call to free |
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | pointer to free output argument | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
| test_free.cpp:85:12:85:12 | a | test_free.cpp:83:12:83:12 | pointer to operator delete output argument | test_free.cpp:85:12:85:12 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
| test_free.cpp:103:10:103:10 | a | test_free.cpp:101:10:101:10 | pointer to free output argument | test_free.cpp:103:10:103:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:101:5:101:8 | call to free | call to free |
| test_free.cpp:129:10:129:11 | * ... | test_free.cpp:128:10:128:11 | pointer to free output argument | test_free.cpp:129:10:129:11 | * ... | Memory pointed to by '* ...' may already have been freed by $@. | test_free.cpp:128:5:128:8 | call to free | call to free |
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:152:22:152:25 | call to free | call to free |
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
| test_free.cpp:302:12:302:14 | buf | test_free.cpp:301:12:301:14 | pointer to g_free output argument | test_free.cpp:302:12:302:14 | buf | Memory pointed to by 'buf' may already have been freed by $@. | test_free.cpp:301:5:301:10 | call to g_free | call to g_free |
| test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:14:10:14:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:14:10:14:10 | a | a | test_free.cpp:11:5:11:8 | call to free | call to free |
| test_free.cpp:31:27:31:27 | a | test_free.cpp:30:10:30:10 | pointer to free output argument | test_free.cpp:31:27:31:27 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:31:27:31:27 | a | a | test_free.cpp:30:5:30:8 | call to free | call to free |
| test_free.cpp:37:27:37:27 | a | test_free.cpp:35:10:35:10 | pointer to free output argument | test_free.cpp:37:27:37:27 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:37:27:37:27 | a | a | test_free.cpp:35:5:35:8 | call to free | call to free |
| test_free.cpp:46:10:46:10 | a | test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:46:10:46:10 | a | a | test_free.cpp:42:22:42:25 | call to free | call to free |
| test_free.cpp:46:10:46:10 | a | test_free.cpp:44:27:44:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:46:10:46:10 | a | a | test_free.cpp:44:22:44:25 | call to free | call to free |
| test_free.cpp:51:10:51:10 | a | test_free.cpp:50:27:50:27 | pointer to free output argument | test_free.cpp:51:10:51:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:51:10:51:10 | a | a | test_free.cpp:50:22:50:25 | call to free | call to free |
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | pointer to free output argument | test_free.cpp:72:14:72:14 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:72:14:72:14 | a | a | test_free.cpp:69:5:69:8 | call to free | call to free |
| test_free.cpp:85:12:85:12 | a | test_free.cpp:83:12:83:12 | pointer to operator delete output argument | test_free.cpp:85:12:85:12 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:85:12:85:12 | a | a | test_free.cpp:83:5:83:13 | delete | delete |
| test_free.cpp:103:10:103:10 | a | test_free.cpp:101:10:101:10 | pointer to free output argument | test_free.cpp:103:10:103:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:103:10:103:10 | a | a | test_free.cpp:101:5:101:8 | call to free | call to free |
| test_free.cpp:129:10:129:11 | * ... | test_free.cpp:128:10:128:11 | pointer to free output argument | test_free.cpp:129:10:129:11 | * ... | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:129:10:129:11 | * ... | * ... | test_free.cpp:128:5:128:8 | call to free | call to free |
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:154:10:154:10 | a | a | test_free.cpp:152:22:152:25 | call to free | call to free |
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:209:10:209:10 | a | a | test_free.cpp:207:5:207:8 | call to free | call to free |
| test_free.cpp:302:12:302:14 | buf | test_free.cpp:301:12:301:14 | pointer to g_free output argument | test_free.cpp:302:12:302:14 | buf | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:302:12:302:14 | buf | buf | test_free.cpp:301:5:301:10 | call to g_free | call to g_free |

View File

@@ -218,6 +218,8 @@ namespace Semmle.Autobuild.CSharp.Tests
public IList<DiagnosticMessage> Diagnostics { get; } = new List<DiagnosticMessage>();
public void AddEntry(DiagnosticMessage message) => this.Diagnostics.Add(message);
public void Dispose() { }
}
/// <summary>
@@ -399,10 +401,8 @@ namespace Semmle.Autobuild.CSharp.Tests
}
private CSharpAutobuilder CreateAutoBuilder(bool isWindows,
string? buildless = null, string? solution = null, string? buildCommand = null, string? ignoreErrors = null,
string? msBuildArguments = null, string? msBuildPlatform = null, string? msBuildConfiguration = null, string? msBuildTarget = null,
string? dotnetArguments = null, string? dotnetVersion = null, string? vsToolsVersion = null,
string? nugetRestore = null, string? allSolutions = null,
string? buildless = null,
string? dotnetVersion = null,
string cwd = @"C:\Project")
{
var codeqlUpperLanguage = Language.CSharp.UpperCaseName;
@@ -412,20 +412,9 @@ namespace Semmle.Autobuild.CSharp.Tests
actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_DIAGNOSTIC_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = isWindows ? "win64" : "linux64";
actions.GetEnvironmentVariable["LGTM_INDEX_VSTOOLS_VERSION"] = vsToolsVersion;
actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_ARGUMENTS"] = msBuildArguments;
actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_PLATFORM"] = msBuildPlatform;
actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_CONFIGURATION"] = msBuildConfiguration;
actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_TARGET"] = msBuildTarget;
actions.GetEnvironmentVariable["LGTM_INDEX_DOTNET_ARGUMENTS"] = dotnetArguments;
actions.GetEnvironmentVariable["LGTM_INDEX_DOTNET_VERSION"] = dotnetVersion;
actions.GetEnvironmentVariable["LGTM_INDEX_BUILD_COMMAND"] = buildCommand;
actions.GetEnvironmentVariable["LGTM_INDEX_SOLUTION"] = solution;
actions.GetEnvironmentVariable["LGTM_INDEX_IGNORE_ERRORS"] = ignoreErrors;
actions.GetEnvironmentVariable["LGTM_INDEX_BUILDLESS"] = buildless;
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_OPTION_BUILDLESS"] = buildless;
actions.GetEnvironmentVariable["LGTM_INDEX_ALL_SOLUTIONS"] = allSolutions;
actions.GetEnvironmentVariable["LGTM_INDEX_NUGET_RESTORE"] = nugetRestore;
if (dotnetVersion is not null)
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_OPTION_DOTNET_VERSION"] = dotnetVersion;
actions.GetEnvironmentVariable["ProgramFiles(x86)"] = isWindows ? @"C:\Program Files (x86)" : null;
actions.GetCurrentDirectory = cwd;
actions.IsWindows = isWindows;
@@ -600,15 +589,6 @@ namespace Semmle.Autobuild.CSharp.Tests
TestAutobuilderScript(autobuilder, 0, 1);
}
private void SkipVsWhere()
{
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = false;
}
private void TestAutobuilderScript(CSharpAutobuilder autobuilder, int expectedOutput, int commandsRun)
{
Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(actions, StartCallback, EndCallback));
@@ -628,23 +608,6 @@ namespace Semmle.Autobuild.CSharp.Tests
}
}
[Fact]
public void TestLinuxBuildCommand()
{
actions.RunProcess["./build.sh --skip-tests"] = 0;
actions.FileExists["csharp.log"] = true;
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.sln";
actions.EnumerateDirectories[@"C:\Project"] = "";
SkipVsWhere();
var autobuilder = CreateAutoBuilder(false, buildCommand: "./build.sh --skip-tests");
TestAutobuilderScript(autobuilder, 0, 1);
}
[Fact]
public void TestLinuxBuildSh()
{
@@ -714,177 +677,6 @@ namespace Semmle.Autobuild.CSharp.Tests
TestAutobuilderScript(autobuilder, 0, 1);
}
[Fact]
public void TestWindowsBuildBatIgnoreErrors()
{
actions.EnumerateFiles[@"C:\Project"] = "foo.cs\nbuild.bat";
actions.EnumerateDirectories[@"C:\Project"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.RunProcess[@"cmd.exe /C C:\Project\build.bat"] = 1;
actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\Project\build.bat"] = @"C:\Project";
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0;
actions.FileExists["csharp.log"] = true;
var autobuilder = CreateAutoBuilder(true, ignoreErrors: "true");
TestAutobuilderScript(autobuilder, 1, 1);
}
[Fact]
public void TestWindowsCmdIgnoreErrors()
{
actions.RunProcess["cmd.exe /C ^\"build.cmd^ --skip-tests^\""] = 3;
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0;
actions.FileExists["csharp.log"] = true;
SkipVsWhere();
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.sln";
actions.EnumerateDirectories[@"C:\Project"] = "";
var autobuilder = CreateAutoBuilder(true, buildCommand: "build.cmd --skip-tests", ignoreErrors: "true");
TestAutobuilderScript(autobuilder, 3, 1);
}
[Fact]
public void TestWindowCSharpMsBuild()
{
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln -DisableParallelProcessing"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
actions.FileExists["csharp.log"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = true;
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest1.cs\ntest2.cs";
actions.EnumerateFiles[@"C:\Project\.nuget"] = "nuget.exe";
actions.EnumerateDirectories[@"C:\Project"] = @".nuget";
actions.EnumerateDirectories[@"C:\Project\.nuget"] = "";
var autobuilder = CreateAutoBuilder(true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows", msBuildPlatform: "x86", msBuildConfiguration: "Debug",
vsToolsVersion: "12", allSolutions: "true");
var testSolution1 = new TestSolution(@"C:\Project\test1.sln");
var testSolution2 = new TestSolution(@"C:\Project\test2.sln");
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution1);
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution2);
TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
public void TestWindowCSharpMsBuildMultipleSolutions()
{
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj -DisableParallelProcessing"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj -DisableParallelProcessing"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
actions.FileExists["csharp.log"] = true;
actions.FileExists[@"C:\Project\test1.csproj"] = true;
actions.FileExists[@"C:\Project\test2.csproj"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = true;
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.EnumerateFiles[@"C:\Project"] = "test1.csproj\ntest2.csproj\ntest1.cs\ntest2.cs";
actions.EnumerateDirectories[@"C:\Project"] = "";
var csproj1 = new XmlDocument();
csproj1.LoadXml(@"<?xml version=""1.0"" encoding=""utf - 8""?>
<Project ToolsVersion=""15.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<ItemGroup>
<Compile Include=""test1.cs"" />
</ItemGroup>
</Project>");
actions.LoadXml[@"C:\Project\test1.csproj"] = csproj1;
var csproj2 = new XmlDocument();
csproj2.LoadXml(@"<?xml version=""1.0"" encoding=""utf - 8""?>
<Project ToolsVersion=""15.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<ItemGroup>
<Compile Include=""test1.cs"" />
</ItemGroup>
</Project>");
actions.LoadXml[@"C:\Project\test2.csproj"] = csproj2;
var autobuilder = CreateAutoBuilder(true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows", msBuildPlatform: "x86", msBuildConfiguration: "Debug",
vsToolsVersion: "12");
TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
public void TestWindowCSharpMsBuildFailed()
{
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 1;
actions.FileExists["csharp.log"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = true;
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest1.cs\ntest2.cs";
actions.EnumerateDirectories[@"C:\Project"] = "";
var autobuilder = CreateAutoBuilder(true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows", msBuildPlatform: "x86", msBuildConfiguration: "Debug",
vsToolsVersion: "12", allSolutions: "true");
var testSolution1 = new TestSolution(@"C:\Project\test1.sln");
var testSolution2 = new TestSolution(@"C:\Project\test2.sln");
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution1);
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution2);
TestAutobuilderScript(autobuilder, 1, 2);
}
[Fact]
public void TestSkipNugetMsBuild()
{
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
actions.FileExists["csharp.log"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"] = true;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"] = false;
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = true;
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest1.cs\ntest2.cs";
actions.EnumerateDirectories[@"C:\Project"] = "";
var autobuilder = CreateAutoBuilder(true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows",
msBuildPlatform: "x86", msBuildConfiguration: "Debug", vsToolsVersion: "12",
allSolutions: "true", nugetRestore: "false");
var testSolution1 = new TestSolution(@"C:\Project\test1.sln");
var testSolution2 = new TestSolution(@"C:\Project\test2.sln");
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution1);
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution2);
TestAutobuilderScript(autobuilder, 0, 2);
}
[Fact]
public void TestSkipNugetBuildless()
{
@@ -900,35 +692,6 @@ namespace Semmle.Autobuild.CSharp.Tests
TestAutobuilderScript(autobuilder, 0, 1);
}
[Fact]
public void TestSkipNugetDotnet()
{
actions.RunProcess["dotnet --info"] = 0;
actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0;
actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0;
actions.RunProcess[@"dotnet build --no-incremental --no-restore C:\Project/test.csproj"] = 0;
actions.FileExists["csharp.log"] = true;
actions.FileExists[@"C:\Project/test.csproj"] = true;
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR"] = "scratch";
actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.cs\ntest.csproj";
actions.EnumerateDirectories[@"C:\Project"] = "";
var xml = new XmlDocument();
xml.LoadXml(@"<Project Sdk=""Microsoft.NET.Sdk"">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
</Project>");
actions.LoadXml[@"C:\Project/test.csproj"] = xml;
var autobuilder = CreateAutoBuilder(false, dotnetArguments: "--no-restore"); // nugetRestore=false does not work for now.
TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
public void TestDotnetVersionNotInstalled()
{
@@ -1053,7 +816,7 @@ namespace Semmle.Autobuild.CSharp.Tests
{
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj -DisableParallelProcessing"] = 1;
actions.RunProcess[@"cmd.exe /C scratch\.nuget\nuget.exe restore C:\Project\dirs.proj -DisableParallelProcessing"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /t:rebuild"] = 0;
actions.FileExists["csharp.log"] = true;
actions.FileExists[@"C:\Project\a\test.csproj"] = true;
actions.FileExists[@"C:\Project\dirs.proj"] = true;
@@ -1088,8 +851,7 @@ namespace Semmle.Autobuild.CSharp.Tests
</Project>");
actions.LoadXml[@"C:\Project\dirs.proj"] = dirsproj;
var autobuilder = CreateAutoBuilder(true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows", msBuildPlatform: "x86", msBuildConfiguration: "Debug",
vsToolsVersion: "12", allSolutions: "true");
var autobuilder = CreateAutoBuilder(true);
TestAutobuilderScript(autobuilder, 0, 3);
}

View File

@@ -25,9 +25,11 @@ namespace Semmle.Autobuild.CSharp
/// </summary>
public CSharpAutobuildOptions(IBuildActions actions) : base(actions)
{
Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) ||
Buildless =
actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false) ||
actions.GetEnvironmentVariable(buildModeEnvironmentVariable)?.ToLower() == "none";
}
}
@@ -46,21 +48,12 @@ namespace Semmle.Autobuild.CSharp
var attempt = BuildScript.Failure;
switch (GetCSharpBuildStrategy())
{
case CSharpBuildStrategy.CustomBuildCommand:
attempt = new BuildCommandRule(DotNetRule.WithDotNet).Analyse(this, false) & CheckExtractorRun(true);
break;
case CSharpBuildStrategy.Buildless:
// No need to check that the extractor has been executed in buildless mode
attempt = BuildScript.Bind(
AddBuildlessStartedDiagnostic() & new StandaloneBuildRule().Analyse(this, false),
AddBuildlessEndedDiagnostic);
break;
case CSharpBuildStrategy.MSBuild:
attempt = new MsBuildRule().Analyse(this, false) & CheckExtractorRun(true);
break;
case CSharpBuildStrategy.DotNet:
attempt = new DotNetRule().Analyse(this, false) & CheckExtractorRun(true);
break;
case CSharpBuildStrategy.Auto:
attempt =
// Attempt a few different build strategies to see if one works
@@ -246,32 +239,15 @@ namespace Semmle.Autobuild.CSharp
/// </summary>
private CSharpBuildStrategy GetCSharpBuildStrategy()
{
if (Options.BuildCommand is not null)
return CSharpBuildStrategy.CustomBuildCommand;
if (Options.Buildless)
return CSharpBuildStrategy.Buildless;
if (Options.MsBuildArguments is not null
|| Options.MsBuildConfiguration is not null
|| Options.MsBuildPlatform is not null
|| Options.MsBuildTarget is not null)
{
return CSharpBuildStrategy.MSBuild;
}
if (Options.DotNetArguments is not null || Options.DotNetVersion is not null)
return CSharpBuildStrategy.DotNet;
return CSharpBuildStrategy.Auto;
}
private enum CSharpBuildStrategy
{
CustomBuildCommand,
Buildless,
MSBuild,
DotNet,
Auto
}
}

View File

@@ -32,7 +32,7 @@ namespace Semmle.Autobuild.CSharp
if (auto)
{
NotDotNetProjects = builder.ProjectsOrSolutionsToBuild
.SelectMany(p => Enumerators.Singleton(p).Concat(p.IncludedProjects))
.SelectMany(p => new[] { p }.Concat(p.IncludedProjects))
.OfType<Project<CSharpAutobuildOptions>>()
.Where(p => !p.DotNetProject);
var notDotNetProject = NotDotNetProjects.FirstOrDefault();
@@ -150,8 +150,7 @@ namespace Semmle.Autobuild.CSharp
Argument("--no-incremental");
return
script.Argument(builder.Options.DotNetArguments).
QuoteArgument(projOrSln).
script.QuoteArgument(projOrSln).
Script;
}
}

View File

@@ -17,7 +17,7 @@ namespace Semmle.Autobuild.CSharp
try
{
Console.WriteLine("CodeQL C# autobuilder");
var builder = new CSharpAutobuilder(actions, options);
using var builder = new CSharpAutobuilder(actions, options);
return builder.AttemptBuild();
}
catch (InvalidEnvironmentException ex)

View File

@@ -11,24 +11,9 @@ namespace Semmle.Autobuild.Shared
/// </summary>
public abstract class AutobuildOptionsShared
{
protected const string lgtmPrefix = "LGTM_INDEX_";
public int SearchDepth { get; } = 3;
public string RootDirectory { get; }
public string? VsToolsVersion { get; }
public string? MsBuildArguments { get; }
public string? MsBuildPlatform { get; }
public string? MsBuildConfiguration { get; }
public string? MsBuildTarget { get; }
public string? DotNetArguments { get; }
public string? DotNetVersion { get; }
public string? BuildCommand { get; }
public IEnumerable<string> Solution { get; }
public bool IgnoreErrors { get; }
public bool AllSolutions { get; }
public bool NugetRestore { get; }
public abstract Language Language { get; }
/// <summary>
@@ -38,19 +23,7 @@ namespace Semmle.Autobuild.Shared
public AutobuildOptionsShared(IBuildActions actions)
{
RootDirectory = actions.GetCurrentDirectory();
VsToolsVersion = actions.GetEnvironmentVariable(lgtmPrefix + "VSTOOLS_VERSION");
MsBuildArguments = actions.GetEnvironmentVariable(lgtmPrefix + "MSBUILD_ARGUMENTS")?.AsStringWithExpandedEnvVars(actions);
MsBuildPlatform = actions.GetEnvironmentVariable(lgtmPrefix + "MSBUILD_PLATFORM");
MsBuildConfiguration = actions.GetEnvironmentVariable(lgtmPrefix + "MSBUILD_CONFIGURATION");
MsBuildTarget = actions.GetEnvironmentVariable(lgtmPrefix + "MSBUILD_TARGET");
DotNetArguments = actions.GetEnvironmentVariable(lgtmPrefix + "DOTNET_ARGUMENTS")?.AsStringWithExpandedEnvVars(actions);
DotNetVersion = actions.GetEnvironmentVariable(lgtmPrefix + "DOTNET_VERSION");
BuildCommand = actions.GetEnvironmentVariable(lgtmPrefix + "BUILD_COMMAND");
Solution = actions.GetEnvironmentVariable(lgtmPrefix + "SOLUTION").AsListWithExpandedEnvVars(actions, Array.Empty<string>());
IgnoreErrors = actions.GetEnvironmentVariable(lgtmPrefix + "IGNORE_ERRORS").AsBool("ignore_errors", false);
AllSolutions = actions.GetEnvironmentVariable(lgtmPrefix + "ALL_SOLUTIONS").AsBool("all_solutions", false);
NugetRestore = actions.GetEnvironmentVariable(lgtmPrefix + "NUGET_RESTORE").AsBool("nuget_restore", true);
DotNetVersion = actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_DOTNET_VERSION");
}
}

View File

@@ -92,7 +92,7 @@ namespace Semmle.Autobuild.Shared
/// The overall design is intended to be extensible so that in theory,
/// it should be possible to add new build rules without touching this code.
/// </summary>
public abstract class Autobuilder<TAutobuildOptions> : IAutobuilder<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
public abstract class Autobuilder<TAutobuildOptions> : IDisposable, IAutobuilder<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
{
/// <summary>
/// Full file paths of files found in the project directory, as well as
@@ -161,9 +161,6 @@ namespace Semmle.Autobuild.Shared
if (matchingFiles.Length == 0)
return null;
if (Options.AllSolutions)
return matchingFiles.Select(p => p.ProjectOrSolution);
return matchingFiles
.Where(f => f.DistanceFromRoot == matchingFiles[0].DistanceFromRoot)
.Select(f => f.ProjectOrSolution);
@@ -185,19 +182,6 @@ namespace Semmle.Autobuild.Shared
projectsOrSolutionsToBuildLazy = new Lazy<IList<IProjectOrSolution>>(() =>
{
List<IProjectOrSolution>? ret;
if (options.Solution.Any())
{
ret = new List<IProjectOrSolution>();
foreach (var solution in options.Solution)
{
if (actions.FileExists(solution))
ret.Add(new Solution<TAutobuildOptions>(this, solution, true));
else
logger.LogError($"The specified project or solution file {solution} was not found");
}
return ret;
}
// First look for `.proj` files
ret = FindFiles(".proj", f => new Project<TAutobuildOptions>(this, f))?.ToList();
if (ret is not null)
@@ -285,9 +269,6 @@ namespace Semmle.Autobuild.Shared
var script = GetBuildScript();
if (Options.IgnoreErrors)
script |= BuildScript.Success;
void startCallback(string s, bool silent)
{
logger.Log(silent ? Severity.Debug : Severity.Info, $"\nRunning {s}");
@@ -370,6 +351,20 @@ namespace Semmle.Autobuild.Shared
}
});
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
diagnostics.Dispose();
}
}
/// <summary>
/// Value of CODEQL_EXTRACTOR_<LANG>_ROOT environment variable.
/// </summary>

View File

@@ -82,11 +82,6 @@ namespace Semmle.Autobuild.Shared
{
var command = new CommandBuilder(builder.Actions, dir, environment);
// A specific Visual Studio version may be required
var vsTools = MsBuildRule.GetVcVarsBatFile(builder);
if (vsTools is not null)
command.CallBatFile(vsTools.Path);
command.RunCommand(this.ScriptPath);
return command.Script;
});

View File

@@ -1,37 +0,0 @@
using Semmle.Util;
namespace Semmle.Autobuild.Shared
{
/// <summary>
/// Execute the build_command rule.
/// </summary>
public class BuildCommandRule : IBuildRule<AutobuildOptionsShared>
{
private readonly WithDotNet<AutobuildOptionsShared> withDotNet;
public BuildCommandRule(WithDotNet<AutobuildOptionsShared> withDotNet)
{
this.withDotNet = withDotNet;
}
public BuildScript Analyse(IAutobuilder<AutobuildOptionsShared> builder, bool auto)
{
if (builder.Options.BuildCommand is null)
return BuildScript.Failure;
// Custom build commands may require a specific .NET Core version
return withDotNet(builder, environment =>
{
var command = new CommandBuilder(builder.Actions, null, environment);
// Custom build commands may require a specific Visual Studio version
var vsTools = MsBuildRule.GetVcVarsBatFile(builder);
if (vsTools is not null)
command.CallBatFile(vsTools.Path);
command.RunCommand(builder.Options.BuildCommand);
return command.Script;
});
}
}
}

View File

@@ -42,9 +42,9 @@ namespace Semmle.Autobuild.Shared
if (auto)
builder.Logger.LogInfo("Attempting to build using MSBuild");
var vsTools = GetVcVarsBatFile(builder);
VcVarsBatFile? vsTools = null;
if (vsTools is null && builder.ProjectsOrSolutionsToBuild.Any())
if (builder.ProjectsOrSolutionsToBuild.Any())
{
var firstSolution = builder.ProjectsOrSolutionsToBuild.OfType<ISolution>().FirstOrDefault();
vsTools = firstSolution is not null
@@ -67,46 +67,44 @@ namespace Semmle.Autobuild.Shared
foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild)
{
if (builder.Options.NugetRestore)
BuildScript GetNugetRestoreScript() =>
new CommandBuilder(builder.Actions).
RunCommand(nuget).
Argument("restore").
QuoteArgument(projectOrSolution.FullPath).
Argument("-DisableParallelProcessing").
Script;
var nugetRestore = GetNugetRestoreScript();
var msbuildRestoreCommand = new CommandBuilder(builder.Actions).
MsBuildCommand(builder).
Argument("/t:restore").
QuoteArgument(projectOrSolution.FullPath);
if (builder.Actions.IsRunningOnAppleSilicon())
{
BuildScript GetNugetRestoreScript() =>
new CommandBuilder(builder.Actions).
RunCommand(nuget).
Argument("restore").
QuoteArgument(projectOrSolution.FullPath).
Argument("-DisableParallelProcessing").
Script;
var nugetRestore = GetNugetRestoreScript();
var msbuildRestoreCommand = new CommandBuilder(builder.Actions).
MsBuildCommand(builder).
Argument("/t:restore").
QuoteArgument(projectOrSolution.FullPath);
// On Apple Silicon, only try package restore with `dotnet msbuild /t:restore`
ret &= BuildScript.Try(msbuildRestoreCommand.Script);
}
else if (nugetDownloaded)
{
ret &= BuildScript.Try(nugetRestore | msbuildRestoreCommand.Script);
}
else
{
// If `nuget restore` fails, and we have not already attempted to download `nuget.exe`,
// download it and reattempt `nuget restore`.
var nugetDownloadAndRestore =
BuildScript.Bind(DownloadNugetExe(builder, nugetDownloadPath), exitCode =>
{
nugetDownloaded = true;
if (exitCode != 0)
return BuildScript.Failure;
if (builder.Actions.IsRunningOnAppleSilicon())
{
// On Apple Silicon, only try package restore with `dotnet msbuild /t:restore`
ret &= BuildScript.Try(msbuildRestoreCommand.Script);
}
else if (nugetDownloaded)
{
ret &= BuildScript.Try(nugetRestore | msbuildRestoreCommand.Script);
}
else
{
// If `nuget restore` fails, and we have not already attempted to download `nuget.exe`,
// download it and reattempt `nuget restore`.
var nugetDownloadAndRestore =
BuildScript.Bind(DownloadNugetExe(builder, nugetDownloadPath), exitCode =>
{
nugetDownloaded = true;
if (exitCode != 0)
return BuildScript.Failure;
nuget = nugetDownloadPath;
return GetNugetRestoreScript();
});
ret &= BuildScript.Try(nugetRestore | nugetDownloadAndRestore | msbuildRestoreCommand.Script);
}
nuget = nugetDownloadPath;
return GetNugetRestoreScript();
});
ret &= BuildScript.Try(nugetRestore | nugetDownloadAndRestore | msbuildRestoreCommand.Script);
}
var command = new CommandBuilder(builder.Actions);
@@ -124,9 +122,9 @@ namespace Semmle.Autobuild.Shared
command.MsBuildCommand(builder);
command.QuoteArgument(projectOrSolution.FullPath);
var target = builder.Options.MsBuildTarget ?? "rebuild";
var platform = builder.Options.MsBuildPlatform ?? (projectOrSolution is ISolution s1 ? s1.DefaultPlatformName : null);
var configuration = builder.Options.MsBuildConfiguration ?? (projectOrSolution is ISolution s2 ? s2.DefaultConfigurationName : null);
var target = "rebuild";
var platform = projectOrSolution is ISolution s1 ? s1.DefaultPlatformName : null;
var configuration = projectOrSolution is ISolution s2 ? s2.DefaultConfigurationName : null;
command.Argument("/t:" + target);
if (platform is not null)
@@ -134,8 +132,6 @@ namespace Semmle.Autobuild.Shared
if (configuration is not null)
command.Argument(string.Format("/p:Configuration=\"{0}\"", configuration));
command.Argument(builder.Options.MsBuildArguments);
// append the build script which invokes msbuild to the overall build script `ret`;
// we insert a check that building the current project or solution was successful:
// if it was not successful, we add it to `FailedProjectsOrSolutions`
@@ -148,41 +144,6 @@ namespace Semmle.Autobuild.Shared
return ret;
}
/// <summary>
/// Gets the BAT file used to initialize the appropriate Visual Studio
/// version/platform, as specified by the `vstools_version` property in
/// lgtm.yml.
///
/// Returns <code>null</code> when no version is specified.
/// </summary>
public static VcVarsBatFile? GetVcVarsBatFile<TAutobuildOptions>(IAutobuilder<TAutobuildOptions> builder) where TAutobuildOptions : AutobuildOptionsShared
{
VcVarsBatFile? vsTools = null;
if (builder.Options.VsToolsVersion is not null)
{
if (int.TryParse(builder.Options.VsToolsVersion, out var msToolsVersion))
{
foreach (var b in BuildTools.VcVarsAllBatFiles(builder.Actions))
{
builder.Logger.Log(Severity.Info, "Found {0} version {1}", b.Path, b.ToolsVersion);
}
vsTools = BuildTools.FindCompatibleVcVars(builder.Actions, msToolsVersion);
if (vsTools is null)
builder.Logger.LogWarning("Could not find build tools matching version {0}", msToolsVersion);
else
builder.Logger.Log(Severity.Info, "Setting Visual Studio tools to {0}", vsTools.Path);
}
else
{
builder.Logger.LogError("The format of vstools_version is incorrect. Please specify an integer.");
}
}
return vsTools;
}
/// <summary>
/// Returns a script for downloading `nuget.exe` from nuget.org.
/// </summary>

View File

@@ -1,44 +1,44 @@
package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:log-injection,sink:sql-injection,source:commandargs,source:environment,source:file,source:file-write,source:local,source:remote,source:windows-registry,summary:taint,summary:value
Amazon.Lambda.APIGatewayEvents,,6,,,,,,,,,,,,,,,,,6,,,
Amazon.Lambda.Core,10,,,,,,,,,,,10,,,,,,,,,,
Dapper,55,,,,,,,,,,,,55,,,,,,,,,
ILCompiler,,,81,,,,,,,,,,,,,,,,,,81,
ILLink.RoslynAnalyzer,,,63,,,,,,,,,,,,,,,,,,63,
ILLink.Shared,,,32,,,,,,,,,,,,,,,,,,29,3
ILLink.Tasks,,,5,,,,,,,,,,,,,,,,,,5,
Internal.IL,,,69,,,,,,,,,,,,,,,,,,67,2
Internal.Pgo,,,9,,,,,,,,,,,,,,,,,,8,1
Internal.TypeSystem,,,367,,,,,,,,,,,,,,,,,,331,36
JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,,,,,7,
Microsoft.Android.Build,,,14,,,,,,,,,,,,,,,,,,14,
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,,7,
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,,
Microsoft.CSharp,,,24,,,,,,,,,,,,,,,,,,24,
Microsoft.Diagnostics.Tools.Pgo,,,13,,,,,,,,,,,,,,,,,,13,
Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,,6,,,,,,,,,12
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,,,,,15,
Microsoft.Extensions.Caching.Memory,,,38,,,,,,,,,,,,,,,,,,37,1
Microsoft.Extensions.Configuration,,2,89,,,,,,,,,,,,2,,,,,,86,3
Microsoft.Extensions.DependencyInjection,,,120,,,,,,,,,,,,,,,,,,120,
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,,,,,,12,
Microsoft.Extensions.Diagnostics.Metrics,,,13,,,,,,,,,,,,,,,,,,13,
Microsoft.Extensions.FileProviders,,,15,,,,,,,,,,,,,,,,,,15,
Microsoft.Extensions.FileSystemGlobbing,,,16,,,,,,,,,,,,,,,,,,14,2
Microsoft.Extensions.Hosting,,,23,,,,,,,,,,,,,,,,,,22,1
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,,,,,,10,
Microsoft.Extensions.Logging,,,60,,,,,,,,,,,,,,,,,,59,1
Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,,,,,,8,
Microsoft.Extensions.Primitives,,,64,,,,,,,,,,,,,,,,,,64,
Microsoft.Interop,,,78,,,,,,,,,,,,,,,,,,78,
Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,,,,,1,
Microsoft.NET.WebAssembly.Webcil,,,7,,,,,,,,,,,,,,,,,,7,
Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,,,,,5,5
Microsoft.WebAssembly.Build.Tasks,,,3,,,,,,,,,,,,,,,,,,3,
Microsoft.Win32,,4,4,,,,,,,,,,,,,,,,,4,4,
Mono.Linker,,,163,,,,,,,,,,,,,,,,,,163,
MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,,
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,,73,18
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,,7,
SourceGenerators,,,4,,,,,,,,,,,,,,,,,,4,
System,67,30,11864,,8,8,9,,,4,5,,33,2,3,1,17,3,4,,9898,1966
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,,
package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:log-injection,sink:sql-injection,source:commandargs,source:database,source:environment,source:file,source:file-write,source:local,source:remote,source:windows-registry,summary:taint,summary:value
Amazon.Lambda.APIGatewayEvents,,6,,,,,,,,,,,,,,,,,,6,,,
Amazon.Lambda.Core,10,,,,,,,,,,,10,,,,,,,,,,,
Dapper,55,42,1,,,,,,,,,,55,,42,,,,,,,,1
ILCompiler,,,81,,,,,,,,,,,,,,,,,,,81,
ILLink.RoslynAnalyzer,,,63,,,,,,,,,,,,,,,,,,,63,
ILLink.Shared,,,32,,,,,,,,,,,,,,,,,,,29,3
ILLink.Tasks,,,5,,,,,,,,,,,,,,,,,,,5,
Internal.IL,,,69,,,,,,,,,,,,,,,,,,,67,2
Internal.Pgo,,,9,,,,,,,,,,,,,,,,,,,8,1
Internal.TypeSystem,,,367,,,,,,,,,,,,,,,,,,,331,36
JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,,,,,,7,
Microsoft.Android.Build,,,14,,,,,,,,,,,,,,,,,,,14,
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,,,7,
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,,,
Microsoft.CSharp,,,24,,,,,,,,,,,,,,,,,,,24,
Microsoft.Diagnostics.Tools.Pgo,,,13,,,,,,,,,,,,,,,,,,,13,
Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,,6,,,,,,,,,,12
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,,,,,,15,
Microsoft.Extensions.Caching.Memory,,,38,,,,,,,,,,,,,,,,,,,37,1
Microsoft.Extensions.Configuration,,2,89,,,,,,,,,,,,,2,,,,,,86,3
Microsoft.Extensions.DependencyInjection,,,120,,,,,,,,,,,,,,,,,,,120,
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,,,,,,,12,
Microsoft.Extensions.Diagnostics.Metrics,,,13,,,,,,,,,,,,,,,,,,,13,
Microsoft.Extensions.FileProviders,,,15,,,,,,,,,,,,,,,,,,,15,
Microsoft.Extensions.FileSystemGlobbing,,,16,,,,,,,,,,,,,,,,,,,14,2
Microsoft.Extensions.Hosting,,,23,,,,,,,,,,,,,,,,,,,22,1
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,,,,,,,10,
Microsoft.Extensions.Logging,,,60,,,,,,,,,,,,,,,,,,,59,1
Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,,,,,,,8,
Microsoft.Extensions.Primitives,,,64,,,,,,,,,,,,,,,,,,,64,
Microsoft.Interop,,,78,,,,,,,,,,,,,,,,,,,78,
Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,,,,,,1,
Microsoft.NET.WebAssembly.Webcil,,,7,,,,,,,,,,,,,,,,,,,7,
Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,,,,,,5,5
Microsoft.WebAssembly.Build.Tasks,,,3,,,,,,,,,,,,,,,,,,,3,
Microsoft.Win32,,4,4,,,,,,,,,,,,,,,,,,4,4,
Mono.Linker,,,163,,,,,,,,,,,,,,,,,,,163,
MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,,,
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,,,73,18
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,,,7,
SourceGenerators,,,4,,,,,,,,,,,,,,,,,,,4,
System,67,44,11872,,8,8,9,,,4,5,,33,2,,3,15,17,3,4,,9906,1966
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,,,
1 package sink source summary sink:code-injection sink:encryption-decryptor sink:encryption-encryptor sink:encryption-keyprop sink:encryption-symmetrickey sink:file-content-store sink:html-injection sink:js-injection sink:log-injection sink:sql-injection source:commandargs source:database source:environment source:file source:file-write source:local source:remote source:windows-registry summary:taint summary:value
2 Amazon.Lambda.APIGatewayEvents 6 6
3 Amazon.Lambda.Core 10 10
4 Dapper 55 42 1 55 42 1
5 ILCompiler 81 81
6 ILLink.RoslynAnalyzer 63 63
7 ILLink.Shared 32 29 3
8 ILLink.Tasks 5 5
9 Internal.IL 69 67 2
10 Internal.Pgo 9 8 1
11 Internal.TypeSystem 367 331 36
12 JsonToItemsTaskFactory 7 7
13 Microsoft.Android.Build 14 14
14 Microsoft.Apple.Build 7 7
15 Microsoft.ApplicationBlocks.Data 28 28
16 Microsoft.CSharp 24 24
17 Microsoft.Diagnostics.Tools.Pgo 13 13
18 Microsoft.EntityFrameworkCore 6 12 6 12
19 Microsoft.Extensions.Caching.Distributed 15 15
20 Microsoft.Extensions.Caching.Memory 38 37 1
21 Microsoft.Extensions.Configuration 2 89 2 86 3
22 Microsoft.Extensions.DependencyInjection 120 120
23 Microsoft.Extensions.DependencyModel 12 12
24 Microsoft.Extensions.Diagnostics.Metrics 13 13
25 Microsoft.Extensions.FileProviders 15 15
26 Microsoft.Extensions.FileSystemGlobbing 16 14 2
27 Microsoft.Extensions.Hosting 23 22 1
28 Microsoft.Extensions.Http 10 10
29 Microsoft.Extensions.Logging 60 59 1
30 Microsoft.Extensions.Options 8 8
31 Microsoft.Extensions.Primitives 64 64
32 Microsoft.Interop 78 78
33 Microsoft.NET.Build.Tasks 1 1
34 Microsoft.NET.WebAssembly.Webcil 7 7
35 Microsoft.VisualBasic 10 5 5
36 Microsoft.WebAssembly.Build.Tasks 3 3
37 Microsoft.Win32 4 4 4 4
38 Mono.Linker 163 163
39 MySql.Data.MySqlClient 48 48
40 Newtonsoft.Json 91 73 18
41 ServiceStack 194 7 27 75 92 7
42 SourceGenerators 4 4
43 System 67 30 44 11864 11872 8 8 9 4 5 33 2 3 1 15 17 3 4 9898 9906 1966
44 Windows.Security.Cryptography.Core 1 1

View File

@@ -8,7 +8,7 @@ C# framework & library support
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
System,"``System.*``, ``System``",30,11864,67,9
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",12,1547,148,
Totals,,42,13418,409,9
System,"``System.*``, ``System``",44,11872,67,9
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",54,1548,148,
Totals,,98,13427,409,9

View File

@@ -89,11 +89,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return dotnetCliInvoker.RunCommand(args);
}
public IList<string> GetListedRuntimes() => GetListed("--list-runtimes", "runtime");
public IList<string> GetListedRuntimes() => GetListed("--list-runtimes");
public IList<string> GetListedSdks() => GetListed("--list-sdks", "SDK");
public IList<string> GetListedSdks() => GetListed("--list-sdks");
private IList<string> GetListed(string args, string artifact)
private IList<string> GetListed(string args)
{
if (dotnetCliInvoker.RunCommand(args, out var artifacts))
{

View File

@@ -143,7 +143,7 @@ namespace Semmle.Extraction.CSharp.Standalone
stopwatch.Start();
using var logger = new ConsoleLogger(options.Verbosity, logThreadId: true);
logger.Log(Severity.Info, "Extracting C# in buildless mode");
logger.Log(Severity.Info, "Extracting C# with build-mode set to 'none'");
using var dependencyManager = new DependencyManager(options.SrcDir, logger);
if (!dependencyManager.NonGeneratedSourcesFiles.Any())

View File

@@ -100,8 +100,14 @@ namespace Semmle.Extraction.CSharp.Entities
/// <param name="child">The child index.</param>
/// <param name="type">A type hint.</param>
/// <returns>The new expression.</returns>
public static Expression Create(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child) =>
CreateFromNode(new ExpressionNodeInfo(cx, node, parent, child));
public static Expression Create(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child, Boolean isCompilerGenerated = false)
{
var info = new ExpressionNodeInfo(cx, node, parent, child)
{
IsCompilerGenerated = isCompilerGenerated
};
return CreateFromNode(info);
}
public static Expression CreateFromNode(ExpressionNodeInfo info) => Expressions.ImplicitCast.Create(info);

View File

@@ -97,7 +97,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.ARRAY_CREATION,
parent,
childIndex,
true,
isCompilerGenerated: true,
null);
var arrayCreation = new Expression(info);

View File

@@ -26,10 +26,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
if (operatorKind.HasValue)
{
// Convert assignment such as `a += b` into `a = a + b`.
var simpleAssignExpr = new Expression(new ExpressionInfo(Context, Type, Location, ExprKind.SIMPLE_ASSIGN, this, 2, false, null));
var simpleAssignExpr = new Expression(new ExpressionInfo(Context, Type, Location, ExprKind.SIMPLE_ASSIGN, this, 2, isCompilerGenerated: true, null));
Create(Context, Syntax.Left, simpleAssignExpr, 1);
var opexpr = new Expression(new ExpressionInfo(Context, Type, Location, operatorKind.Value, simpleAssignExpr, 0, false, null));
Create(Context, Syntax.Left, opexpr, 0);
var opexpr = new Expression(new ExpressionInfo(Context, Type, Location, operatorKind.Value, simpleAssignExpr, 0, isCompilerGenerated: true, null));
Create(Context, Syntax.Left, opexpr, 0, isCompilerGenerated: true);
Create(Context, Syntax.Right, opexpr, 1);
opexpr.OperatorCall(trapFile, Syntax);
}

View File

@@ -41,7 +41,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.CAST,
parent,
childIndex,
true,
isCompilerGenerated: true,
ValueAsString(value));
var ret = new Expression(info);

View File

@@ -6,7 +6,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class Spread : Expression
{
public Spread(Context cx, SpreadElementSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.SPREAD_ELEMENT, parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.SPREAD_ELEMENT, parent, child, isCompilerGenerated: false, null))
{
Create(cx, syntax.Expression, this, 0);
}

View File

@@ -24,7 +24,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.DEFAULT,
parent,
childIndex,
true,
isCompilerGenerated: true,
value);
return new Expression(info);

View File

@@ -11,7 +11,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
private Discard(Context cx, CSharpSyntaxNode syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, cx.GetType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.DISCARD, parent, child, false, null))
base(new ExpressionInfo(cx, cx.GetType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.DISCARD, parent, child, isCompilerGenerated: false, null))
{
}

View File

@@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
if (Kind == ExprKind.POINTER_INDIRECTION)
{
var qualifierInfo = new ExpressionNodeInfo(Context, qualifier, this, 0);
var add = new Expression(new ExpressionInfo(Context, qualifierInfo.Type, Location, ExprKind.ADD, this, 0, false, null));
var add = new Expression(new ExpressionInfo(Context, qualifierInfo.Type, Location, ExprKind.ADD, this, 0, isCompilerGenerated: false, null));
qualifierInfo.SetParent(add, 0);
CreateFromNode(qualifierInfo);
PopulateArguments(trapFile, argumentList, 1);

View File

@@ -14,13 +14,13 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
private ImplicitCast(ExpressionNodeInfo info)
: base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.CAST, info.Parent, info.Child, true, info.ExprValue))
: base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.CAST, info.Parent, info.Child, isCompilerGenerated: true, info.ExprValue))
{
Expr = Factory.Create(new ExpressionNodeInfo(Context, info.Node, this, 0));
}
private ImplicitCast(ExpressionNodeInfo info, IMethodSymbol method)
: base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue))
: base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, isCompilerGenerated: true, info.ExprValue))
{
Expr = Factory.Create(info.SetParent(this, 0));
@@ -65,7 +65,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
kind,
parent,
childIndex,
true,
isCompilerGenerated: true,
v);
var method = GetImplicitConversionMethod(type, value);
@@ -93,7 +93,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.CAST,
parent,
childIndex,
true,
isCompilerGenerated: true,
ValueAsString(value));
return new Expression(info);

View File

@@ -45,7 +45,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.ARRAY_INIT,
parent,
index,
true,
isCompilerGenerated: true,
null);
return new Expression(info);
@@ -132,7 +132,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
var addMethod = Method.Create(Context, collectionInfo.Symbol as IMethodSymbol);
var voidType = AnnotatedTypeSymbol.CreateNotAnnotated(Context.Compilation.GetSpecialType(SpecialType.System_Void));
var invocation = new Expression(new ExpressionInfo(Context, voidType, Context.CreateLocation(i.GetLocation()), ExprKind.METHOD_INVOCATION, this, child++, false, null));
var invocation = new Expression(new ExpressionInfo(Context, voidType, Context.CreateLocation(i.GetLocation()), ExprKind.METHOD_INVOCATION, this, child++, isCompilerGenerated: true, null));
if (addMethod is not null)
trapFile.expr_call(invocation, addMethod);

View File

@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case SyntaxKind.InterpolatedStringText:
// Create a string literal
var interpolatedText = (InterpolatedStringTextSyntax)c;
new Expression(new ExpressionInfo(Context, Type, Context.CreateLocation(c.GetLocation()), ExprKind.UTF16_STRING_LITERAL, this, child++, false, interpolatedText.TextToken.ValueText));
new Expression(new ExpressionInfo(Context, Type, Context.CreateLocation(c.GetLocation()), ExprKind.UTF16_STRING_LITERAL, this, child++, isCompilerGenerated: false, interpolatedText.TextToken.ValueText));
break;
default:
throw new InternalError(c, $"Unhandled interpolation kind {c.Kind()}");

View File

@@ -63,7 +63,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public static Lambda Create(ExpressionNodeInfo info, ParenthesizedLambdaExpressionSyntax node) => new Lambda(info, node);
private Lambda(ExpressionNodeInfo info, SimpleLambdaExpressionSyntax node)
: this(info.SetKind(ExprKind.LAMBDA), node.Body, Enumerators.Singleton(node.Parameter), null) { }
: this(info.SetKind(ExprKind.LAMBDA), node.Body, [node.Parameter], null) { }
public static Lambda Create(ExpressionNodeInfo info, SimpleLambdaExpressionSyntax node) => new Lambda(info, node);

View File

@@ -97,7 +97,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
kind,
parent,
childIndex,
true,
isCompilerGenerated: true,
ValueAsString(value));
return new Expression(info);
@@ -112,7 +112,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.NULL_LITERAL,
parent,
childIndex,
true,
isCompilerGenerated: true,
ValueAsString(null));
return new Expression(info);

View File

@@ -30,7 +30,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
return;
}
var objectInitializer = new Expression(new ExpressionInfo(Context, Type, Location, ExprKind.OBJECT_INIT, this, -1, false, null));
var objectInitializer = new Expression(new ExpressionInfo(Context, Type, Location, ExprKind.OBJECT_INIT, this, -1, isCompilerGenerated: false, null));
foreach (var init in Syntax.Initializers)
{
@@ -40,11 +40,11 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
var type = property.GetAnnotatedType();
var loc = Context.CreateLocation(init.GetLocation());
var assignment = new Expression(new ExpressionInfo(Context, type, loc, ExprKind.SIMPLE_ASSIGN, objectInitializer, child++, false, null));
var assignment = new Expression(new ExpressionInfo(Context, type, loc, ExprKind.SIMPLE_ASSIGN, objectInitializer, child++, isCompilerGenerated: false, null));
Create(Context, init.Expression, assignment, 0);
Property.Create(Context, property);
var access = new Expression(new ExpressionInfo(Context, type, loc, ExprKind.PROPERTY_ACCESS, assignment, 1, false, null));
var access = new Expression(new ExpressionInfo(Context, type, loc, ExprKind.PROPERTY_ACCESS, assignment, 1, isCompilerGenerated: false, null));
trapFile.expr_access(access, propEntity);
}
}

View File

@@ -59,7 +59,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.OBJECT_CREATION,
parent,
childIndex,
true,
isCompilerGenerated: true,
null));
var longTypeSymbol = constructorSymbol.Parameters[0].Type;

View File

@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class BinaryPattern : Expression
{
public BinaryPattern(Context cx, BinaryPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken, syntax), parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken, syntax), parent, child, isCompilerGenerated: false, null))
{
Pattern.Create(cx, syntax.Left, this, 0);
Pattern.Create(cx, syntax.Right, this, 1);

View File

@@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class ListPattern : Expression
{
internal ListPattern(Context cx, ListPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.LIST_PATTERN, parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.LIST_PATTERN, parent, child, isCompilerGenerated: false, null))
{
syntax.Patterns.ForEach((p, i) => Pattern.Create(cx, p, this, i));
}

View File

@@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class PositionalPattern : Expression
{
internal PositionalPattern(Context cx, PositionalPatternClauseSyntax posPc, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, isCompilerGenerated: false, null))
{
posPc.Subpatterns.ForEach((p, i) => Pattern.Create(cx, p.Pattern, this, i));
}

View File

@@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class PropertyPattern : Expression
{
internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, isCompilerGenerated: false, null))
{
child = 0;
foreach (var sub in pp.Subpatterns)
@@ -56,7 +56,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
};
private static Expression CreateSyntheticExp(Context cx, Microsoft.CodeAnalysis.Location location, IExpressionParentEntity parent, int child) =>
new Expression(new ExpressionInfo(cx, null, cx.CreateLocation(location), ExprKind.PROPERTY_PATTERN, parent, child, false, null));
new Expression(new ExpressionInfo(cx, null, cx.CreateLocation(location), ExprKind.PROPERTY_PATTERN, parent, child, isCompilerGenerated: false, null));
private static void MakeExpressions(Context cx, IExpressionParentEntity parent, SubpatternSyntax syntax, int child)
{

View File

@@ -15,7 +15,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
/// <param name="parent">The parent pattern/expression.</param>
/// <param name="child">The child index of this pattern.</param>
public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, isCompilerGenerated: false, null))
{
// Extract the type access
if (syntax.Type is TypeSyntax t)

View File

@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class RelationalPattern : Expression
{
public RelationalPattern(Context cx, RelationalPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken), parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken), parent, child, isCompilerGenerated: false, null))
{
Expression.Create(cx, syntax.Expression, this, 0);
}

View File

@@ -6,7 +6,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class SlicePattern : Expression
{
public SlicePattern(Context cx, SlicePatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.SLICE_PATTERN, parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.SLICE_PATTERN, parent, child, isCompilerGenerated: false, null))
{
if (syntax.Pattern is not null)
{

View File

@@ -6,7 +6,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class UnaryPattern : Expression
{
public UnaryPattern(Context cx, UnaryPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.NOT_PATTERN, parent, child, false, null))
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.NOT_PATTERN, parent, child, isCompilerGenerated: false, null))
{
Pattern.Create(cx, syntax.Pattern, this, 0);
}

View File

@@ -23,7 +23,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public QueryCall(Context cx, IMethodSymbol? method, SyntaxNode clause, IExpressionParentEntity parent, int child)
: base(new ExpressionInfo(cx, method?.GetAnnotatedReturnType(),
cx.CreateLocation(clause.GetLocation()),
ExprKind.METHOD_INVOCATION, parent, child, false, null))
ExprKind.METHOD_INVOCATION, parent, child, isCompilerGenerated: false, null))
{
if (method is not null)
cx.TrapWriter.Writer.expr_call(this, Method.Create(cx, method));
@@ -97,7 +97,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
Expression.Create(cx, Expr, decl, 0);
var nameLoc = cx.CreateLocation(name.GetLocation());
var access = new Expression(new ExpressionInfo(cx, type, nameLoc, ExprKind.LOCAL_VARIABLE_ACCESS, decl, 1, false, null));
var access = new Expression(new ExpressionInfo(cx, type, nameLoc, ExprKind.LOCAL_VARIABLE_ACCESS, decl, 1, isCompilerGenerated: false, null));
cx.TrapWriter.Writer.expr_access(access, LocalVariable.Create(cx, variableSymbol));
return decl;

View File

@@ -27,7 +27,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal SwitchCase(Context cx, SwitchExpressionArmSyntax arm, Switch parent, int child) :
base(new ExpressionInfo(
cx, cx.GetType(arm.Expression), cx.CreateLocation(arm.GetLocation()),
ExprKind.SWITCH_CASE, parent, child, false, null))
ExprKind.SWITCH_CASE, parent, child, isCompilerGenerated: false, null))
{
Expressions.Pattern.Create(cx, arm.Pattern, this, 0);
if (arm.WhenClause is WhenClauseSyntax when)

View File

@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
private This(IExpressionInfo info) : base(info) { }
public static This CreateImplicit(Context cx, ITypeSymbol @class, Extraction.Entities.Location loc, IExpressionParentEntity parent, int child) =>
new This(new ExpressionInfo(cx, AnnotatedTypeSymbol.CreateNotAnnotated(@class), loc, Kinds.ExprKind.THIS_ACCESS, parent, child, true, null));
new This(new ExpressionInfo(cx, AnnotatedTypeSymbol.CreateNotAnnotated(@class), loc, Kinds.ExprKind.THIS_ACCESS, parent, child, isCompilerGenerated: true, null));
public static This CreateExplicit(ExpressionNodeInfo info) => new This(info.SetKind(ExprKind.THIS_ACCESS));
}

View File

@@ -44,7 +44,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.TYPE_ACCESS,
parent,
childIndex,
true,
isCompilerGenerated: true,
null);
return new Expression(typeAccessInfo);

View File

@@ -26,7 +26,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ExprKind.TYPEOF,
parent,
childIndex,
true,
isCompilerGenerated: true,
null);
var ret = new Expression(info);

View File

@@ -15,7 +15,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public static VariableDeclaration Create(Context cx, ISymbol symbol, AnnotatedTypeSymbol? type, TypeSyntax? optionalSyntax, Extraction.Entities.Location exprLocation, bool isVar, IExpressionParentEntity parent, int child)
{
var ret = new VariableDeclaration(new ExpressionInfo(cx, type, exprLocation, ExprKind.LOCAL_VAR_DECL, parent, child, false, null));
var ret = new VariableDeclaration(new ExpressionInfo(cx, type, exprLocation, ExprKind.LOCAL_VAR_DECL, parent, child, isCompilerGenerated: false, null));
cx.Try(null, null, () =>
{
var l = LocalVariable.Create(cx, symbol);
@@ -52,7 +52,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public static Expression CreateParenthesized(Context cx, DeclarationExpressionSyntax node, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child, INamedTypeSymbol? t)
{
var type = t is null ? (AnnotatedTypeSymbol?)null : new AnnotatedTypeSymbol(t, t.NullableAnnotation);
var tuple = new Expression(new ExpressionInfo(cx, type, cx.CreateLocation(node.GetLocation()), ExprKind.TUPLE, parent, child, false, null));
var tuple = new Expression(new ExpressionInfo(cx, type, cx.CreateLocation(node.GetLocation()), ExprKind.TUPLE, parent, child, isCompilerGenerated: false, null));
cx.Try(null, null, () =>
{
@@ -68,7 +68,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public static Expression CreateParenthesized(Context cx, VarPatternSyntax varPattern, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child)
{
var tuple = new Expression(
new ExpressionInfo(cx, null, cx.CreateLocation(varPattern.GetLocation()), ExprKind.TUPLE, parent, child, false, null),
new ExpressionInfo(cx, null, cx.CreateLocation(varPattern.GetLocation()), ExprKind.TUPLE, parent, child, isCompilerGenerated: false, null),
shouldPopulate: false);
var elementTypes = new List<ITypeSymbol?>();
@@ -148,7 +148,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
Create(cx, node, node.Designation, parent, child, cx.GetTypeInfo(node).Type.DisambiguateType() as INamedTypeSymbol);
public static VariableDeclaration Create(Context cx, CSharpSyntaxNode c, AnnotatedTypeSymbol? type, IExpressionParentEntity parent, int child) =>
new VariableDeclaration(new ExpressionInfo(cx, type, cx.CreateLocation(c.FixedLocation()), ExprKind.LOCAL_VAR_DECL, parent, child, false, null));
new VariableDeclaration(new ExpressionInfo(cx, type, cx.CreateLocation(c.FixedLocation()), ExprKind.LOCAL_VAR_DECL, parent, child, isCompilerGenerated: false, null));
public static VariableDeclaration Create(Context cx, CatchDeclarationSyntax d, bool isVar, IExpressionParentEntity parent, int child)
{
@@ -179,7 +179,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
Create(cx, d.Initializer.Value, ret, 0);
// Create an access
var access = new Expression(new ExpressionInfo(cx, type, localVar.Location, ExprKind.LOCAL_VARIABLE_ACCESS, ret, 1, false, null));
var access = new Expression(new ExpressionInfo(cx, type, localVar.Location, ExprKind.LOCAL_VARIABLE_ACCESS, ret, 1, isCompilerGenerated: false, null));
cx.TrapWriter.Writer.expr_access(access, localVar);
}

View File

@@ -110,9 +110,9 @@ namespace Semmle.Extraction.CSharp.Entities
string? constValue, ref int child)
{
var type = Symbol.GetAnnotatedType();
var simpleAssignExpr = new Expression(new ExpressionInfo(Context, type, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, constValue));
var simpleAssignExpr = new Expression(new ExpressionInfo(Context, type, loc, ExprKind.SIMPLE_ASSIGN, this, child++, isCompilerGenerated: true, constValue));
Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer, simpleAssignExpr, 0));
var access = new Expression(new ExpressionInfo(Context, type, Location, ExprKind.FIELD_ACCESS, simpleAssignExpr, 1, false, constValue));
var access = new Expression(new ExpressionInfo(Context, type, Location, ExprKind.FIELD_ACCESS, simpleAssignExpr, 1, isCompilerGenerated: true, constValue));
trapFile.expr_access(access, this);
return access;
}

View File

@@ -86,9 +86,9 @@ namespace Semmle.Extraction.CSharp.Entities
{
var loc = Context.CreateLocation(initializer!.GetLocation());
var annotatedType = AnnotatedTypeSymbol.CreateNotAnnotated(Symbol.Type);
var simpleAssignExpr = new Expression(new ExpressionInfo(Context, annotatedType, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, null));
var simpleAssignExpr = new Expression(new ExpressionInfo(Context, annotatedType, loc, ExprKind.SIMPLE_ASSIGN, this, child++, isCompilerGenerated: true, null));
Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer.Value, simpleAssignExpr, 0));
var access = new Expression(new ExpressionInfo(Context, annotatedType, Location, ExprKind.PROPERTY_ACCESS, simpleAssignExpr, 1, false, null));
var access = new Expression(new ExpressionInfo(Context, annotatedType, Location, ExprKind.PROPERTY_ACCESS, simpleAssignExpr, 1, isCompilerGenerated: true, null));
trapFile.expr_access(access, this);
if (!Symbol.IsStatic)
{

View File

@@ -189,7 +189,7 @@ namespace Semmle.Extraction.CSharp
// compilation.Clone() is used to allow symbols to be garbage collected.
using var trapWriter = transformedSourcePath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile);
upToDate = FileIsUpToDate(sourcePath, trapWriter.TrapFile);
var currentTaskId = IncrementTaskCount();
ReportProgressTaskStarted(currentTaskId, sourcePath);

View File

@@ -35,15 +35,7 @@ namespace Semmle.Extraction.CSharp
public static Options CreateWithEnvironment(string[] arguments)
{
var options = new Options();
var extractionOptions = Environment.GetEnvironmentVariable("LGTM_INDEX_EXTRACTOR");
var argsList = new List<string>(arguments);
if (!string.IsNullOrEmpty(extractionOptions))
{
argsList.AddRange(extractionOptions.Split(' '));
}
options.ParseArguments(argsList);
return options;
}

View File

@@ -12,11 +12,6 @@ namespace Semmle.Extraction.Tests
private CSharp.Options? options;
private CSharp.Standalone.Options? standaloneOptions;
public OptionsTests()
{
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "");
}
[Fact]
public void DefaultOptions()
{
@@ -28,7 +23,6 @@ namespace Semmle.Extraction.Tests
Assert.True(options.Threads >= 1);
Assert.Equal(Verbosity.Info, options.LegacyVerbosity);
Assert.False(options.Console);
Assert.False(options.Fast);
Assert.Equal(TrapWriter.CompressionMode.Brotli, options.TrapCompression);
}
@@ -165,14 +159,6 @@ namespace Semmle.Extraction.Tests
Assert.True(standaloneOptions.Help);
}
[Fact]
public void Fast()
{
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "--fast");
options = CSharp.Options.CreateWithEnvironment(Array.Empty<string>());
Assert.True(options.Fast);
}
[Fact]
public void ArchiveArguments()
{

View File

@@ -60,11 +60,6 @@ namespace Semmle.Extraction
/// </summary>
public bool Cache { get; private set; } = true;
/// <summary>
/// Whether "fast extraction mode" has been enabled.
/// </summary>
public bool Fast { get; private set; } = false;
/// <summary>
/// Whether extraction is done using `codeql test run`.
/// </summary>
@@ -115,9 +110,6 @@ namespace Semmle.Extraction
case "cache":
Cache = value;
return true;
case "fast":
Fast = value;
return true;
case "qltest":
QlTest = value;
return true;

View File

@@ -1,54 +0,0 @@
using Xunit;
using Semmle.Util;
using Assert = Xunit.Assert;
namespace SemmleTests.Semmle.Util
{
public class ActionMapTests
{
[Fact]
public void TestAddthenOnAdd()
{
var am = new ActionMap<int, int>();
am.Add(1, 2);
int value = 0;
am.OnAdd(1, x => value = x);
Assert.Equal(2, value);
}
[Fact]
public void TestOnAddthenAdd()
{
var am = new ActionMap<int, int>();
int value = 0;
am.OnAdd(1, x => value = x);
am.Add(1, 2);
Assert.Equal(2, value);
}
[Fact]
public void TestNotAdded()
{
var am = new ActionMap<int, int>();
int value = 0;
am.OnAdd(1, x => value = x);
am.Add(2, 2);
Assert.Equal(0, value);
}
[Fact]
public void TestMultipleActions()
{
var am = new ActionMap<int, int>();
int value1 = 0, value2 = 0;
am.OnAdd(1, x => value1 = x);
am.OnAdd(1, x => value2 = x);
am.Add(1, 2);
Assert.Equal(2, value1);
Assert.Equal(2, value2);
}
}
}

View File

@@ -1,78 +0,0 @@
using Xunit;
using System;
using Semmle.Util;
using Assert = Xunit.Assert;
namespace SemmleTests
{
public class TextTest
{
//#################### PRIVATE VARIABLES ####################
#region
/// <summary>
/// A shorter way of writing Environment.NewLine (it gets used repeatedly).
/// </summary>
private static readonly string NL = Environment.NewLine;
#endregion
//#################### TEST METHODS ####################
#region
[Fact]
public void GetAllTest()
{
var input = new string[]
{
"Said once a young coder from Crewe,",
"'I like to write tests, so I do!",
"They help me confirm",
"That I don't need to squirm -",
"My code might look nice, but works too!'"
};
var text = new Text(input);
Assert.Equal(string.Join(NL, input) + NL, text.GetAll());
}
[Fact]
public void GetPortionTest()
{
var input = new string[]
{
"There once was a jolly young tester",
"Who couldn't leave software to fester -",
"He'd prod and he'd poke",
"Until something bad broke,",
"And then he'd find someone to pester."
};
var text = new Text(input);
// A single-line range (to test the special case).
Assert.Equal("jolly" + NL, text.GetPortion(0, 17, 0, 22));
// A two-line range.
Assert.Equal("prod and he'd poke" + NL + "Until" + NL, text.GetPortion(2, 5, 3, 5));
// A three-line range (to test that the middle line is included in full).
Assert.Equal("poke" + NL + "Until something bad broke," + NL + "And then" + NL, text.GetPortion(2, 19, 4, 8));
// An invalid but recoverable range (to test that a best effort is made rather than crashing).
Assert.Equal(NL + "Who couldn't leave software to fester -" + NL, text.GetPortion(0, int.MaxValue, 1, int.MaxValue));
// Some quite definitely dodgy ranges (to test that exceptions are thrown).
Assert.Throws<Exception>(() => text.GetPortion(-1, 0, 0, 0));
Assert.Throws<Exception>(() => text.GetPortion(0, -1, 0, 0));
Assert.Throws<Exception>(() => text.GetPortion(0, 0, -1, 0));
Assert.Throws<Exception>(() => text.GetPortion(0, 0, 0, -1));
Assert.Throws<Exception>(() => text.GetPortion(3, 5, 2, 5));
Assert.Throws<Exception>(() => text.GetPortion(2, 5, int.MaxValue, 5));
}
#endregion
}
}

View File

@@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
namespace Semmle.Util
{
/// <summary>
/// A dictionary which performs an action when items are added to the dictionary.
/// The order in which keys and actions are added does not matter.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class ActionMap<TKey, TValue> where TKey : notnull
{
public void Add(TKey key, TValue value)
{
if (actions.TryGetValue(key, out var a))
a(value);
values[key] = value;
}
public void OnAdd(TKey key, Action<TValue> action)
{
if (actions.TryGetValue(key, out var a))
{
actions[key] = a + action;
}
else
{
actions.Add(key, action);
}
if (values.TryGetValue(key, out var val))
{
action(val);
}
}
// Action associated with each key.
private readonly Dictionary<TKey, Action<TValue>> actions = new Dictionary<TKey, Action<TValue>>();
// Values associated with each key.
private readonly Dictionary<TKey, TValue> values = new Dictionary<TKey, TValue>();
}
}

View File

@@ -1,19 +0,0 @@
using System.Collections.Generic;
namespace Semmle.Util
{
public static class Enumerators
{
/// <summary>
/// Create an enumerable with a single element.
/// </summary>
///
/// <typeparam name="T">The type of the enumerable/element.</typeparam>
/// <param name="t">The element.</param>
/// <returns>An enumerable containing a single element.</returns>
public static IEnumerable<T> Singleton<T>(T t)
{
yield return t;
}
}
}

View File

@@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Semmle.Util
{
/// <summary>
/// Utility to temporarily rename a set of files.
/// </summary>
public sealed class FileRenamer : IDisposable
{
private readonly string[] files;
private const string suffix = ".codeqlhidden";
public FileRenamer(IEnumerable<FileInfo> oldFiles)
{
files = oldFiles.Select(f => f.FullName).ToArray();
foreach (var file in files)
{
File.Move(file, file + suffix);
}
}
public void Dispose()
{
foreach (var file in files)
{
File.Move(file + suffix, file);
}
}
}
}

View File

@@ -1,165 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Semmle.Util
{
/// <summary>
/// A dictionary from strings to elements of type T.
/// </summary>
///
/// <remarks>
/// This data structure is able to locate items based on an "approximate match"
/// of the key. This is used for example when attempting to identify two terms
/// in different trap files which are similar but not identical.
///
/// The algorithm locates the closest match to a string based on a "distance function".
///
/// Whilst many distance functions are possible, a bespoke algorithm is used here,
/// for efficiency and suitability for the domain.
///
/// The distance is defined as the Hamming Distance of the numbers in the string.
/// Each string is split into the base "form" (stripped of numbers) and a vector of
/// numbers. (Numbers are non-negative integers in this context).
///
/// Strings with a different "form" are considered different and have a distance
/// of infinity.
///
/// This distance function is reflexive, symmetric and obeys the triangle inequality.
///
/// E.g. foo(bar,1,2) has form "foo(bar,,)" and integers {1,2}
///
/// distance(foo(bar,1,2), foo(bar,1,2)) = 0
/// distance(foo(bar,1,2), foo(bar,1,3)) = 1
/// distance(foo(bar,2,1), foo(bar,1,2)) = 2
/// distance(foo(bar,1,2), foo(baz,1,2)) = infinity
/// </remarks>
///
/// <typeparam name="T">The value type.</typeparam>
public class FuzzyDictionary<T> where T : class
{
// All data items indexed by the "base string" (stripped of numbers)
private readonly Dictionary<string, List<KeyValuePair<string, T>>> index = new Dictionary<string, List<KeyValuePair<string, T>>>();
/// <summary>
/// Stores a new KeyValuePair in the data structure.
/// </summary>
/// <param name="k">The key.</param>
/// <param name="v">The value.</param>
public void Add(string k, T v)
{
var kv = new KeyValuePair<string, T>(k, v);
var root = StripDigits(k);
index.AddAnother(root, kv);
}
/// <summary>
/// Computes the Hamming Distance between two sequences of the same length.
/// </summary>
/// <param name="v1">Vector 1</param>
/// <param name="v2">Vector 2</param>
/// <returns>The Hamming Distance.</returns>
private static int HammingDistance<TElement>(IEnumerable<TElement> v1, IEnumerable<TElement> v2) where TElement : notnull
{
return v1.Zip(v2, (x, y) => x.Equals(y) ? 0 : 1).Sum();
}
/// <summary>
/// Locates the value with the smallest Hamming Distance from the query.
/// </summary>
/// <param name="query">The query string.</param>
/// <param name="distance">The distance between the query string and the stored string.</param>
/// <returns>The best match, or null (default).</returns>
public T? FindMatch(string query, out int distance)
{
var root = StripDigits(query);
if (!index.TryGetValue(root, out var list))
{
distance = 0;
return default(T);
}
return BestMatch(query, list, (a, b) => HammingDistance(ExtractIntegers(a), ExtractIntegers(b)), out distance);
}
/// <summary>
/// Returns the best match (with the smallest distance) for a query.
/// </summary>
/// <param name="query">The query string.</param>
/// <param name="candidates">The list of candidate matches.</param>
/// <param name="distance">The distance function.</param>
/// <param name="bestDistance">The distance between the query and the stored string.</param>
/// <returns>The stored value.</returns>
private static T? BestMatch(string query, IEnumerable<KeyValuePair<string, T>> candidates, Func<string, string, int> distance, out int bestDistance)
{
var bestMatch = default(T);
bestDistance = 0;
var first = true;
foreach (var candidate in candidates)
{
var d = distance(query, candidate.Key);
if (d == 0)
return candidate.Value;
if (first || d < bestDistance)
{
bestDistance = d;
bestMatch = candidate.Value;
first = false;
}
}
return bestMatch;
}
/// <summary>
/// Removes all digits from a string.
/// </summary>
/// <param name="input">The input string.</param>
/// <returns>String with digits removed.</returns>
private static string StripDigits(string input)
{
var result = new StringBuilder();
foreach (var c in input.Where(c => !char.IsDigit(c)))
result.Append(c);
return result.ToString();
}
/// <summary>
/// Extracts and enumerates all non-negative integers in a string.
/// </summary>
/// <param name="input">The string to enumerate.</param>
/// <returns>The sequence of integers.</returns>
private static IEnumerable<int> ExtractIntegers(string input)
{
var inNumber = false;
var value = 0;
foreach (var c in input)
{
if (char.IsDigit(c))
{
if (inNumber)
{
value = value * 10 + (c - '0');
}
else
{
inNumber = true;
value = c - '0';
}
}
else
{
if (inNumber)
{
yield return value;
inNumber = false;
}
}
}
}
}
}

View File

@@ -1,18 +0,0 @@
namespace Semmle.Util
{
/// <summary>
/// An instance of this class maintains a shared reference to an object.
/// This makes it possible for several different parts of the code to
/// share access to an object that can change (that is, they all want
/// to refer to the same object, but the object to which they jointly
/// refer may vary over time).
/// </summary>
/// <typeparam name="T">The type of the shared object.</typeparam>
public sealed class SharedReference<T> where T : class
{
/// <summary>
/// The shared object to which different parts of the code want to refer.
/// </summary>
public T? Obj { get; set; }
}
}

View File

@@ -1,41 +0,0 @@
using System.Collections.Generic;
using System.Linq;
namespace Semmle.Util
{
public static class StringExtensions
{
public static (string, string) Split(this string self, int index0)
{
var split = self.Split(new[] { index0 });
return (split[0], split[1]);
}
public static (string, string, string) Split(this string self, int index0, int index1)
{
var split = self.Split(new[] { index0, index1 });
return (split[0], split[1], split[2]);
}
public static (string, string, string, string) Split(this string self, int index0, int index1, int index2)
{
var split = self.Split(new[] { index0, index1, index2 });
return (split[0], split[1], split[2], split[3]);
}
private static List<string> Split(this string self, params int[] indices)
{
var ret = new List<string>();
var previousIndex = 0;
foreach (var index in indices.OrderBy(i => i))
{
ret.Add(self.Substring(previousIndex, index - previousIndex));
previousIndex = index;
}
ret.Add(self.Substring(previousIndex));
return ret;
}
}
}

View File

@@ -1,105 +0,0 @@
using System;
using System.IO;
namespace Semmle.Util
{
/// <summary>
/// An instance of this class represents a piece of text, e.g. the text of a C# source file.
/// </summary>
public sealed class Text
{
//#################### PRIVATE VARIABLES ####################
#region
/// <summary>
/// The text, stored line-by-line.
/// </summary>
private readonly string[] lines;
#endregion
//#################### CONSTRUCTORS ####################
#region
/// <summary>
/// Constructs a text object from an array of lines.
/// </summary>
/// <param name="lines">The lines of text.</param>
public Text(string[] lines)
{
this.lines = lines;
}
#endregion
//#################### PUBLIC METHODS ####################
#region
/// <summary>
/// Gets the whole text.
/// </summary>
/// <returns>The whole text.</returns>
public string GetAll()
{
using var sw = new StringWriter();
foreach (var s in lines)
{
sw.WriteLine(s);
}
return sw.ToString();
}
/// <summary>
/// Gets the portion of text that lies in the specified location range.
/// </summary>
/// <param name="startRow">The row at which the portion starts.</param>
/// <param name="startColumn">The column in the start row at which the portion starts.</param>
/// <param name="endRow">The row at which the portion ends.</param>
/// <param name="endColumn">The column in the end row at which the portion ends.</param>
/// <returns>The portion of text that lies in the specified location range.</returns>
public string GetPortion(int startRow, int startColumn, int endRow, int endColumn)
{
// Perform some basic validation on the range bounds.
if (startRow < 0 || endRow < 0 || startColumn < 0 || endColumn < 0 || endRow >= lines.Length || startRow > endRow)
{
throw new Exception
(
string.Format("Bad range ({0},{1}):({2},{3}) in a piece of text with {4} lines", startRow, startColumn, endRow, endColumn, lines.Length)
);
}
using var sw = new StringWriter();
string line;
for (var i = startRow; i <= endRow; ++i)
{
if (i == startRow && i == endRow)
{
// This is a single-line range, so take the bit between "startColumn" and "endColumn".
line = startColumn <= lines[i].Length ? lines[i].Substring(startColumn, endColumn - startColumn) : "";
}
else if (i == startRow)
{
// This is the first line of a multi-line range, so take the bit from "startColumn" onwards.
line = startColumn <= lines[i].Length ? lines[i].Substring(startColumn) : "";
}
else if (i == endRow)
{
// This is the last line of a multi-line range, so take the bit up to "endColumn".
line = endColumn <= lines[i].Length ? lines[i].Substring(0, endColumn) : lines[i];
}
else
{
// This is a line in the middle of a multi-line range, so take the whole line.
line = lines[i];
}
sw.WriteLine(line);
}
return sw.ToString();
}
#endregion
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
@@ -179,64 +178,4 @@ namespace Semmle.Util
this.PlaintextMessage = plaintextMessage;
}
}
/// <summary>
/// Provides the ability to write diagnostic messages to some output.
/// </summary>
public interface IDiagnosticsWriter
{
/// <summary>
/// Adds <paramref name="message" /> as a new diagnostics entry.
/// </summary>
/// <param name="message">The diagnostics entry to add.</param>
void AddEntry(DiagnosticMessage message);
}
/// <summary>
/// A wrapper around an underlying <see cref="StreamWriter" /> which allows
/// <see cref="DiagnosticMessage" /> objects to be serialized to it.
/// </summary>
public sealed class DiagnosticsStream : IDiagnosticsWriter, IDisposable
{
private readonly JsonSerializer serializer;
private readonly StreamWriter writer;
/// <summary>
/// Initialises a new <see cref="DiagnosticsStream" /> for a file at <paramref name="path" />.
/// </summary>
/// <param name="path">The path to the file that should be created.</param>
public DiagnosticsStream(string path)
{
this.writer = File.CreateText(path);
var contractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
};
serializer = new JsonSerializer
{
ContractResolver = contractResolver,
NullValueHandling = NullValueHandling.Ignore
};
}
/// <summary>
/// Adds <paramref name="message" /> as a new diagnostics entry.
/// </summary>
/// <param name="message">The diagnostics entry to add.</param>
public void AddEntry(DiagnosticMessage message)
{
serializer.Serialize(writer, message);
writer.Flush();
}
/// <summary>
/// Releases all resources used by the <see cref="DiagnosticsStream" /> object.
/// </summary>
public void Dispose()
{
writer.Dispose();
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Semmle.Util
{
/// <summary>
/// A wrapper around an underlying <see cref="StreamWriter" /> which allows
/// <see cref="DiagnosticMessage" /> objects to be serialized to it.
/// </summary>
public sealed class DiagnosticsStream : IDiagnosticsWriter
{
private readonly JsonSerializer serializer;
private readonly StreamWriter writer;
/// <summary>
/// Initialises a new <see cref="DiagnosticsStream" /> for a file at <paramref name="path" />.
/// </summary>
/// <param name="path">The path to the file that should be created.</param>
public DiagnosticsStream(string path)
{
this.writer = File.CreateText(path);
var contractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
};
serializer = new JsonSerializer
{
ContractResolver = contractResolver,
NullValueHandling = NullValueHandling.Ignore
};
}
/// <summary>
/// Adds <paramref name="message" /> as a new diagnostics entry.
/// </summary>
/// <param name="message">The diagnostics entry to add.</param>
public void AddEntry(DiagnosticMessage message)
{
serializer.Serialize(writer, message);
writer.Flush();
}
/// <summary>
/// Releases all resources used by the <see cref="DiagnosticsStream" /> object.
/// </summary>
public void Dispose()
{
writer.Dispose();
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
namespace Semmle.Util
{
/// <summary>
/// Provides the ability to write diagnostic messages to some output.
/// </summary>
public interface IDiagnosticsWriter : IDisposable
{
/// <summary>
/// Adds <paramref name="message" /> as a new diagnostics entry.
/// </summary>
/// <param name="message">The diagnostics entry to add.</param>
void AddEntry(DiagnosticMessage message);
}
}

View File

@@ -1,57 +0,0 @@
using System.Collections.Generic;
namespace Semmle.Util
{
/// <summary>
/// A worklist of items, providing the operations of adding an item, checking
/// whether there are new items and iterating a chunk of unprocessed items.
/// Any one item will only be accepted into the worklist once.
/// </summary>
public class Worklist<T>
{
private readonly HashSet<T> internalSet = new HashSet<T>();
private LinkedList<T> internalList = new LinkedList<T>();
private bool hasNewElements = false;
/// <summary>
/// Gets a value indicating whether this instance has had any new elements added
/// since the last time <c>GetUnprocessedElements()</c> was called.
/// </summary>
/// <value>
/// <c>true</c> if this instance has new elements; otherwise, <c>false</c>.
/// </value>
public bool HasNewElements => hasNewElements;
/// <summary>
/// Add the specified element to the worklist.
/// </summary>
/// <param name='element'>
/// If set to <c>true</c> element.
/// </param>
public bool Add(T element)
{
if (internalSet.Contains(element))
return false;
internalSet.Add(element);
internalList.AddLast(element);
hasNewElements = true;
return true;
}
/// <summary>
/// Gets the unprocessed elements that have been accumulated since the last time
/// this method was called. If <c>HasNewElements == true</c>, the resulting list
/// will be non-empty.
/// </summary>
/// <returns>
/// The unprocessed elements.
/// </returns>
public LinkedList<T> GetUnprocessedElements()
{
var result = internalList;
internalList = new LinkedList<T>();
hasNewElements = false;
return result;
}
}
}

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.7.13
version: 1.7.14-dev
groups:
- csharp
- solorigate

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.7.13
version: 1.7.14-dev
groups:
- csharp
- solorigate

View File

@@ -19,3 +19,12 @@ extensions:
- ["System.Diagnostics", "TraceListenerCollection", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
- ["System.Diagnostics", "TraceListenerCollection", False, "get_Item", "(System.String)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
- ["System.Diagnostics", "TraceListenerCollection", False, "set_Item", "(System.Int32,System.Diagnostics.TraceListener)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
- addsTo:
pack: codeql/csharp-all
extensible: neutralModel
data:
- ["System.Diagnostics", "ProcessStartInfo", "set_Arguments", "(System.String)", "summary", "manual"]
- ["System.Diagnostics", "ProcessStartInfo", "set_FileName", "(System.String)", "summary", "manual"]
- ["System.Diagnostics", "ProcessStartInfo", "set_UserName", "(System.String)", "summary", "manual"]
- ["System.Diagnostics", "ProcessStartInfo", "set_Verb", "(System.String)", "summary", "manual"]
- ["System.Diagnostics", "ProcessStartInfo", "set_WorkingDirectory", "(System.String)", "summary", "manual"]

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 0.9.0
version: 0.9.1-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp
@@ -13,6 +13,7 @@ dependencies:
codeql/threat-models: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}
codeql/xml: ${workspace}
dataExtensions:
- ext/*.model.yml
- ext/generated/*.model.yml

View File

@@ -32,7 +32,10 @@ private predicate shouldPrint(Element e, Location l) {
}
private predicate isImplicitExpression(ControlFlowElement element) {
element.(Expr).isImplicit() and not exists(element.getAChild())
element.(Expr).isImplicit() and
not element instanceof CastExpr and
not element.(OperatorCall).getTarget() instanceof ImplicitConversionOperator and
not element instanceof ElementInitializer
}
private predicate isFilteredCompilerGenerated(Declaration d) {
@@ -291,18 +294,6 @@ class ControlFlowElementNode extends ElementNode {
controlFlowElement = element and
// Removing implicit expressions
not isImplicitExpression(element) and
// Removing extra nodes that are generated for an `AssignOperation`
not exists(AssignOperation ao |
ao.hasExpandedAssignment() and
(
ao.getExpandedAssignment() = controlFlowElement or
ao.getExpandedAssignment().getRValue() = controlFlowElement or
ao.getExpandedAssignment().getRValue().(BinaryOperation).getLeftOperand() =
controlFlowElement.getParent*() or
ao.getExpandedAssignment().getRValue().(OperatorCall).getChild(0) =
controlFlowElement.getParent*()
)
) and
not isNotNeeded(element.getParent+()) and
// LambdaExpr is both a Callable and a ControlFlowElement,
// print it with the more specific CallableNode
@@ -429,7 +420,7 @@ final class DeclarationWithAccessorsNode extends ElementNode {
result.(ParametersNode).getParameterizable() = declaration
or
childIndex = 2 and
result.(ElementNode).getElement() = declaration.(Property).getInitializer().getParent()
result.(ElementNode).getElement() = declaration.(Property).getInitializer()
or
result.(ElementNode).getElement() =
rank[childIndex - 2](Element a, string file, int line, int column, string name |
@@ -462,12 +453,7 @@ final class FieldNode extends ElementNode {
result.(AttributesNode).getAttributable() = field
or
childIndex = 1 and
field.hasInitializer() and
(
if field.getDeclaringType() instanceof Enum
then result.(ElementNode).getElement() = field.getInitializer()
else result.(ElementNode).getElement() = field.getInitializer().getParent()
)
result.(ElementNode).getElement() = field.getInitializer()
}
}

View File

@@ -408,7 +408,7 @@ class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent
* }
* ```
*/
override Expr getInitializer() { result = this.getChildExpr(0).getChildExpr(0) }
final override Expr getInitializer() { result = this.getChildExpr(0).getChildExpr(0) }
/**
* Holds if this field has an initial value. For example, the initial
@@ -515,6 +515,4 @@ class EnumConstant extends MemberConstant {
* ```
*/
predicate hasExplicitValue() { exists(this.getInitializer()) }
override Expr getInitializer() { result = this.getChildExpr(0) }
}

View File

@@ -3,305 +3,67 @@
*/
import semmle.files.FileSystem
private import codeql.xml.Xml
private class TXmlLocatable =
@xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters;
private module Input implements InputSig<File, Location> {
class XmlLocatableBase = @xmllocatable or @xmlnamespaceable;
/** An XML element that has a location. */
class XmlLocatable extends @xmllocatable, TXmlLocatable {
/** Gets the source location for this element. */
Location getLocation() { xmllocations(this, result) }
predicate xmllocations_(XmlLocatableBase e, Location loc) { xmllocations(e, loc) }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
class XmlParentBase = @xmlparent;
class XmlNamespaceableBase = @xmlnamespaceable;
class XmlElementBase = @xmlelement;
class XmlFileBase = File;
predicate xmlEncoding_(XmlFileBase f, string enc) { xmlEncoding(f, enc) }
class XmlDtdBase = @xmldtd;
predicate xmlDTDs_(XmlDtdBase e, string root, string publicId, string systemId, XmlFileBase file) {
xmlDTDs(e, root, publicId, systemId, file)
}
predicate xmlElements_(
XmlElementBase e, string name, XmlParentBase parent, int idx, XmlFileBase file
) {
exists(File f, Location l | l = this.getLocation() |
locations_default(l, f, startline, startcolumn, endline, endcolumn) and
filepath = f.getAbsolutePath()
)
xmlElements(e, name, parent, idx, file)
}
/** Gets a textual representation of this element. */
string toString() { none() } // overridden in subclasses
}
class XmlAttributeBase = @xmlattribute;
/**
* An `XmlParent` is either an `XmlElement` or an `XmlFile`,
* both of which can contain other elements.
*/
class XmlParent extends @xmlparent {
XmlParent() {
// explicitly restrict `this` to be either an `XmlElement` or an `XmlFile`;
// the type `@xmlparent` currently also includes non-XML files
this instanceof @xmlelement or xmlEncoding(this, _)
predicate xmlAttrs_(
XmlAttributeBase e, XmlElementBase elementid, string name, string value, int idx,
XmlFileBase file
) {
xmlAttrs(e, elementid, name, value, idx, file)
}
/**
* Gets a printable representation of this XML parent.
* (Intended to be overridden in subclasses.)
*/
string getName() { none() } // overridden in subclasses
class XmlNamespaceBase = @xmlnamespace;
/** Gets the file to which this XML parent belongs. */
XmlFile getFile() { result = this or xmlElements(this, _, _, _, result) }
/** Gets the child element at a specified index of this XML parent. */
XmlElement getChild(int index) { xmlElements(result, _, this, index, _) }
/** Gets a child element of this XML parent. */
XmlElement getAChild() { xmlElements(result, _, this, _, _) }
/** Gets a child element of this XML parent with the given `name`. */
XmlElement getAChild(string name) { xmlElements(result, _, this, _, _) and result.hasName(name) }
/** Gets a comment that is a child of this XML parent. */
XmlComment getAComment() { xmlComments(result, _, this, _) }
/** Gets a character sequence that is a child of this XML parent. */
XmlCharacters getACharactersSet() { xmlChars(result, _, this, _, _, _) }
/** Gets the depth in the tree. (Overridden in XmlElement.) */
int getDepth() { result = 0 }
/** Gets the number of child XML elements of this XML parent. */
int getNumberOfChildren() { result = count(XmlElement e | xmlElements(e, _, this, _, _)) }
/** Gets the number of places in the body of this XML parent where text occurs. */
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
/**
* Gets the result of appending all the character sequences of this XML parent from
* left to right, separated by a space.
*/
string allCharactersString() {
result =
concat(string chars, int pos | xmlChars(_, chars, this, pos, _, _) | chars, " " order by pos)
predicate xmlNs_(XmlNamespaceBase e, string prefixName, string uri, XmlFileBase file) {
xmlNs(e, prefixName, uri, file)
}
/** Gets the text value contained in this XML parent. */
string getTextValue() { result = this.allCharactersString() }
predicate xmlHasNs_(XmlNamespaceableBase e, XmlNamespaceBase ns, XmlFileBase file) {
xmlHasNs(e, ns, file)
}
/** Gets a printable representation of this XML parent. */
string toString() { result = this.getName() }
}
class XmlCommentBase = @xmlcomment;
/** An XML file. */
class XmlFile extends XmlParent, File {
XmlFile() { xmlEncoding(this, _) }
predicate xmlComments_(XmlCommentBase e, string text, XmlParentBase parent, XmlFileBase file) {
xmlComments(e, text, parent, file)
}
/** Gets a printable representation of this XML file. */
override string toString() { result = this.getName() }
class XmlCharactersBase = @xmlcharacters;
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }
/** Gets the XML file itself. */
override XmlFile getFile() { result = this }
/** Gets a top-most element in an XML file. */
XmlElement getARootElement() { result = this.getAChild() }
/** Gets a DTD associated with this XML file. */
XmlDtd getADtd() { xmlDTDs(result, _, _, _, this) }
}
/**
* An XML document type definition (DTD).
*
* Example:
*
* ```
* <!ELEMENT person (firstName, lastName?)>
* <!ELEMENT firstName (#PCDATA)>
* <!ELEMENT lastName (#PCDATA)>
* ```
*/
class XmlDtd extends XmlLocatable, @xmldtd {
/** Gets the name of the root element of this DTD. */
string getRoot() { xmlDTDs(this, result, _, _, _) }
/** Gets the public ID of this DTD. */
string getPublicId() { xmlDTDs(this, _, result, _, _) }
/** Gets the system ID of this DTD. */
string getSystemId() { xmlDTDs(this, _, _, result, _) }
/** Holds if this DTD is public. */
predicate isPublic() { not xmlDTDs(this, _, "", _, _) }
/** Gets the parent of this DTD. */
XmlParent getParent() { xmlDTDs(this, _, _, _, result) }
override string toString() {
this.isPublic() and
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
or
not this.isPublic() and
result = this.getRoot() + " SYSTEM '" + this.getSystemId() + "'"
predicate xmlChars_(
XmlCharactersBase e, string text, XmlParentBase parent, int idx, int isCDATA, XmlFileBase file
) {
xmlChars(e, text, parent, idx, isCDATA, file)
}
}
/**
* An XML element in an XML file.
*
* Example:
*
* ```
* <manifest xmlns:android="http://schemas.android.com/apk/res/android"
* package="com.example.exampleapp" android:versionCode="1">
* </manifest>
* ```
*/
class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
/** Holds if this XML element has the given `name`. */
predicate hasName(string name) { name = this.getName() }
/** Gets the name of this XML element. */
override string getName() { xmlElements(this, result, _, _, _) }
/** Gets the XML file in which this XML element occurs. */
override XmlFile getFile() { xmlElements(this, _, _, _, result) }
/** Gets the parent of this XML element. */
XmlParent getParent() { xmlElements(this, _, result, _, _) }
/** Gets the index of this XML element among its parent's children. */
int getIndex() { xmlElements(this, _, _, result, _) }
/** Holds if this XML element has a namespace. */
predicate hasNamespace() { xmlHasNs(this, _, _) }
/** Gets the namespace of this XML element, if any. */
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
/** Gets the index of this XML element among its parent's children. */
int getElementPositionIndex() { xmlElements(this, _, _, result, _) }
/** Gets the depth of this element within the XML file tree structure. */
override int getDepth() { result = this.getParent().getDepth() + 1 }
/** Gets an XML attribute of this XML element. */
XmlAttribute getAnAttribute() { result.getElement() = this }
/** Gets the attribute with the specified `name`, if any. */
XmlAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
/** Holds if this XML element has an attribute with the specified `name`. */
predicate hasAttribute(string name) { exists(this.getAttribute(name)) }
/** Gets the value of the attribute with the specified `name`, if any. */
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
/** Gets a printable representation of this XML element. */
override string toString() { result = this.getName() }
}
/**
* An attribute that occurs inside an XML element.
*
* Examples:
*
* ```
* package="com.example.exampleapp"
* android:versionCode="1"
* ```
*/
class XmlAttribute extends @xmlattribute, XmlLocatable {
/** Gets the name of this attribute. */
string getName() { xmlAttrs(this, _, result, _, _, _) }
/** Gets the XML element to which this attribute belongs. */
XmlElement getElement() { xmlAttrs(this, result, _, _, _, _) }
/** Holds if this attribute has a namespace. */
predicate hasNamespace() { xmlHasNs(this, _, _) }
/** Gets the namespace of this attribute, if any. */
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
/** Gets the value of this attribute. */
string getValue() { xmlAttrs(this, _, _, result, _, _) }
/** Gets a printable representation of this XML attribute. */
override string toString() { result = this.getName() + "=" + this.getValue() }
}
/**
* A namespace used in an XML file.
*
* Example:
*
* ```
* xmlns:android="http://schemas.android.com/apk/res/android"
* ```
*/
class XmlNamespace extends XmlLocatable, @xmlnamespace {
/** Gets the prefix of this namespace. */
string getPrefix() { xmlNs(this, result, _, _) }
/** Gets the URI of this namespace. */
string getUri() { xmlNs(this, _, result, _) }
/** Holds if this namespace has no prefix. */
predicate isDefault() { this.getPrefix() = "" }
override string toString() {
this.isDefault() and result = this.getUri()
or
not this.isDefault() and result = this.getPrefix() + ":" + this.getUri()
}
}
/**
* A comment in an XML file.
*
* Example:
*
* ```
* <!-- This is a comment. -->
* ```
*/
class XmlComment extends @xmlcomment, XmlLocatable {
/** Gets the text content of this XML comment. */
string getText() { xmlComments(this, result, _, _) }
/** Gets the parent of this XML comment. */
XmlParent getParent() { xmlComments(this, _, result, _) }
/** Gets a printable representation of this XML comment. */
override string toString() { result = this.getText() }
}
/**
* A sequence of characters that occurs between opening and
* closing tags of an XML element, excluding other elements.
*
* Example:
*
* ```
* <content>This is a sequence of characters.</content>
* ```
*/
class XmlCharacters extends @xmlcharacters, XmlLocatable {
/** Gets the content of this character sequence. */
string getCharacters() { xmlChars(this, result, _, _, _, _) }
/** Gets the parent of this character sequence. */
XmlParent getParent() { xmlChars(this, _, result, _, _, _) }
/** Holds if this character sequence is CDATA. */
predicate isCDATA() { xmlChars(this, _, _, _, 1, _) }
/** Gets a printable representation of this XML character sequence. */
override string toString() { result = this.getCharacters() }
}
import Make<File, Location, Input>

View File

@@ -1997,6 +1997,8 @@ class FieldOrProperty extends Assignable, Modifiable {
or
p.getDeclaringType() instanceof AnonymousClass
)
or
p.fromLibrary()
)
}

View File

@@ -47,15 +47,13 @@
*
* For sources, an `output` can be either "", "Argument[n]", "Argument[n1..n2]",
* "Parameter", "Parameter[n]", "Parameter[n1..n2]", or "ReturnValue":
* - "": Selects a read of a selected field, property, or parameter.
* - "": Selects a read of a selected field or property.
* - "Argument[n]": Selects the post-update value of an argument in a call to the
* selected element. That is, the value of the argument after the call returns.
* The arguments are zero-indexed, and `this` specifies the qualifier.
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
* the given range. The range is inclusive at both ends.
* - "Parameter": Selects the value of a parameter of the selected element.
* "Parameter" is also allowed in case the selected element is already a
* parameter itself.
* - "Parameter[n]": Similar to "Parameter" but restricted to a specific
* numbered parameter (zero-indexed, and `this` specifies the value of `this`).
* - "Parameter[n1..n2]": Similar to "Parameter[n]" but selects any parameter

View File

@@ -67,7 +67,11 @@ class Expr extends ControlFlowElement, @expr {
* Holds if this expression is generated by the compiler and does not appear
* explicitly in the source code.
*/
predicate isImplicit() { compiler_generated(this) }
final predicate isImplicit() {
compiler_generated(this) or
this =
any(AssignOperation op).getExpandedAssignment().getRValue().getChildExpr(0).getAChildExpr+()
}
/**
* Gets an expression that is the result of stripping (recursively) all

View File

@@ -87,7 +87,7 @@ predicate extractionIsStandalone(string key, int value) {
value = 0 and
not extractionIsStandalone()
) and
key = "Is buildless extraction"
key = "Is extracted with build-mode set to 'none'"
}
signature module StatsSig {

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.8.13
version: 0.8.14-dev
groups:
- csharp
- queries

View File

@@ -163,9 +163,7 @@ attributes.cs:
# 67| 4: [BlockStmt] {...}
# 70| [Enum] E
# 70| 5: [Field] A
# 70| 1: [AssignExpr] ... = ...
# 70| 0: [MemberConstantAccess] access to constant A
# 70| 1: [IntLiteral] 42
# 70| 1: [IntLiteral] 42
# 72| [Class] ArgsAttribute
#-----| 3: (Base types)
# 72| 0: [TypeMention] Attribute

View File

@@ -186,14 +186,10 @@ trivia.cs:
# 89| 4: [BlockStmt] {...}
# 92| 7: [Field] F1
# 92| -1: [TypeMention] int
# 92| 1: [AssignExpr] ... = ...
# 92| 0: [FieldAccess] access to field F1
# 94| 1: [IntLiteral] 10
# 94| 1: [IntLiteral] 10
# 98| 8: [Field] F2
# 98| -1: [TypeMention] int
# 98| 1: [AssignExpr] ... = ...
# 98| 0: [FieldAccess] access to field F2
# 98| 1: [IntLiteral] 0
# 98| 1: [IntLiteral] 0
# 100| 9: [Property] P1
# 100| -1: [TypeMention] int
# 102| 3: [Getter] get_P1

View File

@@ -1111,18 +1111,14 @@ StaticInterfaceMembers.cs:
#-----| 3: (Base types)
# 28| 4: [Property] Real
# 28| -1: [TypeMention] double
# 28| 2: [AssignExpr] ... = ...
# 28| 0: [PropertyCall] access to property Real
# 28| 1: [DoubleLiteral] 0
# 28| 2: [DoubleLiteral] 0
# 28| 3: [Getter] get_Real
# 28| 4: [Setter] set_Real
#-----| 2: (Parameters)
# 28| 0: [Parameter] value
# 29| 5: [Property] Imaginary
# 29| -1: [TypeMention] double
# 29| 2: [AssignExpr] ... = ...
# 29| 0: [PropertyCall] access to property Imaginary
# 29| 1: [DoubleLiteral] 0
# 29| 2: [DoubleLiteral] 0
# 29| 3: [Getter] get_Imaginary
# 29| 4: [Setter] set_Imaginary
#-----| 2: (Parameters)

View File

@@ -2,9 +2,7 @@ csharp6.cs:
# 10| [Class] TestCSharp6
# 12| 6: [Property] Value
# 12| -1: [TypeMention] int
# 15| 2: [AssignExpr] ... = ...
# 12| 0: [PropertyCall] access to property Value
# 15| 1: [IntLiteral] 20
# 15| 2: [IntLiteral] 20
# 14| 3: [Getter] get_Value
# 17| 7: [Method] Fn
# 17| -1: [TypeMention] Void

View File

@@ -35,15 +35,11 @@ csharp72.cs:
# 44| [Class] NumericLiterals
# 46| 5: [Field] binaryValue
# 46| -1: [TypeMention] int
# 46| 1: [AssignExpr] ... = ...
# 46| 0: [FieldAccess] access to field binaryValue
# 46| 1: [IntLiteral] 85
# 46| 1: [IntLiteral] 85
# 49| [Class] PrivateProtected
# 51| 5: [Field] X
# 51| -1: [TypeMention] int
# 51| 1: [AssignExpr] ... = ...
# 51| 0: [FieldAccess] access to field X
# 51| 1: [IntLiteral] 1
# 51| 1: [IntLiteral] 1
# 53| 6: [Method] F
# 53| -1: [TypeMention] Void
# 53| 4: [BlockStmt] {...}

View File

@@ -2,25 +2,17 @@ CSharp7.cs:
# 5| [Class] Literals
# 7| 5: [Field] x
# 7| -1: [TypeMention] int
# 7| 1: [AssignExpr] ... = ...
# 7| 0: [FieldAccess] access to field x
# 7| 1: [IntLiteral] 11
# 7| 1: [IntLiteral] 11
# 8| 6: [Field] y
# 8| -1: [TypeMention] int
# 8| 1: [AssignExpr] ... = ...
# 8| 0: [FieldAccess] access to field y
# 8| 1: [IntLiteral] 123456
# 8| 1: [IntLiteral] 123456
# 9| 7: [Field] z
# 9| -1: [TypeMention] int
# 9| 1: [AssignExpr] ... = ...
# 9| 0: [FieldAccess] access to field z
# 9| 1: [IntLiteral] 128
# 9| 1: [IntLiteral] 128
# 12| [Class] ExpressionBodiedMembers
# 14| 4: [Field] field
# 14| -1: [TypeMention] int
# 14| 1: [AssignExpr] ... = ...
# 14| 0: [FieldAccess] access to field field
# 14| 1: [IntLiteral] 0
# 14| 1: [IntLiteral] 0
# 15| 5: [Method] Foo
# 15| -1: [TypeMention] int
# 15| 4: [FieldAccess] access to field field

Some files were not shown because too many files have changed in this diff Show More