mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge branch 'main' into reuse-even-more-nodes
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`.
|
||||
@@ -53,7 +53,7 @@ private class ArgvSource extends LocalFlowSource {
|
||||
exists(Function main, Parameter argv |
|
||||
main.hasGlobalName("main") and
|
||||
main.getParameter(1) = argv and
|
||||
this.asParameter(_) = argv
|
||||
this.asParameter(2) = argv
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,6 @@ predicate isNonConst(DataFlow::Node node, boolean isIndirect) {
|
||||
or
|
||||
e instanceof NewArrayExpr
|
||||
or
|
||||
e instanceof AssignExpr
|
||||
or
|
||||
exists(Variable v | v = e.(VariableAccess).getTarget() |
|
||||
v.getType().(ArrayType).getBaseType() instanceof CharType and
|
||||
exists(AssignExpr ae |
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.security.FunctionWithWrappers
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import SqlTainted::PathGraph
|
||||
|
||||
class SqlLikeFunction extends FunctionWithWrappers {
|
||||
SqlLikeFunction() { sqlArgument(this.getName(), _) }
|
||||
@@ -24,31 +26,43 @@ class SqlLikeFunction extends FunctionWithWrappers {
|
||||
override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) }
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element tainted) {
|
||||
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _))
|
||||
Expr asSinkExpr(DataFlow::Node node) {
|
||||
result = node.asIndirectArgument()
|
||||
or
|
||||
// We want the conversion so we only get one node for the expression
|
||||
result = node.asConvertedExpr()
|
||||
}
|
||||
|
||||
module SqlTaintedConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node node) {
|
||||
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(asSinkExpr(node), _))
|
||||
}
|
||||
|
||||
override predicate isBarrier(Expr e) {
|
||||
super.isBarrier(e)
|
||||
or
|
||||
e.getUnspecifiedType() instanceof IntegralType
|
||||
or
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
|
||||
e = sql.getACallToThisFunction().getArgument(arg) and
|
||||
node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and
|
||||
input.isParameterDeref(arg) and
|
||||
sql.barrierSqlArgument(input, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module SqlTainted = TaintTracking::Global<SqlTaintedConfig>;
|
||||
|
||||
from
|
||||
SqlLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
|
||||
string taintCause, string callChain
|
||||
SqlLikeFunction runSql, Expr taintedArg, FlowSource taintSource, SqlTainted::PathNode sourceNode,
|
||||
SqlTainted::PathNode sinkNode, string callChain
|
||||
where
|
||||
runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
|
||||
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
||||
isUserInput(taintSource, taintCause)
|
||||
SqlTainted::flowPath(sourceNode, sinkNode) and
|
||||
taintedArg = asSinkExpr(sinkNode.getNode()) and
|
||||
taintSource = sourceNode.getNode()
|
||||
select taintedArg, sourceNode, sinkNode,
|
||||
"This argument to a SQL query function is derived from $@ and then passed to " + callChain + ".",
|
||||
taintSource, "user input (" + taintCause + ")"
|
||||
taintSource, "user input (" + taintSource.getSourceType() + ")"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results.
|
||||
@@ -40,7 +40,7 @@ module WordexpTaintConfig implements DataFlow::ConfigSig {
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof WordexpFunction |
|
||||
fc.getArgument(0) = sink.asExpr() and
|
||||
fc.getArgument(0) = sink.asIndirectArgument(1) and
|
||||
not isCommandSubstitutionDisabled(fc)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
edges
|
||||
| test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath indirection |
|
||||
nodes
|
||||
| test.cpp:22:27:22:30 | argv | semmle.label | argv |
|
||||
| test.cpp:22:27:22:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
|
||||
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
|
||||
| test.cpp:29:13:29:20 | filePath indirection | semmle.label | filePath indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath indirection | test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath indirection | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
|
||||
@@ -1798,6 +1798,23 @@ ir.c:
|
||||
# 10| Type = [CTypedefType] MyCoords
|
||||
# 10| ValueCategory = lvalue
|
||||
# 11| getStmt(3): [ReturnStmt] return ...
|
||||
# 13| [TopLevelFunction] void CStyleCast(void*)
|
||||
# 13| <params>:
|
||||
# 13| getParameter(0): [Parameter] src
|
||||
# 13| Type = [VoidPointerType] void *
|
||||
# 14| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 15| getStmt(0): [DeclStmt] declaration
|
||||
# 15| getDeclarationEntry(0): [VariableDeclarationEntry] definition of dst
|
||||
# 15| Type = [CharPointerType] char *
|
||||
# 15| getVariable().getInitializer(): [Initializer] initializer for dst
|
||||
# 15| getExpr(): [VariableAccess] src
|
||||
# 15| Type = [VoidPointerType] void *
|
||||
# 15| ValueCategory = prvalue(load)
|
||||
# 15| getExpr().getFullyConverted(): [CStyleCast] (char *)...
|
||||
# 15| Conversion = [PointerConversion] pointer conversion
|
||||
# 15| Type = [CharPointerType] char *
|
||||
# 15| ValueCategory = prvalue
|
||||
# 16| getStmt(1): [ReturnStmt] return ...
|
||||
ir.cpp:
|
||||
# 1| [TopLevelFunction] void Constants()
|
||||
# 1| <params>:
|
||||
|
||||
@@ -9,3 +9,10 @@ void MyCoordsTest(int pos) {
|
||||
coords.x = coords.y = pos + 1;
|
||||
coords.x = getX(&coords);
|
||||
}
|
||||
|
||||
void CStyleCast(void *src)
|
||||
{
|
||||
char *dst = (char*)src;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: --microsoft
|
||||
|
||||
@@ -978,6 +978,20 @@
|
||||
| ir.c:10:19:10:25 | ChiTotal | total:m9_13 |
|
||||
| ir.c:10:19:10:25 | SideEffect | ~m9_13 |
|
||||
| ir.c:10:20:10:25 | Unary | r10_2 |
|
||||
| ir.c:13:6:13:15 | ChiPartial | partial:m13_3 |
|
||||
| ir.c:13:6:13:15 | ChiTotal | total:m13_2 |
|
||||
| ir.c:13:6:13:15 | SideEffect | m13_3 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_5 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_5 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_7 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_7 |
|
||||
| ir.c:13:23:13:25 | Load | m13_6 |
|
||||
| ir.c:13:23:13:25 | SideEffect | m13_8 |
|
||||
| ir.c:15:11:15:13 | Address | &:r15_1 |
|
||||
| ir.c:15:17:15:26 | StoreValue | r15_4 |
|
||||
| ir.c:15:24:15:26 | Address | &:r15_2 |
|
||||
| ir.c:15:24:15:26 | Load | m13_6 |
|
||||
| ir.c:15:24:15:26 | Unary | r15_3 |
|
||||
| ir.cpp:1:6:1:14 | ChiPartial | partial:m1_3 |
|
||||
| ir.cpp:1:6:1:14 | ChiTotal | total:m1_2 |
|
||||
| ir.cpp:1:6:1:14 | SideEffect | m1_3 |
|
||||
|
||||
@@ -766,6 +766,26 @@ ir.c:
|
||||
# 7| v7_7(void) = AliasedUse : ~m?
|
||||
# 7| v7_8(void) = ExitFunction :
|
||||
|
||||
# 13| void CStyleCast(void*)
|
||||
# 13| Block 0
|
||||
# 13| v13_1(void) = EnterFunction :
|
||||
# 13| mu13_2(unknown) = AliasedDefinition :
|
||||
# 13| mu13_3(unknown) = InitializeNonLocal :
|
||||
# 13| r13_4(glval<void *>) = VariableAddress[src] :
|
||||
# 13| mu13_5(void *) = InitializeParameter[src] : &:r13_4
|
||||
# 13| r13_6(void *) = Load[src] : &:r13_4, ~m?
|
||||
# 13| mu13_7(unknown) = InitializeIndirection[src] : &:r13_6
|
||||
# 15| r15_1(glval<char *>) = VariableAddress[dst] :
|
||||
# 15| r15_2(glval<void *>) = VariableAddress[src] :
|
||||
# 15| r15_3(void *) = Load[src] : &:r15_2, ~m?
|
||||
# 15| r15_4(char *) = Convert : r15_3
|
||||
# 15| mu15_5(char *) = Store[dst] : &:r15_1, r15_4
|
||||
# 16| v16_1(void) = NoOp :
|
||||
# 13| v13_8(void) = ReturnIndirection[src] : &:r13_6, ~m?
|
||||
# 13| v13_9(void) = ReturnVoid :
|
||||
# 13| v13_10(void) = AliasedUse : ~m?
|
||||
# 13| v13_11(void) = ExitFunction :
|
||||
|
||||
ir.cpp:
|
||||
# 1| void Constants()
|
||||
# 1| Block 0
|
||||
|
||||
@@ -156,3 +156,10 @@ void fmt_via_strcpy(char *data) {
|
||||
strcpy(data, "some string");
|
||||
printf(data); // BAD
|
||||
}
|
||||
|
||||
void fmt_with_assignment() {
|
||||
const char *x, *y;
|
||||
|
||||
x = y = "a";
|
||||
printf(y); // GOOD
|
||||
}
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
edges
|
||||
| test.c:8:27:8:30 | argv | test.c:17:11:17:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection |
|
||||
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection |
|
||||
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection |
|
||||
nodes
|
||||
| test.c:8:27:8:30 | argv | semmle.label | argv |
|
||||
| test.c:8:27:8:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
|
||||
| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection |
|
||||
@@ -21,12 +15,8 @@ nodes
|
||||
| test.c:57:10:57:16 | access to array indirection | semmle.label | access to array indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv | user input (a command-line argument) |
|
||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) |
|
||||
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) |
|
||||
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
edges
|
||||
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
|
||||
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
|
||||
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||
@@ -73,7 +72,6 @@ edges
|
||||
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:19:220:26 | filename indirection |
|
||||
nodes
|
||||
| test.cpp:15:27:15:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:15:27:15:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:22:45:22:52 | userName indirection | semmle.label | userName indirection |
|
||||
| test.cpp:23:12:23:19 | command1 indirection | semmle.label | command1 indirection |
|
||||
@@ -156,7 +154,6 @@ subpaths
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
#select
|
||||
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | call to getenv indirection | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
edges
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
subpaths
|
||||
| test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
|
||||
nodes
|
||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
||||
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
|
||||
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
|
||||
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
|
||||
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
|
||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
||||
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
|
||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:15:20:15:23 | argv | user input (argv) |
|
||||
| test.cpp:43:27:43:33 | access to array | test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:43:27:43:30 | argv | user input (argv) |
|
||||
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
edges
|
||||
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
|
||||
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection |
|
||||
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument |
|
||||
@@ -21,10 +17,7 @@ edges
|
||||
| overflowdestination.cpp:76:30:76:32 | src indirection | overflowdestination.cpp:57:52:57:54 | src indirection |
|
||||
nodes
|
||||
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
||||
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
|
||||
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
|
||||
| overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument |
|
||||
@@ -44,7 +37,6 @@ subpaths
|
||||
| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument |
|
||||
#select
|
||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | src2 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
edges
|
||||
| test1.c:7:26:7:29 | argv | test1.c:9:9:9:9 | i |
|
||||
| test1.c:7:26:7:29 | argv | test1.c:11:9:11:9 | i |
|
||||
| test1.c:7:26:7:29 | argv | test1.c:13:9:13:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:9:9:9:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:9:9:9:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:11:9:11:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:11:9:11:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:13:9:13:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:13:9:13:9 | i |
|
||||
| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i |
|
||||
| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i |
|
||||
@@ -15,8 +9,6 @@ edges
|
||||
| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i |
|
||||
| test1.c:48:16:48:16 | i | test1.c:53:15:53:15 | j |
|
||||
nodes
|
||||
| test1.c:7:26:7:29 | argv | semmle.label | argv |
|
||||
| test1.c:7:26:7:29 | argv indirection | semmle.label | argv indirection |
|
||||
| test1.c:7:26:7:29 | argv indirection | semmle.label | argv indirection |
|
||||
| test1.c:9:9:9:9 | i | semmle.label | i |
|
||||
| test1.c:11:9:11:9 | i | semmle.label | i |
|
||||
@@ -29,12 +21,6 @@ nodes
|
||||
| test1.c:53:15:53:15 | j | semmle.label | j |
|
||||
subpaths
|
||||
#select
|
||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv indirection | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv indirection | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv indirection | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv indirection | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv indirection | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv indirection | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
edges
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:43:38:43:44 | tainted |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:44:38:44:63 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:46:38:46:63 | ... + ... |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:50:26:50:29 | size |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... |
|
||||
| test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... |
|
||||
@@ -47,8 +35,6 @@ edges
|
||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:355:35:355:38 | size |
|
||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:356:35:356:38 | size |
|
||||
nodes
|
||||
| test.cpp:39:27:39:30 | argv | semmle.label | argv |
|
||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
||||
| test.cpp:44:38:44:63 | ... * ... | semmle.label | ... * ... |
|
||||
@@ -92,23 +78,11 @@ nodes
|
||||
| test.cpp:356:35:356:38 | size | semmle.label | size |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:23 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:31 | call to getenv indirection | user input (an environment variable) |
|
||||
|
||||
@@ -4,7 +4,6 @@ edges
|
||||
nodes
|
||||
| test2.cpp:110:3:110:6 | call to gets indirection | semmle.label | call to gets indirection |
|
||||
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
8
csharp/.vscode/extensions.json
vendored
8
csharp/.vscode/extensions.json
vendored
@@ -1,9 +1,11 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"github.vscode-codeql",
|
||||
"ms-dotnettools.csharp",
|
||||
"formulahendry.dotnet-test-explorer",
|
||||
"hbenl.vscode-test-explorer"
|
||||
"gaoshan0621.csharp-format-usings",
|
||||
"github.vscode-codeql",
|
||||
"hbenl.vscode-test-explorer",
|
||||
"ms-dotnettools.csharp",
|
||||
"ms-dotnettools.csdevkit"
|
||||
],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
5
csharp/.vscode/settings.json
vendored
5
csharp/.vscode/settings.json
vendored
@@ -7,5 +7,8 @@
|
||||
"editor.defaultFormatter": "ms-dotnettools.csharp"
|
||||
},
|
||||
"omnisharp.enableEditorConfigSupport": true,
|
||||
"omnisharp.enableRoslynAnalyzers": true
|
||||
"omnisharp.enableRoslynAnalyzers": true,
|
||||
"csharpFormatUsings.splitGroups": false,
|
||||
"csharpFormatUsings.sortOrder": "Xunit System Microsoft Semmle.Util Semmle",
|
||||
"dotnet.defaultSolution": "CSharp.sln"
|
||||
}
|
||||
53
csharp/.vscode/tasks.json
vendored
53
csharp/.vscode/tasks.json
vendored
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "dotnet build",
|
||||
"command": "dotnet",
|
||||
"type": "shell",
|
||||
"args": [
|
||||
"build",
|
||||
// Ask dotnet build to generate full paths for file names.
|
||||
"/property:GenerateFullPaths=true",
|
||||
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"reveal": "always"
|
||||
},
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "dotnet rebuild",
|
||||
"command": "dotnet",
|
||||
"type": "shell",
|
||||
"args": [
|
||||
"build",
|
||||
"--no-incremental",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"reveal": "always"
|
||||
},
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "dotnet test",
|
||||
"command": "dotnet",
|
||||
"type": "shell",
|
||||
"args": [
|
||||
"test",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"reveal": "always"
|
||||
},
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
name: "csharp"
|
||||
aliases:
|
||||
- "c#"
|
||||
display_name: "C#"
|
||||
version: 1.22.1
|
||||
column_kind: "utf16"
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Runtime.InteropServices;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Driver
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Semmle.Util.Logging;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Driver
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Semmle.Util.Logging;
|
||||
using System;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
using Semmle.Extraction.CIL.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CIL
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using Semmle.Extraction.CIL.Entities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
using Semmle.Extraction.CIL.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CIL
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Semmle.Extraction.Entities;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
internal interface ITypeSignature
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Semmle.Extraction.PDB;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.DiaSymReader;
|
||||
using System.Reflection;
|
||||
using Microsoft.DiaSymReader;
|
||||
|
||||
#pragma warning disable IDE0060, CA1822
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using Microsoft.DiaSymReader;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.Metadata;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.PDB
|
||||
{
|
||||
|
||||
@@ -59,10 +59,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
// The OrderBy is used to ensure that we by default select the highest version number.
|
||||
foreach (var info in assemblyInfoByFileName.Values
|
||||
.OrderBy(info => info.Name)
|
||||
.ThenBy(info => info.NetCoreVersion ?? emptyVersion)
|
||||
.ThenBy(info => info.Version ?? emptyVersion))
|
||||
{
|
||||
foreach (var index in info.IndexStrings)
|
||||
{
|
||||
assemblyInfoById[index] = info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,15 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores information about an assembly file (DLL).
|
||||
/// </summary>
|
||||
internal sealed class AssemblyInfo
|
||||
internal sealed partial class AssemblyInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The file containing the assembly.
|
||||
@@ -28,6 +30,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// </summary>
|
||||
public System.Version? Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the .NET Core framework that this assembly targets.
|
||||
///
|
||||
/// This is extracted from the `TargetFrameworkAttribute` of the assembly, e.g.
|
||||
/// ```
|
||||
/// [assembly:TargetFramework(".NETCoreApp,Version=v7.0")]
|
||||
/// ```
|
||||
/// yields version 7.0.
|
||||
/// </summary>
|
||||
public Version? NetCoreVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The public key token of the assembly.
|
||||
/// </summary>
|
||||
@@ -97,13 +110,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
Filename = filename;
|
||||
}
|
||||
|
||||
private AssemblyInfo(string filename, string name, Version version, string culture, string publicKeyToken)
|
||||
private AssemblyInfo(string filename, string name, Version version, string culture, string publicKeyToken, Version? netCoreVersion)
|
||||
{
|
||||
Filename = filename;
|
||||
Name = name;
|
||||
Version = version;
|
||||
Culture = culture;
|
||||
PublicKeyToken = publicKeyToken;
|
||||
NetCoreVersion = netCoreVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -150,7 +164,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var metadata = pereader.GetMetadata();
|
||||
unsafe
|
||||
{
|
||||
var reader = new System.Reflection.Metadata.MetadataReader(metadata.Pointer, metadata.Length);
|
||||
var reader = new MetadataReader(metadata.Pointer, metadata.Length);
|
||||
var def = reader.GetAssemblyDefinition();
|
||||
|
||||
// This is how you compute the public key token from the full public key.
|
||||
@@ -162,7 +176,39 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
publicKeyString.AppendFormat("{0:x2}", b);
|
||||
|
||||
var culture = def.Culture.IsNil ? "neutral" : reader.GetString(def.Culture);
|
||||
return new AssemblyInfo(filename, reader.GetString(def.Name), def.Version, culture, publicKeyString.ToString());
|
||||
Version? netCoreVersion = null;
|
||||
|
||||
foreach (var attrHandle in def.GetCustomAttributes().Select(reader.GetCustomAttribute))
|
||||
{
|
||||
var ctorHandle = attrHandle.Constructor;
|
||||
if (ctorHandle.Kind != HandleKind.MemberReference)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var mHandle = reader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent;
|
||||
if (mHandle.Kind != HandleKind.TypeReference)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var name = reader.GetString(reader.GetTypeReference((TypeReferenceHandle)mHandle).Name);
|
||||
|
||||
if (name is "TargetFrameworkAttribute")
|
||||
{
|
||||
var decoded = attrHandle.DecodeValue(new DummyAttributeDecoder());
|
||||
if (
|
||||
decoded.FixedArguments.Length > 0 &&
|
||||
decoded.FixedArguments[0].Value is string value &&
|
||||
NetCoreAppRegex().Match(value).Groups.TryGetValue("version", out var match))
|
||||
{
|
||||
netCoreVersion = new Version(match.Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new AssemblyInfo(filename, reader.GetString(def.Name), def.Version, culture, publicKeyString.ToString(), netCoreVersion);
|
||||
}
|
||||
}
|
||||
catch (BadImageFormatException)
|
||||
@@ -176,5 +222,33 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
throw new AssemblyLoadException();
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^\.NETCoreApp,Version=v(?<version>\d+\.\d+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||
private static partial Regex NetCoreAppRegex();
|
||||
|
||||
private class DummyAttributeDecoder : ICustomAttributeTypeProvider<int>
|
||||
{
|
||||
public int GetPrimitiveType(PrimitiveTypeCode typeCode) => 0;
|
||||
|
||||
public int GetSystemType() => throw new NotImplementedException();
|
||||
|
||||
public int GetSZArrayType(int elementType) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
public int GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
public int GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
public int GetTypeFromSerializedName(string name) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
public PrimitiveTypeCode GetUnderlyingEnumType(int type) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
public bool IsSystemType(int type) => throw new NotImplementedException();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private readonly IDictionary<string, string> unresolvedReferences = new ConcurrentDictionary<string, string>();
|
||||
private int failedProjects;
|
||||
private int succeededProjects;
|
||||
private readonly string[] allSources;
|
||||
private readonly List<string> allSources;
|
||||
private int conflictedReferences = 0;
|
||||
private readonly IDependencyOptions options;
|
||||
private readonly DirectoryInfo sourceDir;
|
||||
private readonly DotNet dotnet;
|
||||
private readonly FileContent fileContent;
|
||||
private readonly TemporaryDirectory packageDirectory;
|
||||
private TemporaryDirectory? razorWorkingDirectory;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -59,8 +60,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
packageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName));
|
||||
|
||||
this.fileContent = new FileContent(packageDirectory, progressMonitor, () => GetFiles("*.*"));
|
||||
this.allSources = GetFiles("*.cs").ToArray();
|
||||
this.fileContent = new FileContent(progressMonitor, () => GetFiles("*.*"));
|
||||
this.allSources = GetFiles("*.cs").ToList();
|
||||
var allProjects = GetFiles("*.csproj");
|
||||
var solutions = options.SolutionFile is not null
|
||||
? new[] { options.SolutionFile }
|
||||
@@ -121,16 +122,23 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
ResolveConflicts();
|
||||
|
||||
// Output the findings
|
||||
foreach (var r in usedReferences.Keys)
|
||||
foreach (var r in usedReferences.Keys.OrderBy(r => r))
|
||||
{
|
||||
progressMonitor.ResolvedReference(r);
|
||||
}
|
||||
|
||||
foreach (var r in unresolvedReferences)
|
||||
foreach (var r in unresolvedReferences.OrderBy(r => r.Key))
|
||||
{
|
||||
progressMonitor.UnresolvedReference(r.Key, r.Value);
|
||||
}
|
||||
|
||||
var webViewExtractionOption = Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_STANDALONE_EXTRACT_WEB_VIEWS");
|
||||
if (bool.TryParse(webViewExtractionOption, out var shouldExtractWebViews) &&
|
||||
shouldExtractWebViews)
|
||||
{
|
||||
GenerateSourceFilesFromWebViews();
|
||||
}
|
||||
|
||||
progressMonitor.Summary(
|
||||
AllSourceFiles.Count(),
|
||||
ProjectSourceFiles.Count(),
|
||||
@@ -143,22 +151,56 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
DateTime.Now - startTime);
|
||||
}
|
||||
|
||||
private void GenerateSourceFilesFromWebViews()
|
||||
{
|
||||
progressMonitor.LogInfo($"Generating source files from cshtml and razor files.");
|
||||
|
||||
var views = GetFiles("*.cshtml")
|
||||
.Concat(GetFiles("*.razor"))
|
||||
.ToArray();
|
||||
|
||||
if (views.Length > 0)
|
||||
{
|
||||
progressMonitor.LogInfo($"Found {views.Length} cshtml and razor files.");
|
||||
|
||||
// TODO: use SDK specified in global.json
|
||||
var sdk = new Sdk(dotnet).GetNewestSdk();
|
||||
if (sdk != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var razor = new Razor(sdk, dotnet, progressMonitor);
|
||||
razorWorkingDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName, "razor"));
|
||||
var generatedFiles = razor.GenerateFiles(views, usedReferences.Keys, razorWorkingDirectory.ToString());
|
||||
this.allSources.AddRange(generatedFiles);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// It's okay, we tried our best to generate source files from cshtml files.
|
||||
progressMonitor.LogInfo($"Failed to generate source files from cshtml files: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DependencyManager(string srcDir) : this(srcDir, DependencyOptions.Default, new ConsoleLogger(Verbosity.Info)) { }
|
||||
|
||||
private IEnumerable<string> GetFiles(string pattern, bool recurseSubdirectories = true)
|
||||
{
|
||||
return sourceDir.GetFiles(pattern, new EnumerationOptions { RecurseSubdirectories = recurseSubdirectories, MatchCasing = MatchCasing.CaseInsensitive })
|
||||
private IEnumerable<string> GetFiles(string pattern, bool recurseSubdirectories = true) =>
|
||||
sourceDir.GetFiles(pattern, new EnumerationOptions
|
||||
{
|
||||
RecurseSubdirectories = recurseSubdirectories,
|
||||
MatchCasing = MatchCasing.CaseInsensitive
|
||||
})
|
||||
.Where(d => d.Extension != ".dll")
|
||||
.Select(d => d.FullName)
|
||||
.Where(d => !options.ExcludesFile(d));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes a unique temp directory for the packages associated
|
||||
/// with this source tree. Use a SHA1 of the directory name.
|
||||
/// </summary>
|
||||
/// <param name="srcDir"></param>
|
||||
/// <returns>The full path of the temp directory.</returns>
|
||||
private static string ComputeTempDirectory(string srcDir)
|
||||
private static string ComputeTempDirectory(string srcDir, string subfolderName = "packages")
|
||||
{
|
||||
var bytes = Encoding.Unicode.GetBytes(srcDir);
|
||||
var sha = SHA1.HashData(bytes);
|
||||
@@ -166,7 +208,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
foreach (var b in sha.Take(8))
|
||||
sb.AppendFormat("{0:x2}", b);
|
||||
|
||||
return Path.Combine(Path.GetTempPath(), "GitHub", "packages", sb.ToString());
|
||||
return Path.Combine(Path.GetTempPath(), "GitHub", subfolderName, sb.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -190,7 +232,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
}
|
||||
|
||||
sortedReferences = sortedReferences.OrderBy(r => r.Version).ToList();
|
||||
var emptyVersion = new Version(0, 0);
|
||||
sortedReferences = sortedReferences.OrderBy(r => r.NetCoreVersion ?? emptyVersion).ThenBy(r => r.Version ?? emptyVersion).ToList();
|
||||
|
||||
var finalAssemblyList = new Dictionary<string, AssemblyInfo>();
|
||||
|
||||
@@ -211,9 +254,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
foreach (var r in sortedReferences)
|
||||
{
|
||||
var resolvedInfo = finalAssemblyList[r.Name];
|
||||
if (resolvedInfo.Version != r.Version)
|
||||
if (resolvedInfo.Version != r.Version || resolvedInfo.NetCoreVersion != r.NetCoreVersion)
|
||||
{
|
||||
progressMonitor.ResolvedConflict(r.Id, resolvedInfo.Id);
|
||||
progressMonitor.ResolvedConflict(r.Id, resolvedInfo.Id + resolvedInfo.NetCoreVersion is null ? "" : $" (.NET Core {resolvedInfo.NetCoreVersion})");
|
||||
++conflictedReferences;
|
||||
}
|
||||
}
|
||||
@@ -349,7 +392,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
nugetConfig = nugetConfigs.FirstOrDefault();
|
||||
}
|
||||
|
||||
foreach (var package in fileContent.NotYetDownloadedPackages)
|
||||
var alreadyDownloadedPackages = Directory.GetDirectories(packageDirectory.DirInfo.FullName)
|
||||
.Select(d => Path.GetFileName(d)
|
||||
.ToLowerInvariant());
|
||||
var notYetDownloadedPackages = fileContent.AllPackages.Except(alreadyDownloadedPackages);
|
||||
foreach (var package in notYetDownloadedPackages)
|
||||
{
|
||||
progressMonitor.NugetInstall(package);
|
||||
using var tempDir = new TemporaryDirectory(ComputeTempDirectory(package));
|
||||
@@ -377,7 +424,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
private void AnalyseSolutions(IEnumerable<string> solutions)
|
||||
{
|
||||
Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = 4 }, solutionFile =>
|
||||
Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, solutionFile =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -392,6 +439,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose() => packageDirectory?.Dispose();
|
||||
public void Dispose()
|
||||
{
|
||||
packageDirectory?.Dispose();
|
||||
razorWorkingDirectory?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
@@ -49,6 +51,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// <param name="path">The path to query.</param>
|
||||
/// <returns>True iff the path matches an exclusion.</returns>
|
||||
bool ExcludesFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// The number of threads to use.
|
||||
/// </summary>
|
||||
int Threads { get; }
|
||||
}
|
||||
|
||||
public class DependencyOptions : IDependencyOptions
|
||||
@@ -71,5 +78,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
public bool ExcludesFile(string path) =>
|
||||
Excludes.Any(path.Contains);
|
||||
|
||||
public int Threads { get; set; } = EnvironmentVariables.GetDefaultNumberOfThreads();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,6 @@ using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal interface IDotNet
|
||||
{
|
||||
bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null);
|
||||
bool New(string folder);
|
||||
bool AddPackage(string folder, string package);
|
||||
IList<string> GetListedRuntimes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Utilities to run the "dotnet" command.
|
||||
/// </summary>
|
||||
@@ -30,29 +22,31 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private void Info()
|
||||
{
|
||||
// TODO: make sure the below `dotnet` version is matching the one specified in global.json
|
||||
progressMonitor.RunningProcess($"{dotnet} --info");
|
||||
using var proc = Process.Start(dotnet, "--info");
|
||||
proc.WaitForExit();
|
||||
var ret = proc.ExitCode;
|
||||
|
||||
if (ret != 0)
|
||||
var res = RunCommand("--info");
|
||||
if (!res)
|
||||
{
|
||||
progressMonitor.CommandFailed(dotnet, "--info", ret);
|
||||
throw new Exception($"{dotnet} --info failed with exit code {ret}.");
|
||||
throw new Exception($"{dotnet} --info failed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static ProcessStartInfo MakeDotnetStartInfo(string args, bool redirectStandardOutput) =>
|
||||
new ProcessStartInfo(dotnet, args)
|
||||
{
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = redirectStandardOutput
|
||||
};
|
||||
|
||||
private bool RunCommand(string args)
|
||||
{
|
||||
progressMonitor.RunningProcess($"{dotnet} {args}");
|
||||
using var proc = Process.Start(dotnet, args);
|
||||
proc.WaitForExit();
|
||||
if (proc.ExitCode != 0)
|
||||
using var proc = Process.Start(MakeDotnetStartInfo(args, redirectStandardOutput: false));
|
||||
proc?.WaitForExit();
|
||||
var exitCode = proc?.ExitCode ?? -1;
|
||||
if (exitCode != 0)
|
||||
{
|
||||
progressMonitor.CommandFailed(dotnet, args, proc.ExitCode);
|
||||
progressMonitor.CommandFailed(dotnet, args, exitCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -76,23 +70,28 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return RunCommand(args);
|
||||
}
|
||||
|
||||
public IList<string> GetListedRuntimes()
|
||||
public IList<string> GetListedRuntimes() => GetListed("--list-runtimes", "runtime");
|
||||
|
||||
public IList<string> GetListedSdks() => GetListed("--list-sdks", "SDK");
|
||||
|
||||
private IList<string> GetListed(string args, string artifact)
|
||||
{
|
||||
const string args = "--list-runtimes";
|
||||
progressMonitor.RunningProcess($"{dotnet} {args}");
|
||||
var pi = new ProcessStartInfo(dotnet, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
var exitCode = pi.ReadOutput(out var runtimes);
|
||||
var pi = MakeDotnetStartInfo(args, redirectStandardOutput: true);
|
||||
var exitCode = pi.ReadOutput(out var artifacts);
|
||||
if (exitCode != 0)
|
||||
{
|
||||
progressMonitor.CommandFailed(dotnet, args, exitCode);
|
||||
return new List<string>();
|
||||
}
|
||||
progressMonitor.LogInfo($"Found runtimes: {string.Join("\n", runtimes)}");
|
||||
return runtimes;
|
||||
progressMonitor.LogInfo($"Found {artifact}s: {string.Join("\n", artifacts)}");
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
public bool Exec(string execArgs)
|
||||
{
|
||||
var args = $"exec {execArgs}";
|
||||
return RunCommand(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal record DotnetVersion : IComparable<DotnetVersion>
|
||||
{
|
||||
private readonly string dir;
|
||||
private readonly Version version;
|
||||
private readonly Version? preReleaseVersion;
|
||||
private readonly string? preReleaseVersionType;
|
||||
private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null;
|
||||
public string FullPath
|
||||
{
|
||||
get
|
||||
{
|
||||
var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : "";
|
||||
var version = this.version + preRelease;
|
||||
return Path.Combine(dir, version);
|
||||
}
|
||||
}
|
||||
|
||||
public DotnetVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion)
|
||||
{
|
||||
this.dir = dir;
|
||||
this.version = Version.Parse(version);
|
||||
if (!string.IsNullOrEmpty(preReleaseVersion) && !string.IsNullOrEmpty(preReleaseVersionType))
|
||||
{
|
||||
this.preReleaseVersionType = preReleaseVersionType;
|
||||
this.preReleaseVersion = Version.Parse(preReleaseVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(DotnetVersion? other)
|
||||
{
|
||||
var c = version.CompareTo(other?.version);
|
||||
if (c == 0 && IsPreRelease)
|
||||
{
|
||||
if (!other!.IsPreRelease)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Both are pre-release like runtime versions.
|
||||
// The pre-release version types are sorted alphabetically (e.g. alpha, beta, preview, rc)
|
||||
// and the pre-release version types are more important that the pre-release version numbers.
|
||||
return preReleaseVersionType != other!.preReleaseVersionType
|
||||
? preReleaseVersionType!.CompareTo(other!.preReleaseVersionType)
|
||||
: preReleaseVersion!.CompareTo(other!.preReleaseVersion);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public override string ToString() => FullPath;
|
||||
}
|
||||
}
|
||||
@@ -12,23 +12,22 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
// This class is used to read a set of files and decide different properties about the
|
||||
// content (by reading the content of the files only once).
|
||||
// The implementation is lazy, so the properties are only calculated when
|
||||
// the first property is accessed.
|
||||
// the first property is accessed.
|
||||
// </summary>
|
||||
internal partial class FileContent
|
||||
{
|
||||
private readonly ProgressMonitor progressMonitor;
|
||||
private readonly IUnsafeFileReader unsafeFileReader;
|
||||
private readonly Func<IEnumerable<string>> getFiles;
|
||||
private readonly Func<HashSet<string>> getAlreadyDownloadedPackages;
|
||||
private readonly HashSet<string> notYetDownloadedPackages = new HashSet<string>();
|
||||
private readonly HashSet<string> allPackages = new HashSet<string>();
|
||||
private readonly Initializer initialize;
|
||||
|
||||
public HashSet<string> NotYetDownloadedPackages
|
||||
public HashSet<string> AllPackages
|
||||
{
|
||||
get
|
||||
{
|
||||
initialize.Run();
|
||||
return notYetDownloadedPackages;
|
||||
return allPackages;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,12 +49,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
}
|
||||
|
||||
internal FileContent(Func<HashSet<string>> getAlreadyDownloadedPackages,
|
||||
ProgressMonitor progressMonitor,
|
||||
internal FileContent(ProgressMonitor progressMonitor,
|
||||
Func<IEnumerable<string>> getFiles,
|
||||
IUnsafeFileReader unsafeFileReader)
|
||||
{
|
||||
this.getAlreadyDownloadedPackages = getAlreadyDownloadedPackages;
|
||||
this.progressMonitor = progressMonitor;
|
||||
this.getFiles = getFiles;
|
||||
this.unsafeFileReader = unsafeFileReader;
|
||||
@@ -63,10 +60,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
|
||||
|
||||
public FileContent(TemporaryDirectory packageDirectory, ProgressMonitor progressMonitor, Func<IEnumerable<string>> getFiles) : this(() => Directory.GetDirectories(packageDirectory.DirInfo.FullName)
|
||||
.Select(d => Path.GetFileName(d)
|
||||
.ToLowerInvariant())
|
||||
.ToHashSet(), progressMonitor, getFiles, new UnsafeFileReader())
|
||||
public FileContent(ProgressMonitor progressMonitor, Func<IEnumerable<string>> getFiles) : this(progressMonitor, getFiles, new UnsafeFileReader())
|
||||
{ }
|
||||
|
||||
private static string GetGroup(ReadOnlySpan<char> input, ValueMatch valueMatch, string groupPrefix)
|
||||
@@ -101,7 +95,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
private void DoInitialize()
|
||||
{
|
||||
var alreadyDownloadedPackages = getAlreadyDownloadedPackages();
|
||||
foreach (var file in getFiles())
|
||||
{
|
||||
try
|
||||
@@ -109,14 +102,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
foreach (ReadOnlySpan<char> line in unsafeFileReader.ReadLines(file))
|
||||
{
|
||||
|
||||
// Find the not yet downloaded packages.
|
||||
// Find all the packages.
|
||||
foreach (var valueMatch in PackageReference().EnumerateMatches(line))
|
||||
{
|
||||
// We can't get the group from the ValueMatch, so doing it manually:
|
||||
var packageName = GetGroup(line, valueMatch, "Include");
|
||||
if (!string.IsNullOrEmpty(packageName) && !alreadyDownloadedPackages.Contains(packageName))
|
||||
if (!string.IsNullOrEmpty(packageName))
|
||||
{
|
||||
notYetDownloadedPackages.Add(packageName);
|
||||
allPackages.Add(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal interface IDotNet
|
||||
{
|
||||
bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null);
|
||||
bool New(string folder);
|
||||
bool AddPackage(string folder, string package);
|
||||
IList<string> GetListedRuntimes();
|
||||
IList<string> GetListedSdks();
|
||||
bool Exec(string execArgs);
|
||||
}
|
||||
}
|
||||
@@ -108,5 +108,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
internal void NoTopLevelNugetConfig() =>
|
||||
LogInfo("Could not find a top-level nuget.config file.");
|
||||
|
||||
internal void RazorSourceGeneratorMissing(string fullPath) =>
|
||||
LogInfo($"Razor source generator folder {fullPath} does not exist.");
|
||||
|
||||
internal void CscMissing(string cscPath) =>
|
||||
LogInfo($"Csc.exe not found at {cscPath}.");
|
||||
|
||||
internal void RazorCscArgs(string args) =>
|
||||
LogInfo($"Running CSC to generate Razor source files. Args: {args}.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal class Razor
|
||||
{
|
||||
private readonly DotnetVersion sdk;
|
||||
private readonly ProgressMonitor progressMonitor;
|
||||
private readonly DotNet dotNet;
|
||||
private readonly string sourceGeneratorFolder;
|
||||
private readonly string cscPath;
|
||||
|
||||
public Razor(DotnetVersion sdk, DotNet dotNet, ProgressMonitor progressMonitor)
|
||||
{
|
||||
this.sdk = sdk;
|
||||
this.progressMonitor = progressMonitor;
|
||||
this.dotNet = dotNet;
|
||||
|
||||
sourceGeneratorFolder = Path.Combine(this.sdk.FullPath, "Sdks", "Microsoft.NET.Sdk.Razor", "source-generators");
|
||||
if (!Directory.Exists(sourceGeneratorFolder))
|
||||
{
|
||||
this.progressMonitor.RazorSourceGeneratorMissing(sourceGeneratorFolder);
|
||||
throw new Exception($"Razor source generator folder {sourceGeneratorFolder} does not exist.");
|
||||
}
|
||||
|
||||
cscPath = Path.Combine(this.sdk.FullPath, "Roslyn", "bincore", "csc.dll");
|
||||
if (!File.Exists(cscPath))
|
||||
{
|
||||
this.progressMonitor.CscMissing(cscPath);
|
||||
throw new Exception($"csc.dll {cscPath} does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateAnalyzerConfig(IEnumerable<string> cshtmls, string analyzerConfigPath)
|
||||
{
|
||||
using var sw = new StreamWriter(analyzerConfigPath);
|
||||
sw.WriteLine("is_global = true");
|
||||
|
||||
foreach (var f in cshtmls.Select(f => f.Replace('\\', '/')))
|
||||
{
|
||||
sw.WriteLine($"\n[{f}]");
|
||||
var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(f)); // TODO: this should be the relative path of the file.
|
||||
sw.WriteLine($"build_metadata.AdditionalFiles.TargetPath = {base64}");
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GenerateFiles(IEnumerable<string> cshtmls, IEnumerable<string> references, string workingDirectory)
|
||||
{
|
||||
var name = Guid.NewGuid().ToString("N").ToUpper();
|
||||
var tempPath = Path.GetTempPath();
|
||||
var analyzerConfig = Path.Combine(tempPath, $"{name}.txt");
|
||||
var dllPath = Path.Combine(tempPath, $"{name}.dll");
|
||||
var cscArgsPath = Path.Combine(tempPath, $"{name}.rsp");
|
||||
var outputFolder = Path.Combine(workingDirectory, name);
|
||||
Directory.CreateDirectory(outputFolder);
|
||||
|
||||
try
|
||||
{
|
||||
GenerateAnalyzerConfig(cshtmls, analyzerConfig);
|
||||
|
||||
progressMonitor.LogInfo($"Analyzer config content: {File.ReadAllText(analyzerConfig)}");
|
||||
|
||||
var args = new StringBuilder();
|
||||
args.Append($"/target:exe /generatedfilesout:\"{outputFolder}\" /out:\"{dllPath}\" /analyzerconfig:\"{analyzerConfig}\" ");
|
||||
|
||||
foreach (var f in Directory.GetFiles(sourceGeneratorFolder, "*.dll"))
|
||||
{
|
||||
args.Append($"/analyzer:\"{f}\" ");
|
||||
}
|
||||
|
||||
foreach (var f in cshtmls)
|
||||
{
|
||||
args.Append($"/additionalfile:\"{f}\" ");
|
||||
}
|
||||
|
||||
foreach (var f in references)
|
||||
{
|
||||
args.Append($"/reference:\"{f}\" ");
|
||||
}
|
||||
|
||||
var argsString = args.ToString();
|
||||
|
||||
progressMonitor.RazorCscArgs(argsString);
|
||||
|
||||
using (var sw = new StreamWriter(cscArgsPath))
|
||||
{
|
||||
sw.Write(argsString);
|
||||
}
|
||||
|
||||
dotNet.Exec($"\"{cscPath}\" /noconfig @\"{cscArgsPath}\"");
|
||||
|
||||
return Directory.GetFiles(outputFolder, "*.*", new EnumerationOptions { RecurseSubdirectories = true });
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeleteFile(analyzerConfig);
|
||||
DeleteFile(dllPath);
|
||||
DeleteFile(cscArgsPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteFile(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private const string aspNetCoreApp = "Microsoft.AspNetCore.App";
|
||||
|
||||
private readonly IDotNet dotNet;
|
||||
private readonly Lazy<Dictionary<string, RuntimeVersion>> newestRuntimes;
|
||||
private Dictionary<string, RuntimeVersion> NewestRuntimes => newestRuntimes.Value;
|
||||
private readonly Lazy<Dictionary<string, DotnetVersion>> newestRuntimes;
|
||||
private Dictionary<string, DotnetVersion> NewestRuntimes => newestRuntimes.Value;
|
||||
private static string ExecutingRuntime => RuntimeEnvironment.GetRuntimeDirectory();
|
||||
|
||||
public Runtime(IDotNet dotNet)
|
||||
@@ -27,58 +27,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
this.newestRuntimes = new(GetNewestRuntimes);
|
||||
}
|
||||
|
||||
internal record RuntimeVersion : IComparable<RuntimeVersion>
|
||||
{
|
||||
private readonly string dir;
|
||||
private readonly Version version;
|
||||
private readonly Version? preReleaseVersion;
|
||||
private readonly string? preReleaseVersionType;
|
||||
private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null;
|
||||
public string FullPath
|
||||
{
|
||||
get
|
||||
{
|
||||
var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : "";
|
||||
var version = this.version + preRelease;
|
||||
return Path.Combine(dir, version);
|
||||
}
|
||||
}
|
||||
|
||||
public RuntimeVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion)
|
||||
{
|
||||
this.dir = dir;
|
||||
this.version = Version.Parse(version);
|
||||
if (!string.IsNullOrEmpty(preReleaseVersion) && !string.IsNullOrEmpty(preReleaseVersionType))
|
||||
{
|
||||
this.preReleaseVersionType = preReleaseVersionType;
|
||||
this.preReleaseVersion = Version.Parse(preReleaseVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(RuntimeVersion? other)
|
||||
{
|
||||
var c = version.CompareTo(other?.version);
|
||||
if (c == 0 && IsPreRelease)
|
||||
{
|
||||
if (!other!.IsPreRelease)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Both are pre-release like runtime versions.
|
||||
// The pre-release version types are sorted alphabetically (e.g. alpha, beta, preview, rc)
|
||||
// and the pre-release version types are more important that the pre-release version numbers.
|
||||
return preReleaseVersionType != other!.preReleaseVersionType
|
||||
? preReleaseVersionType!.CompareTo(other!.preReleaseVersionType)
|
||||
: preReleaseVersion!.CompareTo(other!.preReleaseVersion);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public override string ToString() => FullPath;
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^(\S+)\s(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")]
|
||||
private static partial Regex RuntimeRegex();
|
||||
|
||||
@@ -88,16 +36,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// It is assume that the format of a listed runtime is something like:
|
||||
/// Microsoft.NETCore.App 7.0.2 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
|
||||
/// </summary>
|
||||
private static Dictionary<string, RuntimeVersion> ParseRuntimes(IList<string> listed)
|
||||
private static Dictionary<string, DotnetVersion> ParseRuntimes(IList<string> listed)
|
||||
{
|
||||
// Parse listed runtimes.
|
||||
var runtimes = new Dictionary<string, RuntimeVersion>();
|
||||
var runtimes = new Dictionary<string, DotnetVersion>();
|
||||
var regex = RuntimeRegex();
|
||||
listed.ForEach(r =>
|
||||
{
|
||||
var match = RuntimeRegex().Match(r);
|
||||
var match = regex.Match(r);
|
||||
if (match.Success)
|
||||
{
|
||||
runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new RuntimeVersion(match.Groups[6].Value, match.Groups[2].Value, match.Groups[4].Value, match.Groups[5].Value));
|
||||
runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new DotnetVersion(match.Groups[6].Value, match.Groups[2].Value, match.Groups[4].Value, match.Groups[5].Value));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -107,7 +56,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// <summary>
|
||||
/// Returns a dictionary mapping runtimes to their newest version.
|
||||
/// </summary>
|
||||
internal Dictionary<string, RuntimeVersion> GetNewestRuntimes()
|
||||
internal Dictionary<string, DotnetVersion> GetNewestRuntimes()
|
||||
{
|
||||
var listed = dotNet.GetListedRuntimes();
|
||||
return ParseRuntimes(listed);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Generic;
|
||||
using Semmle.Util;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal partial class Sdk
|
||||
{
|
||||
private readonly IDotNet dotNet;
|
||||
|
||||
public Sdk(IDotNet dotNet) => this.dotNet = dotNet;
|
||||
|
||||
[GeneratedRegex(@"^(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")]
|
||||
private static partial Regex SdkRegex();
|
||||
|
||||
private static HashSet<DotnetVersion> ParseSdks(IList<string> listed)
|
||||
{
|
||||
var sdks = new HashSet<DotnetVersion>();
|
||||
var regex = SdkRegex();
|
||||
listed.ForEach(r =>
|
||||
{
|
||||
var match = regex.Match(r);
|
||||
if (match.Success)
|
||||
{
|
||||
sdks.Add(new DotnetVersion(match.Groups[5].Value, match.Groups[1].Value, match.Groups[3].Value, match.Groups[4].Value));
|
||||
}
|
||||
});
|
||||
|
||||
return sdks;
|
||||
}
|
||||
|
||||
public DotnetVersion? GetNewestSdk()
|
||||
{
|
||||
var listed = dotNet.GetListedSdks();
|
||||
var sdks = ParseSdks(listed);
|
||||
return sdks.Max();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Semmle.Extraction.CSharp.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Comments
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Semmle.Extraction.CSharp.Entities;
|
||||
using Semmle.Util;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Semmle.Util;
|
||||
using Semmle.Extraction.CSharp.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Semmle.Extraction.CSharp;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Semmle.Extraction.Entities;
|
||||
using System.IO;
|
||||
using System;
|
||||
using Semmle.Extraction.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Util;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Semmle.Extraction.Entities;
|
||||
using System.IO;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.CSharp.Populators;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.CSharp.Entities.Expressions;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Semmle.Extraction.Kinds;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using Semmle.Util;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Util;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax; // lgtm[cs/similar-file]
|
||||
using System.IO; // lgtm[cs/similar-file]
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax; // lgtm[cs/similar-file]
|
||||
using System.IO; // lgtm[cs/similar-file]
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax; // lgtm[cs/similar-file]
|
||||
using System.IO; // lgtm[cs/similar-file]
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Entities;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user