mirror of
https://github.com/github/codeql.git
synced 2026-05-18 21:27:08 +02:00
Compare commits
117 Commits
calumgrant
...
js/vea-hac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a11732ef25 | ||
|
|
d0c9e3f7ad | ||
|
|
9082972842 | ||
|
|
116873c9b0 | ||
|
|
290b0fc4ab | ||
|
|
332d118d93 | ||
|
|
82bbecc9c4 | ||
|
|
13ff9412a4 | ||
|
|
9d24b5afa6 | ||
|
|
95ec4e8d26 | ||
|
|
17e0cc5648 | ||
|
|
196b6d7a1d | ||
|
|
9def57250d | ||
|
|
9af9873e04 | ||
|
|
9f5782b67b | ||
|
|
c61177cf42 | ||
|
|
4140942479 | ||
|
|
fd306ed79b | ||
|
|
8962307291 | ||
|
|
0000c72329 | ||
|
|
3ef7a0932a | ||
|
|
f29d2c21bd | ||
|
|
3b44b131b9 | ||
|
|
4a97f95890 | ||
|
|
84ea3a9a2c | ||
|
|
8f2e51faa6 | ||
|
|
f828f8ea65 | ||
|
|
95d579d9de | ||
|
|
f3daba510b | ||
|
|
88e67715a1 | ||
|
|
53eb753346 | ||
|
|
037114b336 | ||
|
|
af72c0848e | ||
|
|
a05636876b | ||
|
|
de58ee5a22 | ||
|
|
a1a93c7331 | ||
|
|
db07c162e4 | ||
|
|
9d00f660f1 | ||
|
|
0311888fd4 | ||
|
|
e4f23b31c6 | ||
|
|
57a53891e9 | ||
|
|
b6703bc25c | ||
|
|
003d208574 | ||
|
|
d8d7688f88 | ||
|
|
3592e76269 | ||
|
|
6aa4c5c187 | ||
|
|
fb8ee07b43 | ||
|
|
4ccff1a630 | ||
|
|
4b7160d4b2 | ||
|
|
5cce5008a3 | ||
|
|
5b6ce56ca2 | ||
|
|
2b81b6c323 | ||
|
|
a39d8b7c7c | ||
|
|
1bc085c8f7 | ||
|
|
bb00d6919a | ||
|
|
e0e405bb31 | ||
|
|
ce711f7d2f | ||
|
|
f20812d8ad | ||
|
|
05f3c64172 | ||
|
|
dae187eb0b | ||
|
|
7f195d0257 | ||
|
|
a8162baada | ||
|
|
ef53184c10 | ||
|
|
9d38c255f5 | ||
|
|
4de4525528 | ||
|
|
79b4890794 | ||
|
|
dc985c2c98 | ||
|
|
b6f6bdc6f4 | ||
|
|
a49b43fdf6 | ||
|
|
317c335269 | ||
|
|
db06c08141 | ||
|
|
f39301f533 | ||
|
|
a6646021d0 | ||
|
|
d967b2baa3 | ||
|
|
3ba6ddc96e | ||
|
|
a4df20da85 | ||
|
|
81eaa6e327 | ||
|
|
5fba9895c6 | ||
|
|
64321b314f | ||
|
|
7b5f2c7d94 | ||
|
|
41e666c724 | ||
|
|
88f6e04339 | ||
|
|
b560ab1a73 | ||
|
|
3626c814ac | ||
|
|
bef556e208 | ||
|
|
5a5fc79b3b | ||
|
|
9926c817de | ||
|
|
53902c824d | ||
|
|
3c5675b3fb | ||
|
|
3154a11b43 | ||
|
|
1ff4c0daf3 | ||
|
|
79fe5f851b | ||
|
|
407837afc4 | ||
|
|
f33222c83b | ||
|
|
df463e51c1 | ||
|
|
60944a9bcb | ||
|
|
1d51d182ec | ||
|
|
04a0740ccb | ||
|
|
cd84500c56 | ||
|
|
0515b12305 | ||
|
|
7b3810eb8f | ||
|
|
ae903abb4b | ||
|
|
3cd4969499 | ||
|
|
ba86c93e67 | ||
|
|
5ed2e033f1 | ||
|
|
ebb744311f | ||
|
|
91a0181cfb | ||
|
|
6ebebc131e | ||
|
|
f546383cee | ||
|
|
d9482441f0 | ||
|
|
941097b639 | ||
|
|
7ae28ceee0 | ||
|
|
5340a89107 | ||
|
|
c43856d8ea | ||
|
|
af1382a6ca | ||
|
|
dc590756b5 | ||
|
|
34b48f51de |
28
.github/workflows/buildifier.yml
vendored
Normal file
28
.github/workflows/buildifier.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Check bazel formatting
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "**.bazel"
|
||||
- "**.bzl"
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Check bazel formatting
|
||||
uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
|
||||
with:
|
||||
extra_args: >
|
||||
buildifier --all-files 2>&1 ||
|
||||
(
|
||||
echo -e "In order to format all bazel files, please run:\n bazel run //:buildifier"; exit 1
|
||||
)
|
||||
@@ -20,13 +20,15 @@ repos:
|
||||
- id: autopep8
|
||||
files: ^misc/codegen/.*\.py
|
||||
|
||||
- repo: https://github.com/warchant/pre-commit-buildifier
|
||||
rev: 0.0.2
|
||||
hooks:
|
||||
- id: buildifier
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: buildifier
|
||||
name: Format bazel files
|
||||
files: \.(bazel|bzl)
|
||||
language: system
|
||||
entry: bazel run //:buildifier
|
||||
pass_filenames: false
|
||||
|
||||
- id: codeql-format
|
||||
name: Fix QL file formatting
|
||||
files: \.qll?$
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
load("@buildifier_prebuilt//:rules.bzl", "buildifier")
|
||||
|
||||
buildifier(
|
||||
name = "buildifier",
|
||||
exclude_patterns = [
|
||||
"./.git/*",
|
||||
],
|
||||
lint_mode = "fix",
|
||||
)
|
||||
|
||||
@@ -22,6 +22,8 @@ bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl")
|
||||
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
|
||||
bazel_dep(name = "fmt", version = "10.0.0")
|
||||
|
||||
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
|
||||
|
||||
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
|
||||
pip.parse(
|
||||
hub_name = "codegen_deps",
|
||||
|
||||
@@ -362,7 +362,7 @@
|
||||
"java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll"
|
||||
],
|
||||
"Python model summaries test extension": [
|
||||
"python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
||||
"python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
||||
"python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
||||
"python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1596,12 +1596,23 @@ private Cpp::Stmt getAChainedBranch(Cpp::IfStmt s) {
|
||||
)
|
||||
}
|
||||
|
||||
private Instruction getInstruction(Node n) {
|
||||
result = n.asInstruction() or
|
||||
result = n.asOperand().getUse() or
|
||||
result = n.(SsaPhiNode).getPhiNode().getBasicBlock().getFirstInstruction() or
|
||||
n.(IndirectInstruction).hasInstructionAndIndirectionIndex(result, _) or
|
||||
result = getInstruction(n.(PostUpdateNode).getPreUpdateNode())
|
||||
private Instruction getAnInstruction(Node n) {
|
||||
result = n.asInstruction()
|
||||
or
|
||||
not n instanceof InstructionNode and
|
||||
result = n.asOperand().getUse()
|
||||
or
|
||||
result = n.(SsaPhiNode).getPhiNode().getBasicBlock().getFirstInstruction()
|
||||
or
|
||||
n.(IndirectInstruction).hasInstructionAndIndirectionIndex(result, _)
|
||||
or
|
||||
not n instanceof IndirectInstruction and
|
||||
exists(Operand operand |
|
||||
n.(IndirectOperand).hasOperandAndIndirectionIndex(operand, _) and
|
||||
result = operand.getUse()
|
||||
)
|
||||
or
|
||||
result = getAnInstruction(n.(PostUpdateNode).getPreUpdateNode())
|
||||
}
|
||||
|
||||
private newtype TDataFlowSecondLevelScope =
|
||||
@@ -1647,7 +1658,7 @@ class DataFlowSecondLevelScope extends TDataFlowSecondLevelScope {
|
||||
|
||||
/** Gets a data-flow node nested within this scope. */
|
||||
Node getANode() {
|
||||
getInstruction(result).getAst().(Cpp::ControlFlowNode).getEnclosingStmt().getParentStmt*() =
|
||||
getAnInstruction(result).getAst().(Cpp::ControlFlowNode).getEnclosingStmt().getParentStmt*() =
|
||||
this.getAStmt()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import cpp
|
||||
|
||||
class StringVariable extends Variable {
|
||||
StringVariable() {
|
||||
this.getType().(PointerType).stripType().getName() = "char"
|
||||
}
|
||||
}
|
||||
|
||||
class StringField extends StringVariable, Field
|
||||
{
|
||||
}
|
||||
|
||||
class StringParameter extends StringVariable, Parameter
|
||||
{
|
||||
}
|
||||
|
||||
from StringVariable f
|
||||
where f.getFile().getRelativePath().matches("c/extractor/src/%")
|
||||
and not f.getASpecifier().getName() = "extern"
|
||||
select f, f.getFile().getRelativePath()
|
||||
@@ -1,9 +0,0 @@
|
||||
import cpp
|
||||
import relevant
|
||||
|
||||
from Function fn
|
||||
where
|
||||
fn.getNamespace() instanceof GlobalNamespace and
|
||||
not exists(fn.getDeclaringType()) and
|
||||
is_relevant_result(fn.getFile())
|
||||
select fn, "This function is not declared in a namespace", fn.getFile().getRelativePath()
|
||||
@@ -1,4 +0,0 @@
|
||||
import cpp
|
||||
|
||||
from Function fn
|
||||
where not exists(fn.getDeclaringType()) and is_relevant_result(fn.getFile())
|
||||
@@ -1,25 +0,0 @@
|
||||
// Flags use of global variables
|
||||
import cpp
|
||||
|
||||
class RelevantGlobalVariable extends GlobalVariable
|
||||
{
|
||||
RelevantGlobalVariable() {
|
||||
any()
|
||||
}
|
||||
}
|
||||
|
||||
predicate is_valid_global_variable(Variable var) {
|
||||
var.getType().stripType().getName() = "trie_node" or
|
||||
var.getType().isConst() or
|
||||
var.getType().isDeeplyConst() or
|
||||
var.isConstexpr() or
|
||||
var.getType() instanceof ArrayType or
|
||||
var.getASpecifier().getName() = "extern" or
|
||||
var.getFile().getRelativePath().matches("c/extractor/edg/%")
|
||||
}
|
||||
|
||||
from GlobalVariable globalVariable, string typeName
|
||||
where
|
||||
not is_valid_global_variable(globalVariable) and
|
||||
typeName = globalVariable.getType().stripType().getName()
|
||||
select globalVariable, typeName, globalVariable.getFile().getRelativePath()
|
||||
@@ -1,7 +0,0 @@
|
||||
import cpp
|
||||
import relevant
|
||||
|
||||
from Call call
|
||||
where call.getTarget().getName().matches("%printf")
|
||||
and is_relevant_result(call.getFile())
|
||||
select call, "Call to a printf formatter", call.getFile().getRelativePath()
|
||||
@@ -1,6 +0,0 @@
|
||||
import cpp
|
||||
|
||||
predicate is_relevant_result(File file)
|
||||
{
|
||||
not file.getRelativePath().matches("c/extractor/edg%")
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import cpp
|
||||
|
||||
class ACompressedFileWrite extends Function {
|
||||
ACompressedFileWrite() {
|
||||
this.getName() = "operator<<" and
|
||||
this.getParameter(0).getType().stripType().getName() = "a_compressed_file"
|
||||
}
|
||||
}
|
||||
|
||||
class LabelDefinition extends Call {
|
||||
LabelDefinition() {
|
||||
this.getTarget() instanceof ACompressedFileWrite and
|
||||
this.getArgument(1).(StringLiteral).getValue().matches("=%")
|
||||
}
|
||||
}
|
||||
|
||||
predicate is_valid_file_write(Call call) {
|
||||
call.getFile().getBaseName() = "dbscheme.cpp"
|
||||
}
|
||||
|
||||
from Call call
|
||||
where
|
||||
call.getTarget() instanceof ACompressedFileWrite
|
||||
and not is_valid_file_write(call)
|
||||
select call
|
||||
@@ -2432,7 +2432,7 @@ void initialization_with_temp_destructor() {
|
||||
}
|
||||
|
||||
void param_with_destructor_by_value(ClassWithDestructor c) {
|
||||
// The call to ~ClassWithDestructor::ClassWithDestructor() seems to be missing here.
|
||||
// The call to ~ClassWithDestructor::ClassWithDestructor() happens on the side of the caller
|
||||
}
|
||||
|
||||
void param_with_destructor_by_pointer(ClassWithDestructor* c) {
|
||||
|
||||
@@ -12,6 +12,22 @@ edges
|
||||
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a | provenance | |
|
||||
| test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a | provenance | |
|
||||
| test_free.cpp:301:12:301:14 | pointer to g_free output argument | test_free.cpp:302:12:302:14 | buf | provenance | |
|
||||
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:322:12:322:12 | a | provenance | |
|
||||
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | test_free.cpp:344:12:344:24 | *access to array [ptr] | provenance | |
|
||||
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | test_free.cpp:345:12:345:24 | *access to array [ptr] | provenance | |
|
||||
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | test_free.cpp:346:12:346:24 | *access to array [ptr] | provenance | |
|
||||
| test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | provenance | |
|
||||
| test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | test_free.cpp:345:12:345:24 | *access to array [ptr] | provenance | |
|
||||
| test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | test_free.cpp:346:12:346:24 | *access to array [ptr] | provenance | |
|
||||
| test_free.cpp:344:12:344:24 | *access to array [ptr] | test_free.cpp:344:26:344:28 | ptr | provenance | |
|
||||
| test_free.cpp:344:26:344:28 | pointer to operator delete output argument | test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | provenance | |
|
||||
| test_free.cpp:345:12:345:24 | *access to array [post update] [ptr] | test_free.cpp:346:12:346:24 | *access to array [ptr] | provenance | |
|
||||
| test_free.cpp:345:12:345:24 | *access to array [ptr] | test_free.cpp:345:26:345:28 | ptr | provenance | |
|
||||
| test_free.cpp:345:12:345:24 | *access to array [ptr] | test_free.cpp:345:26:345:28 | ptr | provenance | |
|
||||
| test_free.cpp:345:26:345:28 | pointer to operator delete output argument | test_free.cpp:345:12:345:24 | *access to array [post update] [ptr] | provenance | |
|
||||
| test_free.cpp:346:12:346:24 | *access to array [ptr] | test_free.cpp:346:26:346:28 | ptr | provenance | |
|
||||
| test_free.cpp:346:12:346:24 | *access to array [ptr] | test_free.cpp:346:26:346:28 | ptr | provenance | |
|
||||
| test_free.cpp:346:12:346:24 | *access to array [ptr] | test_free.cpp:346:26:346:28 | ptr | provenance | |
|
||||
nodes
|
||||
| test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test_free.cpp:14:10:14:10 | a | semmle.label | a |
|
||||
@@ -39,6 +55,26 @@ nodes
|
||||
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
|
||||
| test_free.cpp:301:12:301:14 | pointer to g_free output argument | semmle.label | pointer to g_free output argument |
|
||||
| test_free.cpp:302:12:302:14 | buf | semmle.label | buf |
|
||||
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:322:12:322:12 | a | semmle.label | a |
|
||||
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | semmle.label | *access to array [post update] [ptr] |
|
||||
| test_free.cpp:343:26:343:28 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | semmle.label | *access to array [post update] [ptr] |
|
||||
| test_free.cpp:344:12:344:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
|
||||
| test_free.cpp:344:26:344:28 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:344:26:344:28 | ptr | semmle.label | ptr |
|
||||
| test_free.cpp:345:12:345:24 | *access to array [post update] [ptr] | semmle.label | *access to array [post update] [ptr] |
|
||||
| test_free.cpp:345:12:345:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
|
||||
| test_free.cpp:345:12:345:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
|
||||
| test_free.cpp:345:26:345:28 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:345:26:345:28 | ptr | semmle.label | ptr |
|
||||
| test_free.cpp:345:26:345:28 | ptr | semmle.label | ptr |
|
||||
| test_free.cpp:346:12:346:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
|
||||
| test_free.cpp:346:12:346:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
|
||||
| test_free.cpp:346:12:346:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
|
||||
| test_free.cpp:346:26:346:28 | ptr | semmle.label | ptr |
|
||||
| test_free.cpp:346:26:346:28 | ptr | semmle.label | ptr |
|
||||
| test_free.cpp:346:26:346:28 | ptr | semmle.label | ptr |
|
||||
subpaths
|
||||
#select
|
||||
| test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:14:10:14:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:14:10:14:10 | a | a | test_free.cpp:11:5:11:8 | call to free | call to free |
|
||||
@@ -54,3 +90,10 @@ subpaths
|
||||
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:154:10:154:10 | a | a | test_free.cpp:152:22:152:25 | call to free | call to free |
|
||||
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:209:10:209:10 | a | a | test_free.cpp:207:5:207:8 | call to free | call to free |
|
||||
| test_free.cpp:302:12:302:14 | buf | test_free.cpp:301:12:301:14 | pointer to g_free output argument | test_free.cpp:302:12:302:14 | buf | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:302:12:302:14 | buf | buf | test_free.cpp:301:5:301:10 | call to g_free | call to g_free |
|
||||
| test_free.cpp:322:12:322:12 | a | test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:322:12:322:12 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:322:12:322:12 | a | a | test_free.cpp:319:9:319:16 | delete | delete |
|
||||
| test_free.cpp:344:26:344:28 | ptr | test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:344:26:344:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:344:26:344:28 | ptr | ptr | test_free.cpp:343:5:343:28 | delete | delete |
|
||||
| test_free.cpp:345:26:345:28 | ptr | test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:345:26:345:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:345:26:345:28 | ptr | ptr | test_free.cpp:343:5:343:28 | delete | delete |
|
||||
| test_free.cpp:345:26:345:28 | ptr | test_free.cpp:344:26:344:28 | pointer to operator delete output argument | test_free.cpp:345:26:345:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:345:26:345:28 | ptr | ptr | test_free.cpp:344:5:344:28 | delete | delete |
|
||||
| test_free.cpp:346:26:346:28 | ptr | test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:346:26:346:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:346:26:346:28 | ptr | ptr | test_free.cpp:343:5:343:28 | delete | delete |
|
||||
| test_free.cpp:346:26:346:28 | ptr | test_free.cpp:344:26:344:28 | pointer to operator delete output argument | test_free.cpp:346:26:346:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:346:26:346:28 | ptr | ptr | test_free.cpp:344:5:344:28 | delete | delete |
|
||||
| test_free.cpp:346:26:346:28 | ptr | test_free.cpp:345:26:345:28 | pointer to operator delete output argument | test_free.cpp:346:26:346:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:346:26:346:28 | ptr | ptr | test_free.cpp:345:5:345:28 | delete | delete |
|
||||
|
||||
@@ -104,6 +104,15 @@
|
||||
| test_free.cpp:293:8:293:10 | buf |
|
||||
| test_free.cpp:301:12:301:14 | buf |
|
||||
| test_free.cpp:302:12:302:14 | buf |
|
||||
| test_free.cpp:313:16:313:16 | a |
|
||||
| test_free.cpp:319:16:319:16 | a |
|
||||
| test_free.cpp:322:12:322:12 | a |
|
||||
| test_free.cpp:331:12:331:12 | a |
|
||||
| test_free.cpp:335:12:335:12 | a |
|
||||
| test_free.cpp:343:26:343:28 | ptr |
|
||||
| test_free.cpp:344:26:344:28 | ptr |
|
||||
| test_free.cpp:345:26:345:28 | ptr |
|
||||
| test_free.cpp:346:26:346:28 | ptr |
|
||||
| virtual.cpp:18:10:18:10 | a |
|
||||
| virtual.cpp:19:10:19:10 | c |
|
||||
| virtual.cpp:38:10:38:10 | b |
|
||||
|
||||
@@ -25,6 +25,11 @@ edges
|
||||
| test_free.cpp:294:3:294:3 | *s [post update] [buf] | test_free.cpp:295:12:295:12 | *s [buf] | provenance | |
|
||||
| test_free.cpp:294:3:294:13 | ... = ... | test_free.cpp:294:3:294:3 | *s [post update] [buf] | provenance | |
|
||||
| test_free.cpp:295:12:295:12 | *s [buf] | test_free.cpp:295:14:295:16 | buf | provenance | |
|
||||
| test_free.cpp:313:16:313:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | |
|
||||
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:321:5:321:6 | * ... | provenance | |
|
||||
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | |
|
||||
| test_free.cpp:322:12:322:12 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | |
|
||||
| test_free.cpp:331:12:331:12 | pointer to operator delete output argument | test_free.cpp:332:5:332:6 | * ... | provenance | |
|
||||
nodes
|
||||
| test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test_free.cpp:12:5:12:5 | a | semmle.label | a |
|
||||
@@ -66,6 +71,15 @@ nodes
|
||||
| test_free.cpp:294:3:294:13 | ... = ... | semmle.label | ... = ... |
|
||||
| test_free.cpp:295:12:295:12 | *s [buf] | semmle.label | *s [buf] |
|
||||
| test_free.cpp:295:14:295:16 | buf | semmle.label | buf |
|
||||
| test_free.cpp:313:16:313:16 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:321:5:321:6 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:322:12:322:12 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:324:5:324:6 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:324:5:324:6 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:324:5:324:6 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:331:12:331:12 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
|
||||
| test_free.cpp:332:5:332:6 | * ... | semmle.label | * ... |
|
||||
subpaths
|
||||
#select
|
||||
| test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
|
||||
@@ -84,3 +98,8 @@ subpaths
|
||||
| test_free.cpp:278:15:278:17 | buf | test_free.cpp:277:8:277:13 | pointer to free output argument | test_free.cpp:278:15:278:17 | buf | Memory may have been previously freed by $@. | test_free.cpp:277:3:277:6 | call to free | call to free |
|
||||
| test_free.cpp:283:14:283:16 | buf | test_free.cpp:282:8:282:12 | pointer to free output argument | test_free.cpp:283:14:283:16 | buf | Memory may have been previously freed by $@. | test_free.cpp:282:3:282:6 | call to free | call to free |
|
||||
| test_free.cpp:295:14:295:16 | buf | test_free.cpp:293:8:293:10 | pointer to free output argument | test_free.cpp:295:14:295:16 | buf | Memory may have been previously freed by $@. | test_free.cpp:293:3:293:6 | call to free | call to free |
|
||||
| test_free.cpp:321:5:321:6 | * ... | test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:321:5:321:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:319:9:319:16 | delete | delete |
|
||||
| test_free.cpp:324:5:324:6 | * ... | test_free.cpp:313:16:313:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:313:9:313:16 | delete | delete |
|
||||
| test_free.cpp:324:5:324:6 | * ... | test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:319:9:319:16 | delete | delete |
|
||||
| test_free.cpp:324:5:324:6 | * ... | test_free.cpp:322:12:322:12 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:322:5:322:12 | delete | delete |
|
||||
| test_free.cpp:332:5:332:6 | * ... | test_free.cpp:331:12:331:12 | pointer to operator delete output argument | test_free.cpp:332:5:332:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:331:5:331:12 | delete | delete |
|
||||
|
||||
@@ -264,9 +264,9 @@ void test_ref_delete(int *&p) {
|
||||
}
|
||||
|
||||
void test_free_assign() {
|
||||
void *a = malloc(10);
|
||||
void *a = malloc(10);
|
||||
void *b;
|
||||
free(b = a); // GOOD
|
||||
free(b = a); // GOOD
|
||||
}
|
||||
|
||||
struct MyStruct {
|
||||
@@ -300,4 +300,48 @@ void g_free (void*);
|
||||
void test_g_free(char* buf) {
|
||||
g_free(buf);
|
||||
g_free(buf); // BAD
|
||||
}
|
||||
}
|
||||
|
||||
// inspired by real world FPs
|
||||
|
||||
void test_goto() {
|
||||
int *a = (int *)malloc(sizeof(int));
|
||||
|
||||
*a = 1; // GOOD
|
||||
if (condition())
|
||||
{
|
||||
delete a;
|
||||
goto after;
|
||||
}
|
||||
*a = 1; // GOOD
|
||||
if (condition())
|
||||
{
|
||||
delete a;
|
||||
}
|
||||
*a = 1; // BAD (use after free)
|
||||
delete a; // BAD (double free)
|
||||
after:
|
||||
*a = 1; // BAD (use after free)
|
||||
}
|
||||
|
||||
void test_reassign() {
|
||||
int *a = (int *)malloc(sizeof(int));
|
||||
|
||||
*a = 1; // GOOD
|
||||
delete a;
|
||||
*a = 1; // BAD (use after free)
|
||||
a = (int *)malloc(sizeof(int));
|
||||
*a = 1; // GOOD
|
||||
delete a;
|
||||
}
|
||||
|
||||
struct PtrContainer {
|
||||
int *ptr;
|
||||
};
|
||||
|
||||
void test_array(PtrContainer *containers) {
|
||||
delete containers[0].ptr; // GOOD
|
||||
delete containers[1].ptr; // GOOD [FALSE POSITIVE]
|
||||
delete containers[2].ptr; // GOOD [FALSE POSITIVE]
|
||||
delete containers[2].ptr; // BAD (double free)
|
||||
}
|
||||
|
||||
@@ -152,7 +152,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var sourceGenerators = new ISourceGenerator[]
|
||||
{
|
||||
new ImplicitUsingsGenerator(fileContent, logger, tempWorkingDirectory),
|
||||
new WebViewGenerator(fileProvider, fileContent, dotnet, this, logger, tempWorkingDirectory, usedReferences.Keys)
|
||||
new RazorGenerator(fileProvider, fileContent, dotnet, this, logger, tempWorkingDirectory, usedReferences.Keys),
|
||||
new ResxGenerator(fileProvider, fileContent, dotnet, this, logger, nugetPackageRestorer, tempWorkingDirectory, usedReferences.Keys),
|
||||
};
|
||||
|
||||
foreach (var sourceGenerator in sourceGenerators)
|
||||
@@ -255,35 +256,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectNewestFrameworkPath(string frameworkPath, string frameworkType, ISet<AssemblyLookupLocation> dllLocations, ISet<string> frameworkLocations)
|
||||
{
|
||||
var versionFolders = GetPackageVersionSubDirectories(frameworkPath);
|
||||
if (versionFolders.Length > 1)
|
||||
{
|
||||
var versions = string.Join(", ", versionFolders.Select(d => d.Name));
|
||||
logger.LogDebug($"Found multiple {frameworkType} DLLs in NuGet packages at {frameworkPath}. Using the latest version ({versionFolders[0].Name}) from: {versions}.");
|
||||
}
|
||||
|
||||
var selectedFrameworkFolder = versionFolders.FirstOrDefault()?.FullName;
|
||||
if (selectedFrameworkFolder is null)
|
||||
{
|
||||
logger.LogDebug($"Found {frameworkType} DLLs in NuGet packages at {frameworkPath}, but no version folder was found.");
|
||||
selectedFrameworkFolder = frameworkPath;
|
||||
}
|
||||
|
||||
dllLocations.Add(selectedFrameworkFolder);
|
||||
frameworkLocations.Add(selectedFrameworkFolder);
|
||||
logger.LogDebug($"Found {frameworkType} DLLs in NuGet packages at {selectedFrameworkFolder}.");
|
||||
}
|
||||
|
||||
private static DirectoryInfo[] GetPackageVersionSubDirectories(string packagePath)
|
||||
{
|
||||
return new DirectoryInfo(packagePath)
|
||||
.EnumerateDirectories("*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
|
||||
.OrderByDescending(d => d.Name) // TODO: Improve sorting to handle pre-release versions.
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private void RemoveFrameworkNugetPackages(ISet<AssemblyLookupLocation> dllLocations, int fromIndex = 0)
|
||||
{
|
||||
var packagesInPrioOrder = FrameworkPackageNames.NetFrameworks;
|
||||
@@ -310,10 +282,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
foreach (var fp in frameworkPaths)
|
||||
{
|
||||
dotnetFrameworkVersionVariantCount += GetPackageVersionSubDirectories(fp.Path!).Length;
|
||||
dotnetFrameworkVersionVariantCount += NugetPackageRestorer.GetOrderedPackageVersionSubDirectories(fp.Path!).Length;
|
||||
}
|
||||
|
||||
SelectNewestFrameworkPath(frameworkPath.Path, ".NET Framework", dllLocations, frameworkLocations);
|
||||
var folder = nugetPackageRestorer.GetNewestNugetPackageVersionFolder(frameworkPath.Path, ".NET Framework");
|
||||
dllLocations.Add(folder);
|
||||
frameworkLocations.Add(folder);
|
||||
RemoveFrameworkNugetPackages(dllLocations, frameworkPath.Index + 1);
|
||||
return;
|
||||
}
|
||||
@@ -331,7 +305,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
if (runtimeLocation is null)
|
||||
{
|
||||
logger.LogInfo("No .NET Desktop Runtime location found. Attempting to restore the .NET Framework reference assemblies manually.");
|
||||
runtimeLocation = nugetPackageRestorer.TryRestoreLatestNetFrameworkReferenceAssemblies();
|
||||
runtimeLocation = nugetPackageRestorer.TryRestore(FrameworkPackageNames.LatestNetFrameworkReferenceAssemblies);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +345,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
// First try to find ASP.NET Core assemblies in the NuGet packages
|
||||
if (GetPackageDirectory(FrameworkPackageNames.AspNetCoreFramework) is string aspNetCorePackage)
|
||||
{
|
||||
SelectNewestFrameworkPath(aspNetCorePackage, "ASP.NET Core", dllLocations, frameworkLocations);
|
||||
var folder = nugetPackageRestorer.GetNewestNugetPackageVersionFolder(aspNetCorePackage, "ASP.NET Core");
|
||||
dllLocations.Add(folder);
|
||||
frameworkLocations.Add(folder);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -387,7 +363,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
if (GetPackageDirectory(FrameworkPackageNames.WindowsDesktopFramework) is string windowsDesktopApp)
|
||||
{
|
||||
SelectNewestFrameworkPath(windowsDesktopApp, "Windows Desktop App", dllLocations, frameworkLocations);
|
||||
var folder = nugetPackageRestorer.GetNewestNugetPackageVersionFolder(windowsDesktopApp, "Windows Desktop App");
|
||||
dllLocations.Add(folder);
|
||||
frameworkLocations.Add(folder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
// See https://docs.microsoft.com/en-us/dotnet/core/tools/global-json
|
||||
var versions = new List<string>();
|
||||
|
||||
foreach (var path in files.Where(p => p.EndsWith("global.json", StringComparison.Ordinal)))
|
||||
foreach (var path in files.Where(p => string.Equals(FileUtils.SafeGetFileName(p, logger), "global.json", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -2,6 +2,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal class EnvironmentVariableNames
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls whether to generate source files from resources (`.resx`).
|
||||
/// </summary>
|
||||
public const string ResourceGeneration = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_EXTRACT_RESOURCES";
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether to generate source files from Asp.Net Core views (`.cshtml`, `.razor`).
|
||||
/// </summary>
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
try
|
||||
{
|
||||
var isPackagesConfig = file.EndsWith("packages.config", StringComparison.OrdinalIgnoreCase);
|
||||
var isPackagesConfig = string.Equals(FileUtils.SafeGetFileName(file, logger), "packages.config", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
foreach (ReadOnlySpan<char> line in unsafeFileReader.ReadLines(file))
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private readonly Lazy<string[]> nugetConfigs;
|
||||
private readonly Lazy<string[]> globalJsons;
|
||||
private readonly Lazy<string[]> razorViews;
|
||||
private readonly Lazy<string[]> resources;
|
||||
private readonly Lazy<string?> rootNugetConfig;
|
||||
|
||||
public FileProvider(DirectoryInfo sourceDir, ILogger logger)
|
||||
@@ -44,6 +45,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
nugetConfigs = new Lazy<string[]>(() => allNonBinary.Value.SelectFileNamesByName("nuget.config").ToArray());
|
||||
globalJsons = new Lazy<string[]>(() => allNonBinary.Value.SelectFileNamesByName("global.json").ToArray());
|
||||
razorViews = new Lazy<string[]>(() => SelectTextFileNamesByExtension("razor view", ".cshtml", ".razor"));
|
||||
resources = new Lazy<string[]>(() => SelectTextFileNamesByExtension("resource", ".resx"));
|
||||
|
||||
rootNugetConfig = new Lazy<string?>(() => all.SelectRootFiles(SourceDir).SelectFileNamesByName("nuget.config").FirstOrDefault());
|
||||
}
|
||||
@@ -116,5 +118,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
public string? RootNugetConfig => rootNugetConfig.Value;
|
||||
public IEnumerable<string> GlobalJsons => globalJsons.Value;
|
||||
public ICollection<string> RazorViews => razorViews.Value;
|
||||
public ICollection<string> Resources => resources.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private readonly Lazy<bool> hasNugetPackageSourceError = new(() => Output.Any(s => s.Contains("NU1301")));
|
||||
public bool HasNugetPackageSourceError => hasNugetPackageSourceError.Value;
|
||||
|
||||
private readonly Lazy<bool> hasNugetNoStablePackageVersionError = new(() => Output.Any(s => s.Contains("NU1103")));
|
||||
public bool HasNugetNoStablePackageVersionError => hasNugetNoStablePackageVersionError.Value;
|
||||
|
||||
private static IEnumerable<string> GetFirstGroupOnMatch(Regex regex, IEnumerable<string> lines) =>
|
||||
lines
|
||||
.Select(line => regex.Match(line))
|
||||
|
||||
@@ -48,16 +48,48 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath(fileProvider.SourceDir.FullName, "missingpackages"), "missing package", logger);
|
||||
}
|
||||
|
||||
public string? TryRestoreLatestNetFrameworkReferenceAssemblies()
|
||||
public string? TryRestore(string package)
|
||||
{
|
||||
if (TryRestorePackageManually(FrameworkPackageNames.LatestNetFrameworkReferenceAssemblies))
|
||||
if (TryRestorePackageManually(package))
|
||||
{
|
||||
return DependencyManager.GetPackageDirectory(FrameworkPackageNames.LatestNetFrameworkReferenceAssemblies, missingPackageDirectory.DirInfo);
|
||||
var packageDir = DependencyManager.GetPackageDirectory(package, missingPackageDirectory.DirInfo);
|
||||
if (packageDir is not null)
|
||||
{
|
||||
return GetNewestNugetPackageVersionFolder(packageDir, package);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetNewestNugetPackageVersionFolder(string packagePath, string packageFriendlyName)
|
||||
{
|
||||
var versionFolders = GetOrderedPackageVersionSubDirectories(packagePath);
|
||||
if (versionFolders.Length > 1)
|
||||
{
|
||||
var versions = string.Join(", ", versionFolders.Select(d => d.Name));
|
||||
logger.LogDebug($"Found multiple {packageFriendlyName} DLLs in NuGet packages at {packagePath}. Using the latest version ({versionFolders[0].Name}) from: {versions}.");
|
||||
}
|
||||
|
||||
var selectedFrameworkFolder = versionFolders.FirstOrDefault()?.FullName;
|
||||
if (selectedFrameworkFolder is null)
|
||||
{
|
||||
logger.LogDebug($"Found {packageFriendlyName} DLLs in NuGet packages at {packagePath}, but no version folder was found.");
|
||||
selectedFrameworkFolder = packagePath;
|
||||
}
|
||||
|
||||
logger.LogDebug($"Found {packageFriendlyName} DLLs in NuGet packages at {selectedFrameworkFolder}.");
|
||||
return selectedFrameworkFolder;
|
||||
}
|
||||
|
||||
public static DirectoryInfo[] GetOrderedPackageVersionSubDirectories(string packagePath)
|
||||
{
|
||||
return new DirectoryInfo(packagePath)
|
||||
.EnumerateDirectories("*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
|
||||
.OrderByDescending(d => d.Name) // TODO: Improve sorting to handle pre-release versions.
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public HashSet<AssemblyLookupLocation> Restore()
|
||||
{
|
||||
var assemblyLookupLocations = new HashSet<AssemblyLookupLocation>();
|
||||
@@ -408,7 +440,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
.Select(d => Path.GetFileName(d).ToLowerInvariant());
|
||||
}
|
||||
|
||||
private bool TryRestorePackageManually(string package, string? nugetConfig = null, PackageReferenceSource packageReferenceSource = PackageReferenceSource.SdkCsProj, bool tryWithoutNugetConfig = true)
|
||||
private bool TryRestorePackageManually(string package, string? nugetConfig = null, PackageReferenceSource packageReferenceSource = PackageReferenceSource.SdkCsProj,
|
||||
bool tryWithoutNugetConfig = true, bool tryPrereleaseVersion = true)
|
||||
{
|
||||
logger.LogInfo($"Restoring package {package}...");
|
||||
using var tempDir = new TemporaryDirectory(
|
||||
@@ -430,59 +463,87 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return false;
|
||||
}
|
||||
|
||||
var res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: nugetConfig));
|
||||
if (!res.Success)
|
||||
var res = TryRestorePackageManually(package, nugetConfig, tempDir, tryPrereleaseVersion);
|
||||
if (res.Success)
|
||||
{
|
||||
if (tryWithoutNugetConfig && res.HasNugetPackageSourceError && nugetConfig is not null)
|
||||
{
|
||||
// Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
|
||||
res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: null, ForceReevaluation: true));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: the restore might fail, we could retry with
|
||||
// - a prerelease (*-* instead of *) version of the package,
|
||||
// - a different target framework moniker.
|
||||
|
||||
if (!res.Success)
|
||||
if (tryWithoutNugetConfig && res.HasNugetPackageSourceError && nugetConfig is not null)
|
||||
{
|
||||
logger.LogDebug($"Trying to restore '{package}' without nuget.config.");
|
||||
// Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
|
||||
res = TryRestorePackageManually(package, nugetConfig: null, tempDir, tryPrereleaseVersion);
|
||||
if (res.Success)
|
||||
{
|
||||
logger.LogInfo($"Failed to restore nuget package {package}");
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
logger.LogInfo($"Failed to restore nuget package {package}");
|
||||
return false;
|
||||
}
|
||||
|
||||
private RestoreResult TryRestorePackageManually(string package, string? nugetConfig, TemporaryDirectory tempDir, bool tryPrereleaseVersion)
|
||||
{
|
||||
var res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: nugetConfig, ForceReevaluation: true));
|
||||
|
||||
if (!res.Success && tryPrereleaseVersion && res.HasNugetNoStablePackageVersionError)
|
||||
{
|
||||
logger.LogDebug($"Failed to restore nuget package {package} because no stable version was found.");
|
||||
TryChangePackageVersion(tempDir.DirInfo, "*-*");
|
||||
|
||||
res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: nugetConfig, ForceReevaluation: true));
|
||||
if (!res.Success)
|
||||
{
|
||||
TryChangePackageVersion(tempDir.DirInfo, "*");
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private void TryChangeTargetFrameworkMoniker(DirectoryInfo tempDir)
|
||||
{
|
||||
TryChangeProjectFile(tempDir, TargetFramework(), $"<TargetFramework>{FrameworkPackageNames.LatestNetFrameworkMoniker}</TargetFramework>", "target framework moniker");
|
||||
}
|
||||
|
||||
private void TryChangePackageVersion(DirectoryInfo tempDir, string newVersion)
|
||||
{
|
||||
TryChangeProjectFile(tempDir, PackageReferenceVersion(), $"Version=\"{newVersion}\"", "package reference version");
|
||||
}
|
||||
|
||||
private bool TryChangeProjectFile(DirectoryInfo projectDir, Regex pattern, string replacement, string patternName)
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.LogInfo($"Changing the target framework moniker in {tempDir.FullName}...");
|
||||
logger.LogDebug($"Changing the {patternName} in {projectDir.FullName}...");
|
||||
|
||||
var csprojs = tempDir.GetFiles("*.csproj", new EnumerationOptions { RecurseSubdirectories = false, MatchCasing = MatchCasing.CaseInsensitive });
|
||||
var csprojs = projectDir.GetFiles("*.csproj", new EnumerationOptions { RecurseSubdirectories = false, MatchCasing = MatchCasing.CaseInsensitive });
|
||||
if (csprojs.Length != 1)
|
||||
{
|
||||
logger.LogError($"Could not find the .csproj file in {tempDir.FullName}, count = {csprojs.Length}");
|
||||
return;
|
||||
logger.LogError($"Could not find the .csproj file in {projectDir.FullName}, count = {csprojs.Length}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var csproj = csprojs[0];
|
||||
var content = File.ReadAllText(csproj.FullName);
|
||||
var matches = TargetFramework().Matches(content);
|
||||
var matches = pattern.Matches(content);
|
||||
if (matches.Count == 0)
|
||||
{
|
||||
logger.LogError($"Could not find target framework in {csproj.FullName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
content = TargetFramework().Replace(content, $"<TargetFramework>{FrameworkPackageNames.LatestNetFrameworkMoniker}</TargetFramework>", 1);
|
||||
File.WriteAllText(csproj.FullName, content);
|
||||
logger.LogError($"Could not find the {patternName} in {csproj.FullName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
content = pattern.Replace(content, replacement, 1);
|
||||
File.WriteAllText(csproj.FullName, content);
|
||||
return true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError($"Failed to update target framework in {tempDir.FullName}: {exc}");
|
||||
logger.LogError($"Failed to change the {patternName} in {projectDir.FullName}: {exc}");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static async Task ExecuteGetRequest(string address, HttpClient httpClient, CancellationToken cancellationToken)
|
||||
@@ -664,6 +725,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
[GeneratedRegex(@"<TargetFramework>.*</TargetFramework>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||
private static partial Regex TargetFramework();
|
||||
|
||||
[GeneratedRegex(@"Version=""(\*|\*-\*)""", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||
private static partial Regex PackageReferenceVersion();
|
||||
|
||||
[GeneratedRegex(@"^(.+)\.(\d+\.\d+\.\d+(-(.+))?)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||
private static partial Regex LegacyNugetPackage();
|
||||
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using Semmle.Util;
|
||||
using System.Text.RegularExpressions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal partial class Sdk
|
||||
{
|
||||
private readonly IDotNet dotNet;
|
||||
private readonly ILogger logger;
|
||||
private readonly Lazy<string?> cscPath;
|
||||
public string? CscPath => cscPath.Value;
|
||||
|
||||
public Sdk(IDotNet dotNet) => this.dotNet = dotNet;
|
||||
private readonly Lazy<DotNetVersion?> newestSdkVersion;
|
||||
public DotNetVersion? Version => newestSdkVersion.Value;
|
||||
|
||||
public Sdk(IDotNet dotNet, ILogger logger)
|
||||
{
|
||||
this.dotNet = dotNet;
|
||||
this.logger = logger;
|
||||
|
||||
newestSdkVersion = new Lazy<DotNetVersion?>(GetNewestSdkVersion);
|
||||
cscPath = new Lazy<string?>(GetCscPath);
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")]
|
||||
private static partial Regex SdkRegex();
|
||||
@@ -30,11 +46,31 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return sdks;
|
||||
}
|
||||
|
||||
public DotNetVersion? GetNewestSdk()
|
||||
private DotNetVersion? GetNewestSdkVersion()
|
||||
{
|
||||
var listed = dotNet.GetListedSdks();
|
||||
var sdks = ParseSdks(listed);
|
||||
return sdks.Max();
|
||||
}
|
||||
|
||||
private string? GetCscPath()
|
||||
{
|
||||
var version = Version;
|
||||
if (version is null)
|
||||
{
|
||||
logger.LogWarning("No dotnet SDK found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var path = Path.Combine(version.FullPath, "Roslyn", "bincore", "csc.dll");
|
||||
logger.LogDebug($"Source generator CSC: '{path}'");
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
logger.LogWarning($"csc.dll not found at '{path}'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal abstract class DotnetSourceGeneratorBase<T> : SourceGeneratorBase where T : DotnetSourceGeneratorWrapper
|
||||
{
|
||||
protected readonly FileProvider fileProvider;
|
||||
protected readonly FileContent fileContent;
|
||||
protected readonly IDotNet dotnet;
|
||||
protected readonly ICompilationInfoContainer compilationInfoContainer;
|
||||
protected readonly IEnumerable<string> references;
|
||||
|
||||
public DotnetSourceGeneratorBase(
|
||||
FileProvider fileProvider,
|
||||
FileContent fileContent,
|
||||
IDotNet dotnet,
|
||||
ICompilationInfoContainer compilationInfoContainer,
|
||||
ILogger logger,
|
||||
TemporaryDirectory tempWorkingDirectory,
|
||||
IEnumerable<string> references) : base(logger, tempWorkingDirectory)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.fileContent = fileContent;
|
||||
this.dotnet = dotnet;
|
||||
this.compilationInfoContainer = compilationInfoContainer;
|
||||
this.references = references;
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> Run()
|
||||
{
|
||||
if (AdditionalFiles.Count == 0)
|
||||
{
|
||||
logger.LogDebug($"No {FileType} files found. Skipping source generation.");
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!fileContent.IsNewProjectStructureUsed)
|
||||
{
|
||||
logger.LogInfo($"Generating source files from {FileType} files is only supported for new (SDK-style) project files");
|
||||
return [];
|
||||
}
|
||||
|
||||
if (fileProvider.Projects.Count == 0)
|
||||
{
|
||||
logger.LogInfo($"No projects found. Skipping source generation from {FileType} files.");
|
||||
return [];
|
||||
}
|
||||
|
||||
logger.LogInfo($"Generating source files from {AdditionalFiles.Count} {FileType} files...");
|
||||
|
||||
// group additional files by closes project file:
|
||||
var projects = fileProvider.Projects
|
||||
.Select(p => (File: p, Directory: FileUtils.SafeGetDirectoryName(p, logger)))
|
||||
.Where(p => p.Directory.Length > 0);
|
||||
|
||||
var groupedFiles = new Dictionary<string, List<string>>();
|
||||
|
||||
foreach (var additionalFile in AdditionalFiles)
|
||||
{
|
||||
var project = projects
|
||||
.Where(p => additionalFile.StartsWith(p.Directory))
|
||||
.OrderByDescending(p => p.Directory.Length)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (project == default)
|
||||
{
|
||||
logger.LogDebug($"Failed to find project file for {additionalFile}");
|
||||
continue;
|
||||
}
|
||||
|
||||
groupedFiles.AddAnother(project.File, additionalFile);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var sdk = new Sdk(dotnet, logger);
|
||||
var sourceGenerator = GetSourceGenerator(sdk);
|
||||
var targetDir = GetTemporaryWorkingDirectory(FileType.ToLowerInvariant());
|
||||
|
||||
return groupedFiles
|
||||
.SelectMany(group => sourceGenerator.RunSourceGenerator(group.Value, group.Key, references, targetDir));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// It's okay, we tried our best to generate source files.
|
||||
logger.LogInfo($"Failed to generate source files from {FileType} files: {ex.Message}");
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ICollection<string> AdditionalFiles { get; }
|
||||
|
||||
protected abstract string FileType { get; }
|
||||
|
||||
protected abstract T GetSourceGenerator(Sdk sdk);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal abstract class DotnetSourceGeneratorWrapper
|
||||
{
|
||||
protected readonly ILogger logger;
|
||||
protected readonly IDotNet dotnet;
|
||||
private readonly string cscPath;
|
||||
|
||||
protected abstract string SourceGeneratorFolder { get; init; }
|
||||
protected abstract string FileType { get; }
|
||||
|
||||
public DotnetSourceGeneratorWrapper(
|
||||
Sdk sdk,
|
||||
IDotNet dotnet,
|
||||
ILogger logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.dotnet = dotnet;
|
||||
|
||||
if (sdk.CscPath is null)
|
||||
{
|
||||
throw new Exception($"Not running {FileType} source generator because CSC path is not available.");
|
||||
}
|
||||
this.cscPath = sdk.CscPath;
|
||||
}
|
||||
|
||||
protected abstract void GenerateAnalyzerConfig(IEnumerable<string> additionalFiles, string csprojFile, string analyzerConfigPath);
|
||||
|
||||
public IEnumerable<string> RunSourceGenerator(IEnumerable<string> additionalFiles, string csprojFile, IEnumerable<string> references, string targetDir)
|
||||
{
|
||||
try
|
||||
{
|
||||
var name = Guid.NewGuid().ToString("N").ToUpper();
|
||||
using var tempDir = new TemporaryDirectory(Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), "source-generator"), "source generator temporary", logger);
|
||||
var analyzerConfigPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.txt");
|
||||
var dllPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.dll");
|
||||
var cscArgsPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.rsp");
|
||||
var outputFolder = Path.Combine(targetDir, name);
|
||||
Directory.CreateDirectory(outputFolder);
|
||||
logger.LogInfo("Producing analyzer config content.");
|
||||
GenerateAnalyzerConfig(additionalFiles, csprojFile, analyzerConfigPath);
|
||||
|
||||
logger.LogDebug($"Analyzer config content: {File.ReadAllText(analyzerConfigPath)}");
|
||||
|
||||
var args = new StringBuilder();
|
||||
args.Append($"/target:exe /generatedfilesout:\"{outputFolder}\" /out:\"{dllPath}\" /analyzerconfig:\"{analyzerConfigPath}\" ");
|
||||
|
||||
foreach (var f in Directory.GetFiles(SourceGeneratorFolder, "*.dll", new EnumerationOptions { RecurseSubdirectories = false, MatchCasing = MatchCasing.CaseInsensitive }))
|
||||
{
|
||||
args.Append($"/analyzer:\"{f}\" ");
|
||||
}
|
||||
|
||||
foreach (var f in additionalFiles)
|
||||
{
|
||||
args.Append($"/additionalfile:\"{f}\" ");
|
||||
}
|
||||
|
||||
foreach (var f in references)
|
||||
{
|
||||
args.Append($"/reference:\"{f}\" ");
|
||||
}
|
||||
|
||||
var argsString = args.ToString();
|
||||
|
||||
logger.LogInfo($"Running CSC to generate source files from {FileType} files.");
|
||||
logger.LogDebug($"Running CSC to generate source files from {FileType} files with arguments: {argsString}.");
|
||||
|
||||
using (var sw = new StreamWriter(cscArgsPath))
|
||||
{
|
||||
sw.Write(argsString);
|
||||
}
|
||||
|
||||
dotnet.Exec($"\"{cscPath}\" /noconfig @\"{cscArgsPath}\"");
|
||||
|
||||
var files = Directory.GetFiles(outputFolder, "*.*", new EnumerationOptions { RecurseSubdirectories = true });
|
||||
|
||||
logger.LogInfo($"Generated {files.Length} source files from {FileType} files.");
|
||||
|
||||
return files;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogInfo($"Failed to generate source files from {FileType} files: {ex.Message}");
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal sealed class Razor : DotnetSourceGeneratorWrapper
|
||||
{
|
||||
protected override string FileType => "Razor";
|
||||
|
||||
protected override string SourceGeneratorFolder { get; init; }
|
||||
|
||||
public Razor(Sdk sdk, IDotNet dotNet, ILogger logger) : base(sdk, dotNet, logger)
|
||||
{
|
||||
var sdkPath = sdk.Version?.FullPath;
|
||||
if (sdkPath is null)
|
||||
{
|
||||
throw new Exception("No SDK path available.");
|
||||
}
|
||||
|
||||
SourceGeneratorFolder = Path.Combine(sdkPath, "Sdks", "Microsoft.NET.Sdk.Razor", "source-generators");
|
||||
this.logger.LogInfo($"Razor source generator folder: {SourceGeneratorFolder}");
|
||||
if (!Directory.Exists(SourceGeneratorFolder))
|
||||
{
|
||||
throw new Exception($"Razor source generator folder {SourceGeneratorFolder} does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void GenerateAnalyzerConfig(IEnumerable<string> cshtmls, string csprojFile, 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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal sealed partial class Resx : DotnetSourceGeneratorWrapper
|
||||
{
|
||||
protected override string FileType => "Resx";
|
||||
|
||||
protected override string SourceGeneratorFolder { get; init; }
|
||||
|
||||
public Resx(Sdk sdk, IDotNet dotNet, ILogger logger, string? sourceGeneratorFolder) : base(sdk, dotNet, logger)
|
||||
{
|
||||
if (sourceGeneratorFolder is null)
|
||||
{
|
||||
throw new Exception("No resx source generator folder available.");
|
||||
}
|
||||
SourceGeneratorFolder = sourceGeneratorFolder;
|
||||
}
|
||||
|
||||
protected override void GenerateAnalyzerConfig(IEnumerable<string> resources, string csprojFile, string analyzerConfigPath)
|
||||
{
|
||||
using var sw = new StreamWriter(analyzerConfigPath);
|
||||
sw.WriteLine("is_global = true");
|
||||
|
||||
var rootNamespace = Path.GetFileNameWithoutExtension(csprojFile);
|
||||
|
||||
var matches = File.ReadAllLines(csprojFile)
|
||||
.Select(line => RootNamespace().Match(line))
|
||||
.Where(match => match.Success)
|
||||
.Select(match => match.Groups[1].Value)
|
||||
.ToArray();
|
||||
|
||||
if (matches.Length == 1)
|
||||
{
|
||||
logger.LogDebug($"RootNamespace found in {csprojFile}: {matches[0]}");
|
||||
rootNamespace = matches[0];
|
||||
}
|
||||
else if (matches.Length > 1)
|
||||
{
|
||||
logger.LogDebug($"Multiple RootNamespace elements found in {csprojFile}. Using the first one.");
|
||||
rootNamespace = matches[0];
|
||||
}
|
||||
|
||||
sw.WriteLine($"build_property.RootNamespace = {rootNamespace}");
|
||||
|
||||
foreach (var f in resources.Select(f => f.Replace('\\', '/')))
|
||||
{
|
||||
sw.WriteLine($"\n[{f}]");
|
||||
sw.WriteLine($"build_metadata.AdditionalFiles.EmitFormatMethods = true");
|
||||
}
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"<RootNamespace>(.*)</RootNamespace>", RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||
private static partial Regex RootNamespace();
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
this.fileContent = fileContent;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> Generate()
|
||||
protected override bool IsEnabled() => true;
|
||||
|
||||
protected override IEnumerable<string> Run()
|
||||
{
|
||||
var usings = new HashSet<string>();
|
||||
if (!fileContent.UseImplicitUsings)
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal class Razor
|
||||
{
|
||||
private readonly DotNetVersion sdk;
|
||||
private readonly ILogger logger;
|
||||
private readonly IDotNet dotNet;
|
||||
private readonly string sourceGeneratorFolder;
|
||||
private readonly string cscPath;
|
||||
|
||||
public Razor(DotNetVersion sdk, IDotNet dotNet, ILogger logger)
|
||||
{
|
||||
this.sdk = sdk;
|
||||
this.logger = logger;
|
||||
this.dotNet = dotNet;
|
||||
|
||||
sourceGeneratorFolder = Path.Combine(this.sdk.FullPath, "Sdks", "Microsoft.NET.Sdk.Razor", "source-generators");
|
||||
this.logger.LogInfo($"Razor source generator folder: {sourceGeneratorFolder}");
|
||||
if (!Directory.Exists(sourceGeneratorFolder))
|
||||
{
|
||||
this.logger.LogInfo($"Razor source generator folder {sourceGeneratorFolder} does not exist.");
|
||||
throw new Exception($"Razor source generator folder {sourceGeneratorFolder} does not exist.");
|
||||
}
|
||||
|
||||
cscPath = Path.Combine(this.sdk.FullPath, "Roslyn", "bincore", "csc.dll");
|
||||
this.logger.LogInfo($"Razor source generator CSC: {cscPath}");
|
||||
if (!File.Exists(cscPath))
|
||||
{
|
||||
this.logger.LogInfo($"Csc.exe not found at {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 = FileUtils.GetTemporaryWorkingDirectory(out var shouldCleanUp);
|
||||
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
|
||||
{
|
||||
logger.LogInfo("Produce analyzer config content.");
|
||||
GenerateAnalyzerConfig(cshtmls, analyzerConfig);
|
||||
|
||||
logger.LogDebug($"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", new EnumerationOptions { RecurseSubdirectories = false, MatchCasing = MatchCasing.CaseInsensitive }))
|
||||
{
|
||||
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();
|
||||
|
||||
logger.LogInfo($"Running CSC to generate Razor source files.");
|
||||
logger.LogDebug($"Running CSC to generate Razor source files with arguments: {argsString}.");
|
||||
|
||||
using (var sw = new StreamWriter(cscArgsPath))
|
||||
{
|
||||
sw.Write(argsString);
|
||||
}
|
||||
|
||||
dotNet.Exec($"\"{cscPath}\" /noconfig @\"{cscArgsPath}\"");
|
||||
|
||||
var files = Directory.GetFiles(outputFolder, "*.*", new EnumerationOptions { RecurseSubdirectories = true });
|
||||
|
||||
logger.LogInfo($"Generated {files.Length} source files from cshtml files.");
|
||||
|
||||
return files;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (shouldCleanUp)
|
||||
{
|
||||
DeleteFile(analyzerConfig);
|
||||
DeleteFile(dllPath);
|
||||
DeleteFile(cscArgsPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteFile(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogWarning($"Failed to delete file {path}: {exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal class RazorGenerator : DotnetSourceGeneratorBase<Razor>
|
||||
{
|
||||
public RazorGenerator(
|
||||
FileProvider fileProvider,
|
||||
FileContent fileContent,
|
||||
IDotNet dotnet,
|
||||
ICompilationInfoContainer compilationInfoContainer,
|
||||
ILogger logger,
|
||||
TemporaryDirectory tempWorkingDirectory,
|
||||
IEnumerable<string> references) : base(fileProvider, fileContent, dotnet, compilationInfoContainer, logger, tempWorkingDirectory, references)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool IsEnabled()
|
||||
{
|
||||
var webViewExtractionOption = Environment.GetEnvironmentVariable(EnvironmentVariableNames.WebViewGeneration);
|
||||
if (webViewExtractionOption == null ||
|
||||
bool.TryParse(webViewExtractionOption, out var shouldExtractWebViews) &&
|
||||
shouldExtractWebViews)
|
||||
{
|
||||
compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "1"));
|
||||
return true;
|
||||
}
|
||||
|
||||
compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "0"));
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override ICollection<string> AdditionalFiles => fileProvider.RazorViews;
|
||||
|
||||
protected override string FileType => "Razor";
|
||||
|
||||
protected override Razor GetSourceGenerator(Sdk sdk) => new Razor(sdk, dotnet, logger);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal class ResxGenerator : DotnetSourceGeneratorBase<Resx>
|
||||
{
|
||||
private readonly string? sourceGeneratorFolder = null;
|
||||
|
||||
public ResxGenerator(
|
||||
FileProvider fileProvider,
|
||||
FileContent fileContent,
|
||||
IDotNet dotnet,
|
||||
ICompilationInfoContainer compilationInfoContainer,
|
||||
ILogger logger,
|
||||
NugetPackageRestorer nugetPackageRestorer,
|
||||
TemporaryDirectory tempWorkingDirectory,
|
||||
IEnumerable<string> references) : base(fileProvider, fileContent, dotnet, compilationInfoContainer, logger, tempWorkingDirectory, references)
|
||||
{
|
||||
if (fileProvider.Resources.Count == 0)
|
||||
{
|
||||
logger.LogDebug("No resources found, skipping resource extraction.");
|
||||
sourceGeneratorFolder = null;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// The package is downloaded to `missingpackages`, which is okay, we're already after the DLL collection phase.
|
||||
var nugetFolder = nugetPackageRestorer.TryRestore("Microsoft.CodeAnalysis.ResxSourceGenerator");
|
||||
if (nugetFolder is not null)
|
||||
{
|
||||
sourceGeneratorFolder = System.IO.Path.Combine(nugetFolder, "analyzers", "dotnet", "cs");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogWarning($"Failed to download source generator: {e.Message}");
|
||||
sourceGeneratorFolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool IsEnabled()
|
||||
{
|
||||
var resourceExtractionOption = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ResourceGeneration);
|
||||
if (bool.TryParse(resourceExtractionOption, out var shouldExtractResources) &&
|
||||
shouldExtractResources)
|
||||
{
|
||||
compilationInfoContainer.CompilationInfos.Add(("Resource extraction enabled", "1"));
|
||||
return true;
|
||||
}
|
||||
|
||||
compilationInfoContainer.CompilationInfos.Add(("Resource extraction enabled", "0"));
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override ICollection<string> AdditionalFiles => fileProvider.Resources;
|
||||
|
||||
protected override string FileType => "Resx";
|
||||
|
||||
protected override Resx GetSourceGenerator(Sdk sdk) => new Resx(sdk, dotnet, logger, sourceGeneratorFolder);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
this.tempWorkingDirectory = tempWorkingDirectory;
|
||||
}
|
||||
|
||||
public abstract IEnumerable<string> Generate();
|
||||
public IEnumerable<string> Generate()
|
||||
{
|
||||
if (!IsEnabled())
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return Run();
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<string> Run();
|
||||
protected abstract bool IsEnabled();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a temporary directory with the given subfolder name.
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal class WebViewGenerator : SourceGeneratorBase
|
||||
{
|
||||
private readonly FileProvider fileProvider;
|
||||
private readonly FileContent fileContent;
|
||||
private readonly IDotNet dotnet;
|
||||
private readonly ICompilationInfoContainer compilationInfoContainer;
|
||||
private readonly IEnumerable<string> references;
|
||||
|
||||
public WebViewGenerator(
|
||||
FileProvider fileProvider,
|
||||
FileContent fileContent,
|
||||
IDotNet dotnet,
|
||||
ICompilationInfoContainer compilationInfoContainer,
|
||||
ILogger logger,
|
||||
TemporaryDirectory tempWorkingDirectory,
|
||||
IEnumerable<string> references) : base(logger, tempWorkingDirectory)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.fileContent = fileContent;
|
||||
this.dotnet = dotnet;
|
||||
this.compilationInfoContainer = compilationInfoContainer;
|
||||
this.references = references;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> Generate()
|
||||
{
|
||||
var webViewExtractionOption = Environment.GetEnvironmentVariable(EnvironmentVariableNames.WebViewGeneration);
|
||||
if (webViewExtractionOption == null ||
|
||||
bool.TryParse(webViewExtractionOption, out var shouldExtractWebViews) &&
|
||||
shouldExtractWebViews)
|
||||
{
|
||||
compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "1"));
|
||||
return GenerateSourceFilesFromWebViews();
|
||||
}
|
||||
|
||||
compilationInfoContainer.CompilationInfos.Add(("WebView extraction enabled", "0"));
|
||||
return [];
|
||||
}
|
||||
|
||||
private IEnumerable<string> GenerateSourceFilesFromWebViews()
|
||||
{
|
||||
var views = fileProvider.RazorViews;
|
||||
if (views.Count == 0)
|
||||
{
|
||||
logger.LogDebug("No cshtml or razor files found.");
|
||||
return [];
|
||||
}
|
||||
|
||||
logger.LogInfo($"Found {views.Count} cshtml and razor files.");
|
||||
|
||||
if (!fileContent.IsAspNetCoreDetected)
|
||||
{
|
||||
logger.LogInfo("Generating source files from cshtml files is only supported for new (SDK-style) project files");
|
||||
return [];
|
||||
}
|
||||
|
||||
logger.LogInfo("Generating source files from cshtml and razor files...");
|
||||
|
||||
var sdk = new Sdk(dotnet).GetNewestSdk();
|
||||
if (sdk != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var razor = new Razor(sdk, dotnet, logger);
|
||||
var targetDir = GetTemporaryWorkingDirectory("razor");
|
||||
var generatedFiles = razor.GenerateFiles(views, references, targetDir);
|
||||
return generatedFiles ?? [];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// It's okay, we tried our best to generate source files from cshtml files.
|
||||
logger.LogInfo($"Failed to generate source files from cshtml files: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,10 +164,10 @@ namespace Semmle.Extraction.Tests
|
||||
"6.0.301 [/usr/local/share/dotnet/sdk7]",
|
||||
};
|
||||
var dotnet = new DotNetStub(null!, listedSdks);
|
||||
var sdk = new Sdk(dotnet);
|
||||
var sdk = new Sdk(dotnet, new LoggerStub());
|
||||
|
||||
// Execute
|
||||
var version = sdk.GetNewestSdk();
|
||||
var version = sdk.Version;
|
||||
|
||||
// Verify
|
||||
Assert.NotNull(version);
|
||||
@@ -186,10 +186,10 @@ namespace Semmle.Extraction.Tests
|
||||
"7.0.400 [/usr/local/share/dotnet/sdk4]",
|
||||
};
|
||||
var dotnet = new DotNetStub(null!, listedSdks);
|
||||
var sdk = new Sdk(dotnet);
|
||||
var sdk = new Sdk(dotnet, new LoggerStub());
|
||||
|
||||
// Execute
|
||||
var version = sdk.GetNewestSdk();
|
||||
var version = sdk.Version;
|
||||
|
||||
// Verify
|
||||
Assert.NotNull(version);
|
||||
|
||||
@@ -185,5 +185,42 @@ namespace Semmle.Util
|
||||
|
||||
return new FileInfo(outputPath);
|
||||
}
|
||||
|
||||
public static string SafeGetDirectoryName(string path, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (dir is null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!dir.EndsWith(Path.DirectorySeparatorChar))
|
||||
{
|
||||
dir += Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogDebug($"Failed to get directory name for {path}: {ex.Message}");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static string? SafeGetFileName(string path, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Path.GetFileName(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogDebug($"Failed to get file name for {path}: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace Semmle.Util
|
||||
|
||||
public DirectoryInfo DirInfo { get; }
|
||||
|
||||
public TemporaryDirectory(string name, string userReportedDirectoryPurpose, ILogger logger)
|
||||
public TemporaryDirectory(string path, string userReportedDirectoryPurpose, ILogger logger)
|
||||
{
|
||||
DirInfo = new DirectoryInfo(name);
|
||||
DirInfo = new DirectoryInfo(path);
|
||||
DirInfo.Create();
|
||||
this.userReportedDirectoryPurpose = userReportedDirectoryPurpose;
|
||||
this.logger = logger;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
| Failed project restore with package source error | 0.0 |
|
||||
| Failed solution restore with package source error | 0.0 |
|
||||
| Project files on filesystem | 1.0 |
|
||||
| Resource extraction enabled | 1.0 |
|
||||
| Restored .NET framework variants | 1.0 |
|
||||
| Restored projects through solution files | 0.0 |
|
||||
| Solution files on filesystem | 0.0 |
|
||||
| Source files generated | 2.0 |
|
||||
| Source files on filesystem | 1.0 |
|
||||
| Successfully restored project files | 1.0 |
|
||||
| Successfully restored solution files | 0.0 |
|
||||
| Unresolved references | 0.0 |
|
||||
| UseWPF set | 0.0 |
|
||||
| UseWindowsForms set | 0.0 |
|
||||
| WebView extraction enabled | 1.0 |
|
||||
@@ -0,0 +1,16 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.commons.Diagnostics
|
||||
|
||||
query predicate compilationInfo(string key, float value) {
|
||||
key != "Resolved references" and
|
||||
key != "Resolved assembly conflicts" and
|
||||
not key.matches("Compiler diagnostic count for%") and
|
||||
exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) |
|
||||
key = infoKey and
|
||||
value = infoValue.toFloat()
|
||||
or
|
||||
not exists(infoValue.toFloat()) and
|
||||
key = infoKey + ": " + infoValue and
|
||||
value = 1
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
| Program.cs |
|
||||
| test-db/working/implicitUsings/GlobalUsings.g.cs |
|
||||
| test-db/working/resx/[...]/Microsoft.CodeAnalysis.ResxSourceGenerator.CSharp/Microsoft.CodeAnalysis.ResxSourceGenerator.CSharp.CSharpResxGenerator/test.Designer.cs |
|
||||
@@ -0,0 +1,22 @@
|
||||
import csharp
|
||||
|
||||
private string getPath(File f) {
|
||||
result = f.getRelativePath() and
|
||||
not exists(
|
||||
result
|
||||
.indexOf("Microsoft.CodeAnalysis.ResxSourceGenerator.CSharp/Microsoft.CodeAnalysis.ResxSourceGenerator.CSharp.CSharpResxGenerator")
|
||||
)
|
||||
or
|
||||
exists(int index |
|
||||
index =
|
||||
f.getRelativePath()
|
||||
.indexOf("Microsoft.CodeAnalysis.ResxSourceGenerator.CSharp/Microsoft.CodeAnalysis.ResxSourceGenerator.CSharp.CSharpResxGenerator") and
|
||||
result =
|
||||
f.getRelativePath().substring(0, index - 32 - 2) + "/[...]/" +
|
||||
f.getRelativePath().substring(index, f.getRelativePath().length())
|
||||
)
|
||||
}
|
||||
|
||||
from File f
|
||||
where f.fromSource()
|
||||
select getPath(f)
|
||||
@@ -0,0 +1,8 @@
|
||||
| Program | Program.<Main>$ |
|
||||
| Program | Program.Program |
|
||||
| Resx.Test1.Test2.test | Resx.Test1.Test2.test.Culture |
|
||||
| Resx.Test1.Test2.test | Resx.Test1.Test2.test.GetResourceString |
|
||||
| Resx.Test1.Test2.test | Resx.Test1.Test2.test.Key123 |
|
||||
| Resx.Test1.Test2.test | Resx.Test1.Test2.test.Key456 |
|
||||
| Resx.Test1.Test2.test | Resx.Test1.Test2.test.ResourceManager |
|
||||
| Resx.Test1.Test2.test | Resx.Test1.Test2.test.s_resourceManager |
|
||||
@@ -0,0 +1,5 @@
|
||||
import csharp
|
||||
|
||||
from Class c
|
||||
where c.fromSource()
|
||||
select c.getFullyQualifiedNameDebug(), c.getAMember().getFullyQualifiedNameDebug()
|
||||
@@ -0,0 +1 @@
|
||||
var dummy = "dummy";
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.101"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Resx.Test1.Test2</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
|
||||
<RemoveDir Directories=".\bin" />
|
||||
<RemoveDir Directories=".\obj" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,6 @@
|
||||
import os
|
||||
from create_database_utils import *
|
||||
|
||||
os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_EXTRACT_RESOURCES"] = "true"
|
||||
|
||||
run_codeql_database_create(lang="csharp", extra_args=["--build-mode=none"])
|
||||
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Key123" xml:space="preserve">
|
||||
<value>Value123</value>
|
||||
<comment/>
|
||||
</data>
|
||||
<data name="Key456" xml:space="preserve">
|
||||
<value>Value456</value>
|
||||
<comment/>
|
||||
</data>
|
||||
</root>
|
||||
@@ -3,6 +3,7 @@
|
||||
| Fallback nuget restore | 1.0 |
|
||||
| Project files on filesystem | 1.0 |
|
||||
| Resolved assembly conflicts | 7.0 |
|
||||
| Resource extraction enabled | 0.0 |
|
||||
| Restored .NET framework variants | 0.0 |
|
||||
| Restored projects through solution files | 0.0 |
|
||||
| Solution files on filesystem | 1.0 |
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
| Inherited Nuget feed count | 1.0 |
|
||||
| Project files on filesystem | 1.0 |
|
||||
| Resolved assembly conflicts | 7.0 |
|
||||
| Resource extraction enabled | 0.0 |
|
||||
| Restored .NET framework variants | 0.0 |
|
||||
| Solution files on filesystem | 1.0 |
|
||||
| Source files generated | 0.0 |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| [...]/newtonsoft.json/13.0.1/lib/netstandard2.0/Newtonsoft.Json.dll |
|
||||
@@ -0,0 +1,18 @@
|
||||
import csharp
|
||||
|
||||
private string getPath(Assembly a) {
|
||||
not a.getCompilation().getOutputAssembly() = a and
|
||||
exists(string s | s = a.getFile().getAbsolutePath() |
|
||||
exists(result.indexOf("Newtonsoft.Json")) and
|
||||
result =
|
||||
"[...]" +
|
||||
s.substring(s.indexOf("test-db/working/") + "test-db/working/".length() + 16 +
|
||||
"/packages".length(), s.length())
|
||||
or
|
||||
result = s and
|
||||
not exists(s.indexOf("test-db/working/"))
|
||||
)
|
||||
}
|
||||
|
||||
from Assembly a
|
||||
select getPath(a)
|
||||
@@ -0,0 +1,6 @@
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
|
||||
<RemoveDir Directories=".\bin" />
|
||||
<RemoveDir Directories=".\obj" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
|
||||
<RemoveDir Directories=".\bin" />
|
||||
<RemoveDir Directories=".\obj" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.101"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create([], lang="csharp", extra_args=["--build-mode=none"])
|
||||
@@ -16,11 +16,21 @@ import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.system.web.Helpers
|
||||
import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
|
||||
private Method getAValidatingMethod() {
|
||||
result = any(AntiForgeryClass a).getValidateMethod()
|
||||
or
|
||||
result.calls(getAValidatingMethod())
|
||||
}
|
||||
|
||||
/** An `AuthorizationFilter` that calls the `AntiForgery.Validate` method. */
|
||||
class AntiForgeryAuthorizationFilter extends AuthorizationFilter {
|
||||
AntiForgeryAuthorizationFilter() {
|
||||
this.getOnAuthorizationMethod().calls*(any(AntiForgeryClass a).getValidateMethod())
|
||||
}
|
||||
AntiForgeryAuthorizationFilter() { this.getOnAuthorizationMethod() = getAValidatingMethod() }
|
||||
}
|
||||
|
||||
private Method getAStartedMethod() {
|
||||
result = any(WebApplication wa).getApplication_StartMethod()
|
||||
or
|
||||
getAStartedMethod().calls(result)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,9 +44,7 @@ predicate hasGlobalAntiForgeryFilter() {
|
||||
// The filter is an antiforgery filter
|
||||
addGlobalFilter.getArgumentForName("filter").getType() instanceof AntiForgeryAuthorizationFilter and
|
||||
// The filter is added by the Application_Start() method
|
||||
any(WebApplication wa)
|
||||
.getApplication_StartMethod()
|
||||
.calls*(addGlobalFilter.getEnclosingCallable())
|
||||
getAStartedMethod() = addGlobalFilter.getEnclosingCallable()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@ Sources
|
||||
-------
|
||||
|
||||
To mark a source of data that is controlled by an untrusted user, we
|
||||
create a class extending ``UntrustedFlowSource::Range``. Inheritance and
|
||||
create a class extending ``RemoteFlowSource::Range``. Inheritance and
|
||||
the characteristic predicate of the class should be used to specify
|
||||
exactly the dataflow node that introduces the data. Here is a short
|
||||
example from ``Mux.qll``.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
class RequestVars extends DataFlow::UntrustedFlowSource::Range, DataFlow::CallNode {
|
||||
class RequestVars extends DataFlow::RemoteFlowSource::Range, DataFlow::CallNode {
|
||||
RequestVars() { this.getTarget().hasQualifiedName("github.com/gorilla/mux", "Vars") }
|
||||
}
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@ Sources
|
||||
-------
|
||||
|
||||
To mark a source of data that is controlled by an untrusted user, we
|
||||
create a class extending ``UntrustedFlowSource::Range``. Inheritance and
|
||||
create a class extending ``RemoteFlowSource::Range``. Inheritance and
|
||||
the characteristic predicate of the class should be used to specify
|
||||
exactly the dataflow node that introduces the data. Here is a short
|
||||
example from ``Mux.qll``.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
class RequestVars extends DataFlow::UntrustedFlowSource::Range, DataFlow::CallNode {
|
||||
class RequestVars extends DataFlow::RemoteFlowSource::Range, DataFlow::CallNode {
|
||||
RequestVars() { this.getTarget().hasQualifiedName("github.com/gorilla/mux", "Vars") }
|
||||
}
|
||||
|
||||
@@ -119,4 +119,4 @@ Here is a short example from ``Stdlib.qll``, which has been slightly simplified.
|
||||
This has the effect that any call to ``Print``, ``Printf``, or
|
||||
``Println`` in the package ``fmt`` is recognized as a logger call.
|
||||
Any query that uses logger calls as a sink will then identify when tainted data
|
||||
has been passed as an argument to ``Print``, ``Printf``, or ``Println``.
|
||||
has been passed as an argument to ``Print``, ``Printf``, or ``Println``.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
require golang.org/x/net v0.0.0-20200505041828-1ed23360d12c
|
||||
require golang.org/x/net v0.23.0
|
||||
|
||||
require golang.org/x/sys v0.18.0 // indirect
|
||||
|
||||
module test
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
go 1.14
|
||||
|
||||
require golang.org/x/net v0.0.0-20200505041828-1ed23360d12c
|
||||
require golang.org/x/net v0.23.0
|
||||
|
||||
module module
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c
|
||||
)
|
||||
require golang.org/x/net v0.23.0
|
||||
|
||||
module makesample
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
go 1.14
|
||||
|
||||
require golang.org/x/net v0.0.0-20200505041828-1ed23360d12c
|
||||
require golang.org/x/net v0.23.0
|
||||
|
||||
module subdir
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
go 1.14
|
||||
|
||||
require golang.org/x/net v0.0.0-20200505041828-1ed23360d12c
|
||||
require golang.org/x/net v0.23.0
|
||||
|
||||
module subdir2
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
go 1.14
|
||||
|
||||
require golang.org/x/net v0.0.0-20200505041828-1ed23360d12c
|
||||
require golang.org/x/net v0.23.0
|
||||
|
||||
module subdir1
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* To make Go consistent with other language libraries, the `UntrustedFlowSource` name has been deprecated throughout. Use `RemoteFlowSource` instead, which replaces it.
|
||||
* Where modules have classes named `UntrustedFlowAsSource`, these are also deprecated and the `Source` class in the same module or the `RemoteFlowSource` class should be used instead.
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources, sinks and taint propagators
|
||||
* Provides classes for working with remote flow sources, sinks and taint propagators
|
||||
* from the `github.com/aws/aws-lambda-go/lambda` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/** A source of input data in an AWS Lambda. */
|
||||
private class LambdaInput extends UntrustedFlowSource::Range {
|
||||
private class LambdaInput extends RemoteFlowSource::Range {
|
||||
LambdaInput() {
|
||||
exists(Parameter p | p = this.asParameter() |
|
||||
p = any(HandlerFunction hf).getAParameter() and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources, sinks and taint propagators
|
||||
* Provides classes for working with remote flow sources, sinks and taint propagators
|
||||
* from the `github.com/beego/beego` package.
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,7 @@ private import semmle.go.security.SafeUrlFlowCustomizations
|
||||
|
||||
// Some TaintTracking::FunctionModel subclasses remain because varargs functions don't work with Models-as-Data sumamries yet.
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources, sinks and taint propagators
|
||||
* Provides classes for working with remote flow sources, sinks and taint propagators
|
||||
* from the [Beego](https://github.com/beego/beego) package.
|
||||
*/
|
||||
module Beego {
|
||||
@@ -50,7 +50,7 @@ module Beego {
|
||||
/**
|
||||
* `BeegoInput` sources of untrusted data.
|
||||
*/
|
||||
private class BeegoInputSource extends UntrustedFlowSource::Range {
|
||||
private class BeegoInputSource extends RemoteFlowSource::Range {
|
||||
string methodName;
|
||||
|
||||
BeegoInputSource() {
|
||||
@@ -81,7 +81,7 @@ module Beego {
|
||||
/**
|
||||
* `beego.Controller` sources of untrusted data.
|
||||
*/
|
||||
private class BeegoControllerSource extends UntrustedFlowSource::Range {
|
||||
private class BeegoControllerSource extends RemoteFlowSource::Range {
|
||||
BeegoControllerSource() {
|
||||
exists(string methodName, FunctionOutput output |
|
||||
methodName = "ParseForm" and
|
||||
@@ -105,7 +105,7 @@ module Beego {
|
||||
/**
|
||||
* `BeegoInputRequestBody` sources of untrusted data.
|
||||
*/
|
||||
private class BeegoInputRequestBodySource extends UntrustedFlowSource::Range {
|
||||
private class BeegoInputRequestBodySource extends RemoteFlowSource::Range {
|
||||
BeegoInputRequestBodySource() {
|
||||
exists(DataFlow::FieldReadNode frn | this = frn |
|
||||
frn.getField().hasQualifiedName(contextPackagePath(), "BeegoInput", "RequestBody")
|
||||
@@ -116,7 +116,7 @@ module Beego {
|
||||
/**
|
||||
* `beego/context.Context` sources of untrusted data.
|
||||
*/
|
||||
private class BeegoContextSource extends UntrustedFlowSource::Range {
|
||||
private class BeegoContextSource extends RemoteFlowSource::Range {
|
||||
BeegoContextSource() {
|
||||
exists(Method m | m.hasQualifiedName(contextPackagePath(), "Context", "GetCookie") |
|
||||
this = m.getACall().getResult()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources, sinks and taint propagators
|
||||
* Provides classes for working with remote flow sources, sinks and taint propagators
|
||||
* from the `github.com/astaxie/beego/orm` subpackage.
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@ import go
|
||||
private import semmle.go.security.StoredXssCustomizations
|
||||
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources, sinks and taint propagators
|
||||
* Provides classes for working with remote flow sources, sinks and taint propagators
|
||||
* from the [Beego ORM](https://github.com/astaxie/beego/orm) subpackage.
|
||||
*/
|
||||
module BeegoOrm {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources from the `github.com/go-chi/chi` package.
|
||||
* Provides classes for working with remote flow sources from the `github.com/go-chi/chi` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
@@ -9,18 +9,18 @@ private module Chi {
|
||||
string packagePath() { result = package("github.com/go-chi/chi", "") }
|
||||
|
||||
/**
|
||||
* Functions that extract URL parameters, considered as a source of untrusted flow.
|
||||
* Functions that extract URL parameters, considered as a source of remote flow.
|
||||
*/
|
||||
private class UserControlledFunction extends UntrustedFlowSource::Range, DataFlow::CallNode {
|
||||
private class UserControlledFunction extends RemoteFlowSource::Range, DataFlow::CallNode {
|
||||
UserControlledFunction() {
|
||||
this.getTarget().hasQualifiedName(packagePath(), ["URLParam", "URLParamFromCtx"])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods that extract URL parameters, considered as a source of untrusted flow.
|
||||
* Methods that extract URL parameters, considered as a source of remote flow.
|
||||
*/
|
||||
private class UserControlledRequestMethod extends UntrustedFlowSource::Range,
|
||||
private class UserControlledRequestMethod extends RemoteFlowSource::Range,
|
||||
DataFlow::MethodCallNode
|
||||
{
|
||||
UserControlledRequestMethod() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources, taint propagators, and HTTP sinks
|
||||
* Provides classes for working with remote flow sources, taint propagators, and HTTP sinks
|
||||
* from the `github.com/labstack/echo` package.
|
||||
*/
|
||||
|
||||
@@ -10,9 +10,9 @@ private module Echo {
|
||||
private string packagePath() { result = package("github.com/labstack/echo", "") }
|
||||
|
||||
/**
|
||||
* Data from a `Context` interface method, considered as a source of untrusted flow.
|
||||
* Data from a `Context` interface method, considered as a source of remote flow.
|
||||
*/
|
||||
private class EchoContextSource extends UntrustedFlowSource::Range {
|
||||
private class EchoContextSource extends RemoteFlowSource::Range {
|
||||
EchoContextSource() {
|
||||
exists(DataFlow::MethodCallNode call, string methodName |
|
||||
methodName =
|
||||
@@ -42,7 +42,7 @@ private module Echo {
|
||||
/**
|
||||
* A call to a method on `Context` struct that unmarshals data into a target.
|
||||
*/
|
||||
private class EchoContextBinder extends UntrustedFlowSource::Range {
|
||||
private class EchoContextBinder extends RemoteFlowSource::Range {
|
||||
EchoContextBinder() {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call.getTarget().hasQualifiedName(packagePath(), "Context", "Bind")
|
||||
|
||||
@@ -95,7 +95,7 @@ module ElazarlGoproxy {
|
||||
}
|
||||
}
|
||||
|
||||
private class UserControlledRequestData extends UntrustedFlowSource::Range {
|
||||
private class UserControlledRequestData extends RemoteFlowSource::Range {
|
||||
UserControlledRequestData() {
|
||||
exists(DataFlow::FieldReadNode frn | this = frn |
|
||||
// liberally consider ProxyCtx.UserData to be untrusted; it's a data field set by a request handler
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources, sinks and taint propagators
|
||||
* Provides classes for working with remote flow sources, sinks and taint propagators
|
||||
* from the `github.com/valyala/fasthttp` package.
|
||||
*/
|
||||
|
||||
@@ -255,11 +255,16 @@ module Fasthttp {
|
||||
* Provide modeling for fasthttp.URI Type.
|
||||
*/
|
||||
module URI {
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowSource = RemoteFlowSource;
|
||||
|
||||
/**
|
||||
* The methods as Remote user controllable source which are part of the incoming URL.
|
||||
*/
|
||||
class UntrustedFlowSource extends UntrustedFlowSource::Range instanceof DataFlow::Node {
|
||||
UntrustedFlowSource() {
|
||||
class RemoteFlowSource extends RemoteFlowSource::Range instanceof DataFlow::Node {
|
||||
RemoteFlowSource() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName(packagePath(), "URI",
|
||||
["FullURI", "LastPathSegment", "Path", "PathOriginal", "QueryString", "String"]) and
|
||||
@@ -273,13 +278,18 @@ module Fasthttp {
|
||||
* Provide modeling for fasthttp.Args Type.
|
||||
*/
|
||||
module Args {
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowSource = RemoteFlowSource;
|
||||
|
||||
/**
|
||||
* The methods as Remote user controllable source which are part of the incoming URL Parameters.
|
||||
*
|
||||
* When support for lambdas has been implemented we should model "VisitAll".
|
||||
*/
|
||||
class UntrustedFlowSource extends UntrustedFlowSource::Range instanceof DataFlow::Node {
|
||||
UntrustedFlowSource() {
|
||||
class RemoteFlowSource extends RemoteFlowSource::Range instanceof DataFlow::Node {
|
||||
RemoteFlowSource() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName(packagePath(), "Args",
|
||||
["Peek", "PeekBytes", "PeekMulti", "PeekMultiBytes", "QueryString", "String"]) and
|
||||
@@ -386,11 +396,16 @@ module Fasthttp {
|
||||
* Provide modeling for fasthttp.Request Type.
|
||||
*/
|
||||
module Request {
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowSource = RemoteFlowSource;
|
||||
|
||||
/**
|
||||
* The methods as Remote user controllable source which can be many part of request.
|
||||
*/
|
||||
class UntrustedFlowSource extends UntrustedFlowSource::Range instanceof DataFlow::Node {
|
||||
UntrustedFlowSource() {
|
||||
class RemoteFlowSource extends RemoteFlowSource::Range instanceof DataFlow::Node {
|
||||
RemoteFlowSource() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName(packagePath(), "Request",
|
||||
[
|
||||
@@ -463,13 +478,18 @@ module Fasthttp {
|
||||
override Http::ResponseWriter getResponseWriter() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowSource = RemoteFlowSource;
|
||||
|
||||
/**
|
||||
* The methods as Remote user controllable source which are generally related to HTTP request.
|
||||
*
|
||||
* When support for lambdas has been implemented we should model "VisitAll", "VisitAllCookie", "VisitAllInOrder", "VisitAllTrailer".
|
||||
*/
|
||||
class UntrustedFlowSource extends UntrustedFlowSource::Range instanceof DataFlow::Node {
|
||||
UntrustedFlowSource() {
|
||||
class RemoteFlowSource extends RemoteFlowSource::Range instanceof DataFlow::Node {
|
||||
RemoteFlowSource() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName(packagePath(), "RequestCtx",
|
||||
[
|
||||
@@ -486,13 +506,18 @@ module Fasthttp {
|
||||
* Provide Methods of fasthttp.RequestHeader which mostly used as remote user controlled sources.
|
||||
*/
|
||||
module RequestHeader {
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowSource = RemoteFlowSource;
|
||||
|
||||
/**
|
||||
* The methods as Remote user controllable source which are mostly related to HTTP Request Headers.
|
||||
*
|
||||
* When support for lambdas has been implemented we should model "VisitAll", "VisitAllCookie", "VisitAllInOrder", "VisitAllTrailer".
|
||||
*/
|
||||
class UntrustedFlowSource extends UntrustedFlowSource::Range instanceof DataFlow::Node {
|
||||
UntrustedFlowSource() {
|
||||
class RemoteFlowSource extends RemoteFlowSource::Range instanceof DataFlow::Node {
|
||||
RemoteFlowSource() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName(packagePath(), "RequestHeader",
|
||||
[
|
||||
|
||||
@@ -10,9 +10,9 @@ private module Gin {
|
||||
string packagePath() { result = package("github.com/gin-gonic/gin", "") }
|
||||
|
||||
/**
|
||||
* Data from a `Context` struct, considered as a source of untrusted flow.
|
||||
* Data from a `Context` struct, considered as a source of remote flow.
|
||||
*/
|
||||
private class GithubComGinGonicGinContextSource extends UntrustedFlowSource::Range {
|
||||
private class GithubComGinGonicGinContextSource extends RemoteFlowSource::Range {
|
||||
GithubComGinGonicGinContextSource() {
|
||||
// Method calls:
|
||||
exists(DataFlow::MethodCallNode call, string methodName |
|
||||
@@ -39,7 +39,7 @@ private module Gin {
|
||||
/**
|
||||
* A call to a method on `Context` struct that unmarshals data into a target.
|
||||
*/
|
||||
private class GithubComGinGonicGinContextBindSource extends UntrustedFlowSource::Range {
|
||||
private class GithubComGinGonicGinContextBindSource extends RemoteFlowSource::Range {
|
||||
GithubComGinGonicGinContextBindSource() {
|
||||
exists(DataFlow::MethodCallNode call, string methodName |
|
||||
call.getTarget().hasQualifiedName(packagePath(), "Context", methodName) and
|
||||
|
||||
@@ -35,7 +35,7 @@ module GoKit {
|
||||
DataFlow::exprNode(result.(FuncLit)) = getAnEndpointFactoryResult()
|
||||
}
|
||||
|
||||
private class EndpointRequest extends UntrustedFlowSource::Range {
|
||||
private class EndpointRequest extends RemoteFlowSource::Range {
|
||||
EndpointRequest() { this = DataFlow::parameterNode(getAnEndpointFunction().getParameter(1)) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ module GoMicro {
|
||||
/**
|
||||
* A set of remote requests from a service handler.
|
||||
*/
|
||||
class Request extends UntrustedFlowSource::Range instanceof DataFlow::ParameterNode {
|
||||
class Request extends RemoteFlowSource::Range instanceof DataFlow::ParameterNode {
|
||||
Request() {
|
||||
exists(ServiceHandler handler |
|
||||
this.asParameter().isParameterOf(handler.getFuncDecl(), 1) and
|
||||
|
||||
@@ -27,14 +27,14 @@ private module GoRestfulHttp {
|
||||
/**
|
||||
* A model of go-restful's `Request` object as a source of user-controlled data.
|
||||
*/
|
||||
private class GoRestfulSource extends UntrustedFlowSource::Range {
|
||||
private class GoRestfulSource extends RemoteFlowSource::Range {
|
||||
GoRestfulSource() { this = any(GoRestfulSourceMethod g).getACall() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A model of go-restful's `Request.ReadEntity` method as a source of user-controlled data.
|
||||
*/
|
||||
private class GoRestfulReadEntitySource extends UntrustedFlowSource::Range {
|
||||
private class GoRestfulReadEntitySource extends RemoteFlowSource::Range {
|
||||
GoRestfulReadEntitySource() {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call.getTarget().hasQualifiedName(packagePath(), "Request", "ReadEntity")
|
||||
|
||||
@@ -39,7 +39,7 @@ module Gqlgen {
|
||||
}
|
||||
|
||||
/** A parameter of a resolver method which receives untrusted input. */
|
||||
class ResolverParameter extends UntrustedFlowSource::Range instanceof DataFlow::ParameterNode {
|
||||
class ResolverParameter extends RemoteFlowSource::Range instanceof DataFlow::ParameterNode {
|
||||
ResolverParameter() {
|
||||
this.asParameter() = any(ResolverImplementationMethod h).getAnUntrustedParameter()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import go
|
||||
*/
|
||||
module Mux {
|
||||
/** An access to a Mux middleware variable. */
|
||||
class RequestVars extends DataFlow::UntrustedFlowSource::Range, DataFlow::CallNode {
|
||||
class RequestVars extends DataFlow::RemoteFlowSource::Range, DataFlow::CallNode {
|
||||
RequestVars() {
|
||||
this.getTarget().hasQualifiedName(package("github.com/gorilla/mux", ""), "Vars")
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides classes for working with untrusted flow sources from the `github.com/revel/revel` package.
|
||||
* Provides classes for working with remote flow sources from the `github.com/revel/revel` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
@@ -12,7 +12,7 @@ module Revel {
|
||||
result = package(["github.com/revel", "github.com/robfig"] + "/revel", "")
|
||||
}
|
||||
|
||||
private class ControllerParams extends UntrustedFlowSource::Range, DataFlow::FieldReadNode {
|
||||
private class ControllerParams extends RemoteFlowSource::Range, DataFlow::FieldReadNode {
|
||||
ControllerParams() {
|
||||
exists(Field f |
|
||||
this.readsField(_, f) and
|
||||
@@ -32,7 +32,7 @@ module Revel {
|
||||
}
|
||||
}
|
||||
|
||||
private class RouteMatchParams extends UntrustedFlowSource::Range, DataFlow::FieldReadNode {
|
||||
private class RouteMatchParams extends RemoteFlowSource::Range, DataFlow::FieldReadNode {
|
||||
RouteMatchParams() {
|
||||
exists(Field f |
|
||||
this.readsField(_, f) and
|
||||
@@ -42,9 +42,7 @@ module Revel {
|
||||
}
|
||||
|
||||
/** An access to an HTTP request field whose value may be controlled by an untrusted user. */
|
||||
private class UserControlledRequestField extends UntrustedFlowSource::Range,
|
||||
DataFlow::FieldReadNode
|
||||
{
|
||||
private class UserControlledRequestField extends RemoteFlowSource::Range, DataFlow::FieldReadNode {
|
||||
UserControlledRequestField() {
|
||||
exists(string fieldName |
|
||||
this.getField().hasQualifiedName(packagePath(), "Request", fieldName)
|
||||
@@ -56,7 +54,7 @@ module Revel {
|
||||
}
|
||||
}
|
||||
|
||||
private class UserControlledRequestMethod extends UntrustedFlowSource::Range,
|
||||
private class UserControlledRequestMethod extends RemoteFlowSource::Range,
|
||||
DataFlow::MethodCallNode
|
||||
{
|
||||
UserControlledRequestMethod() {
|
||||
|
||||
@@ -130,7 +130,7 @@ module Twirp {
|
||||
}
|
||||
|
||||
/** A request coming to the service handler. */
|
||||
class Request extends UntrustedFlowSource::Range instanceof DataFlow::ParameterNode {
|
||||
class Request extends RemoteFlowSource::Range instanceof DataFlow::ParameterNode {
|
||||
Request() {
|
||||
exists(ServiceHandler handler |
|
||||
this.asParameter().isParameterOf(handler.getFuncDecl(), 1) and
|
||||
|
||||
@@ -127,7 +127,7 @@ module WebSocketRequestCall {
|
||||
/**
|
||||
* A message written to a WebSocket, considered as a flow sink for reflected XSS.
|
||||
*/
|
||||
class WebSocketReaderAsSource extends UntrustedFlowSource::Range {
|
||||
class WebSocketReaderAsSource extends RemoteFlowSource::Range {
|
||||
WebSocketReaderAsSource() {
|
||||
exists(WebSocketReader r | this = r.getAnOutput().getNode(r.getACall()))
|
||||
}
|
||||
|
||||
@@ -9,9 +9,7 @@ private import semmle.go.dataflow.internal.FlowSummaryImpl::Private
|
||||
/** Provides models of commonly used functions in the `net/http` package. */
|
||||
module NetHttp {
|
||||
/** An access to an HTTP request field whose value may be controlled by an untrusted user. */
|
||||
private class UserControlledRequestField extends UntrustedFlowSource::Range,
|
||||
DataFlow::FieldReadNode
|
||||
{
|
||||
private class UserControlledRequestField extends RemoteFlowSource::Range, DataFlow::FieldReadNode {
|
||||
UserControlledRequestField() {
|
||||
exists(string fieldName | this.getField().hasQualifiedName("net/http", "Request", fieldName) |
|
||||
fieldName =
|
||||
|
||||
@@ -29,8 +29,13 @@ module CommandInjection {
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` or `Source` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowAsSource = RemoteFlowAsSource;
|
||||
|
||||
/** A source of untrusted data, considered as a taint source for command injection. */
|
||||
class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { }
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/** A command name, considered as a taint sink for command injection. */
|
||||
class CommandNameAsSink extends Sink {
|
||||
|
||||
@@ -187,13 +187,13 @@ class UnknownExternalApiDataNode extends ExternalApiDataNode {
|
||||
deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
|
||||
UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
|
||||
}
|
||||
|
||||
private module UntrustedDataConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
|
||||
}
|
||||
@@ -211,13 +211,13 @@ module UntrustedDataToExternalApiFlow = DataFlow::Global<UntrustedDataConfig>;
|
||||
deprecated class UntrustedDataToUnknownExternalApiConfig extends TaintTracking::Configuration {
|
||||
UntrustedDataToUnknownExternalApiConfig() { this = "UntrustedDataToUnknownExternalAPIConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof UnknownExternalApiDataNode }
|
||||
}
|
||||
|
||||
private module UntrustedDataToUnknownExternalApiConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof UnknownExternalApiDataNode }
|
||||
}
|
||||
|
||||
@@ -5,21 +5,31 @@
|
||||
import go
|
||||
private import semmle.go.dataflow.ExternalFlow as ExternalFlow
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowSource = RemoteFlowSource;
|
||||
|
||||
/**
|
||||
* A source of data that is controlled by an untrusted user.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `UntrustedFlowSource::Range` instead.
|
||||
* extend `RemoteFlowSource::Range` instead.
|
||||
*/
|
||||
class UntrustedFlowSource extends DataFlow::Node instanceof UntrustedFlowSource::Range { }
|
||||
class RemoteFlowSource extends DataFlow::Node instanceof RemoteFlowSource::Range { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` instead.
|
||||
*/
|
||||
deprecated module UntrustedFlowSource = RemoteFlowSource;
|
||||
|
||||
/** Provides a class for modeling new sources of untrusted data. */
|
||||
module UntrustedFlowSource {
|
||||
module RemoteFlowSource {
|
||||
/**
|
||||
* A source of data that is controlled by an untrusted user.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `UntrustedFlowSource` instead.
|
||||
* extend `RemoteFlowSource` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node { }
|
||||
|
||||
|
||||
@@ -25,8 +25,13 @@ module LogInjection {
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` or `Source` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowAsSource = RemoteFlowAsSource;
|
||||
|
||||
/** A source of untrusted data, considered as a taint source for log injection. */
|
||||
class UntrustedFlowAsSource extends Source instanceof UntrustedFlowSource { }
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/** An argument to a logging mechanism. */
|
||||
class LoggerSink extends Sink {
|
||||
|
||||
@@ -49,7 +49,7 @@ module MissingJwtSignatureCheck {
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultSource extends Source instanceof UntrustedFlowSource { }
|
||||
private class DefaultSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
private class DefaultSink extends Sink {
|
||||
DefaultSink() { sinkNode(this, "jwt") }
|
||||
|
||||
@@ -42,11 +42,16 @@ module OpenUrlRedirect {
|
||||
abstract predicate hasTaintStep(DataFlow::Node pred, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` or `Source` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowAsSource = RemoteFlowAsSource;
|
||||
|
||||
/**
|
||||
* A source of third-party user input, considered as a flow source for URL redirects.
|
||||
*/
|
||||
class UntrustedFlowAsSource extends Source, UntrustedFlowSource {
|
||||
UntrustedFlowAsSource() {
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource {
|
||||
RemoteFlowAsSource() {
|
||||
// exclude some fields and methods of URLs that are generally not attacker-controllable for
|
||||
// open redirect exploits
|
||||
not this instanceof Http::Redirect::UnexploitableSource
|
||||
|
||||
@@ -34,10 +34,15 @@ module ReflectedXss {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` or `Source` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowAsSource = RemoteFlowAsSource;
|
||||
|
||||
/**
|
||||
* A third-party controllable input, considered as a flow source for reflected XSS.
|
||||
*/
|
||||
class UntrustedFlowAsSource extends Source, UntrustedFlowSource { }
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/** An arbitrary XSS sink, considered as a flow sink for stored XSS. */
|
||||
private class AnySink extends Sink instanceof SharedXss::Sink { }
|
||||
|
||||
@@ -32,10 +32,15 @@ module RequestForgery {
|
||||
/** An outgoing sanitizer edge for request forgery vulnerabilities. */
|
||||
abstract class SanitizerEdge extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSource` or `Source` instead.
|
||||
*/
|
||||
deprecated class UntrustedFlowAsSource = RemoteFlowAsSource;
|
||||
|
||||
/**
|
||||
* A third-party controllable input, considered as a flow source for request forgery.
|
||||
*/
|
||||
class UntrustedFlowAsSource extends Source, UntrustedFlowSource { }
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* The URL of an HTTP request, viewed as a sink for request forgery.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user