Merge branch 'main' into redsun82/swift-open-redirection

This commit is contained in:
Paolo Tranquilli 2022-12-09 09:59:21 +01:00
Родитель 26ae8f177b cddb5c5e2d
Коммит 4a41bb4061
40 изменённых файлов: 487 добавлений и 240 удалений

21
.github/workflows/check-query-ids.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
name: Check query IDs
on:
pull_request:
paths:
- "**/src/**/*.ql"
- misc/scripts/check-query-ids.py
- .github/workflows/check-query-ids.yml
branches:
- main
- "rc/*"
workflow_dispatch:
jobs:
check:
name: Check query IDs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check for duplicate query IDs
run: python3 misc/scripts/check-query-ids.py

1
.github/workflows/swift.yml поставляемый
Просмотреть файл

@ -65,6 +65,7 @@ jobs:
if : ${{ github.event_name == 'pull_request' }}
needs: build-and-test-macos
runs-on: macos-12-xl
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-integration-tests

Просмотреть файл

@ -470,6 +470,10 @@
"javascript/ql/src/Comments/CommentedOutCodeReferences.inc.qhelp",
"python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp"
],
"ThreadResourceAbuse qhelp": [
"java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp",
"java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp"
],
"IDE Contextual Queries": [
"cpp/ql/lib/IDEContextual.qll",
"csharp/ql/lib/IDEContextual.qll",

Просмотреть файл

@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `scanf` and `fscanf` functions and their variants are now recognized as flow sources.

Просмотреть файл

@ -27,7 +27,7 @@ private import implementations.StdString
private import implementations.Swap
private import implementations.GetDelim
private import implementations.SmartPointer
private import implementations.Sscanf
private import implementations.Scanf
private import implementations.Send
private import implementations.Recv
private import implementations.Accept

Просмотреть файл

@ -1,6 +1,6 @@
/**
* Provides implementation classes modeling `sscanf`, `fscanf` and various similar
* functions. See `semmle.code.cpp.models.Models` for usage information.
* Provides implementation classes modeling the `scanf` family of functions.
* See `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.Function
@ -9,18 +9,15 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.FlowSource
/**
* The standard function `sscanf`, `fscanf` and its assorted variants
* The `scanf` family of functions.
*/
private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, SideEffectFunction {
SscanfModel() { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf }
abstract private class ScanfFunctionModel extends ArrayFunction, TaintFunction, AliasFunction,
SideEffectFunction {
override predicate hasArrayWithNullTerminator(int bufParam) {
bufParam = this.(ScanfFunction).getFormatParameterIndex()
or
not this instanceof Fscanf and
bufParam = this.(ScanfFunction).getInputParameterIndex()
}
override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) }
@ -36,7 +33,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
)
}
private int getArgsStartPosition() { result = this.getNumberOfParameters() }
int getArgsStartPosition() { result = this.getNumberOfParameters() }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and
@ -70,3 +67,36 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
]
}
}
/**
* The standard function `scanf` and its assorted variants
*/
private class ScanfModel extends ScanfFunctionModel, LocalFlowSourceFunction instanceof Scanf {
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and
description = "Value read by " + this.getName()
}
}
/**
* The standard function `fscanf` and its assorted variants
*/
private class FscanfModel extends ScanfFunctionModel, RemoteFlowSourceFunction instanceof Fscanf {
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and
description = "Value read by " + this.getName()
}
}
/**
* The standard function `sscanf` and its assorted variants
*/
private class SscanfModel extends ScanfFunctionModel {
SscanfModel() { this instanceof Sscanf or this instanceof Snscanf }
override predicate hasArrayWithNullTerminator(int bufParam) {
super.hasArrayWithNullTerminator(bufParam)
or
bufParam = this.(ScanfFunction).getInputParameterIndex()
}
}

Просмотреть файл

@ -19,7 +19,25 @@ import semmle.code.cpp.ir.dataflow.TaintTracking
import DataFlow::PathGraph
/**
* A taint flow configuration for flow from user input to a buffer write.
* A buffer write into a sensitive expression.
*/
class SensitiveBufferWrite extends Expr instanceof BufferWrite::BufferWrite {
SensitiveBufferWrite() { super.getDest() instanceof SensitiveExpr }
/**
* Gets a data source of this operation.
*/
Expr getASource() { result = super.getASource() }
/**
* Gets the destination buffer of this operation.
*/
Expr getDest() { result = super.getDest() }
}
/**
* A taint flow configuration for flow from user input to a buffer write
* into a sensitive expression.
*/
class ToBufferConfiguration extends TaintTracking::Configuration {
ToBufferConfiguration() { this = "ToBufferConfiguration" }
@ -31,18 +49,17 @@ class ToBufferConfiguration extends TaintTracking::Configuration {
}
override predicate isSink(DataFlow::Node sink) {
exists(BufferWrite::BufferWrite w | w.getASource() = sink.asExpr())
exists(SensitiveBufferWrite w | w.getASource() = sink.asExpr())
}
}
from
ToBufferConfiguration config, BufferWrite::BufferWrite w, DataFlow::PathNode sourceNode,
DataFlow::PathNode sinkNode, FlowSource source, SensitiveExpr dest
ToBufferConfiguration config, SensitiveBufferWrite w, DataFlow::PathNode sourceNode,
DataFlow::PathNode sinkNode, FlowSource source
where
config.hasFlowPath(sourceNode, sinkNode) and
sourceNode.getNode() = source and
w.getASource() = sinkNode.getNode().asExpr() and
dest = w.getDest()
w.getASource() = sinkNode.getNode().asExpr()
select w, sourceNode, sinkNode,
"This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@.", source,
"user input (" + source.getSourceType() + ")"
"This write into buffer '" + w.getDest().toString() + "' may contain unencrypted data from $@.",
source, "user input (" + source.getSourceType() + ")"

Просмотреть файл

@ -11,8 +11,20 @@ class LocalFlowSourceTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "local_source" and
value = "" and
exists(LocalFlowSource node |
exists(LocalFlowSource node, int n |
n =
strictcount(LocalFlowSource otherNode |
node.getLocation().getStartLine() = otherNode.getLocation().getStartLine()
) and
(
n = 1 and value = ""
or
// If there is more than one node on this line
// we specify the location explicitly.
n > 1 and
value =
node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn()
) and
location = node.getLocation() and
element = node.toString()
)

Просмотреть файл

@ -11,8 +11,20 @@ class RemoteFlowSourceTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "remote_source" and
value = "" and
exists(RemoteFlowSource node |
exists(RemoteFlowSource node, int n |
n =
strictcount(RemoteFlowSource otherNode |
node.getLocation().getStartLine() = otherNode.getLocation().getStartLine()
) and
(
n = 1 and value = ""
or
// If there is more than one node on this line
// we specify the location explicitly.
n > 1 and
value =
node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn()
) and
location = node.getLocation() and
element = node.toString()
)
@ -26,8 +38,20 @@ class RemoteFlowSinkTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "remote_sink" and
value = "" and
exists(RemoteFlowSink node |
exists(RemoteFlowSink node, int n |
n =
strictcount(RemoteFlowSink otherNode |
node.getLocation().getStartLine() = otherNode.getLocation().getStartLine()
) and
(
n = 1 and value = ""
or
// If there is more than one node on this line
// we specify the location explicitly.
n > 1 and
value =
node.getLocation().getStartLine().toString() + ":" + node.getLocation().getStartColumn()
) and
location = node.getLocation() and
element = node.toString()
)

Просмотреть файл

@ -26,3 +26,17 @@ void test_readv_and_writev(iovec* iovs) {
readv(0, iovs, 16); // $ remote_source
writev(0, iovs, 16); // $ remote_sink
}
struct FILE;
int fscanf(FILE *stream, const char *format, ...);
int scanf(const char *format, ...);
void test_scanf(FILE *stream, int *d, char *buf) {
scanf(""); // Not a local source, as there are no output arguments
fscanf(stream, ""); // Not a remote source, as there are no output arguments
scanf("%d", d); // $ local_source
fscanf(stream, "%d", d); // $ remote_source
scanf("%d %s", d, buf); // $ local_source=40:18 local_source=40:21
fscanf(stream, "%d %s", d, buf); // $ remote_source=41:27 remote_source=41:30
}

Просмотреть файл

@ -1,7 +1,6 @@
edges
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
| test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection |
| test.c:37:17:37:24 | fileName | test.c:38:11:38:18 | fileName indirection |
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection |
| test.c:43:17:43:24 | fileName | test.c:44:11:44:18 | fileName indirection |
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection |
@ -10,7 +9,6 @@ nodes
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:31:22:31:25 | argv | semmle.label | argv |
| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:37:17:37:24 | fileName | semmle.label | fileName |
| test.c:37:17:37:24 | scanf output argument | semmle.label | scanf output argument |
| test.c:38:11:38:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:43:17:43:24 | fileName | semmle.label | fileName |
@ -20,5 +18,5 @@ subpaths
#select
| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (argv) |
| test.c:32:11:32:18 | fileName | test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:31:22:31:25 | argv | user input (argv) |
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | fileName | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | fileName | user input (scanf) |
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | fileName | user input (scanf) |
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | fileName | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | fileName | user input (scanf) |

Просмотреть файл

@ -7,42 +7,12 @@ edges
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 |
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 indirection |
| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 |
| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 |
| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 |
| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
@ -65,16 +35,11 @@ nodes
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection |
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:31:15:31:23 | scanf output argument | semmle.label | scanf output argument |
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... |
@ -84,11 +49,6 @@ nodes
#select
| tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
| tests.c:29:3:29:9 | call to sprintf | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
| tests.c:31:15:31:23 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
| tests.c:31:15:31:23 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
| tests.c:33:21:33:29 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
| tests.c:33:21:33:29 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
| tests.c:33:21:33:29 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 |
| tests.c:34:25:34:33 | buffer100 | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv |

Просмотреть файл

@ -6,14 +6,11 @@
/** A possible cargo item. */
class Cargo extends string {
Cargo() {
this = "Nothing" or
this = "Goat" or
this = "Cabbage" or
this = "Wolf"
this = ["Nothing", "Goat", "Cabbage", "Wolf"]
}
}
/** One of two shores. */
/** A shore, named either `Left` or `Right`. */
class Shore extends string {
Shore() {
this = "Left" or
@ -93,7 +90,7 @@ class Cargo extends string {
// Reachable by first following pathSoFar and then ferrying cargo
exists(string pathSoFar, string visitedStatesSoFar, Cargo cargo |
result = this.reachesVia(pathSoFar, visitedStatesSoFar).safeFerry(cargo) and
not exists(int i | i = visitedStatesSoFar.indexOf(result)) and // resulting state is not visited yet
not exists(visitedStatesSoFar.indexOf(result)) and // resulting state is not visited yet
visitedStates = visitedStatesSoFar + "_" + result and
path = pathSoFar + ",\nthen " + cargo + " is ferried " + result.towards()
)

Просмотреть файл

@ -154,7 +154,7 @@ class Shore extends string {
State reachesVia(string path) {
exists(string pathSoFar |
result = this.reachesVia(pathSoFar).transition() and
not exists(int i | i = pathSoFar.indexOf(result.toString())) and
not exists(pathSoFar.indexOf(result.toString())) and
path = pathSoFar + "\n↓\n" + result
)
}
@ -169,7 +169,7 @@ class Shore extends string {
}
override State reachesVia(string path) {
path = this + "\n↓\n" + result and result = transition()
path = this + "\n↓\n" + result and result = this.transition()
or
result = super.reachesVia(path)
}

Просмотреть файл

@ -118,7 +118,7 @@ class State extends TState {
State reachesVia(string path) {
exists(string pathSoFar |
result = this.reachesVia(pathSoFar).transition() and
not exists(int i | i = pathSoFar.indexOf(result.toString())) and
not exists(pathSoFar.indexOf(result.toString())) and
path = pathSoFar + "\n" + result
)
}
@ -133,7 +133,7 @@ class InitialState extends State {
}
override State reachesVia(string path) {
path = this + "\n" + result and result = transition()
path = this + "\n" + result and result = this.transition()
or
result = super.reachesVia(path)
}

Просмотреть файл

@ -891,7 +891,7 @@ open class KotlinFileExtractor(
f.realOverrideTarget.let { it != f && (it as? IrSimpleFunction)?.modality != Modality.ABSTRACT && isKotlinDefinedInterface(it.parentClassOrNull) }
private fun makeInterfaceForwarder(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
forceExtractFunction(f, parentId, extractBody = false, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = OverriddenFunctionAttributes(visibility = DescriptorVisibilities.PUBLIC)).also { functionId ->
forceExtractFunction(f, parentId, extractBody = false, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = OverriddenFunctionAttributes(visibility = DescriptorVisibilities.PUBLIC, modality = Modality.OPEN)).also { functionId ->
tw.writeCompiler_generated(functionId, CompilerGeneratedKinds.INTERFACE_FORWARDER.kind)
if (extractBody) {
val realFunctionLocId = tw.getLocation(f)
@ -1243,6 +1243,13 @@ open class KotlinFileExtractor(
if (f.isSuspend) {
addModifiers(id, "suspend")
}
if (f.symbol !is IrConstructorSymbol) {
when(overriddenAttributes?.modality ?: (f as? IrSimpleFunction)?.modality) {
Modality.ABSTRACT -> addModifiers(id, "abstract")
Modality.FINAL -> addModifiers(id, "final")
else -> Unit
}
}
linesOfCode?.linesOfCodeInDeclaration(f, id)
@ -5304,7 +5311,7 @@ open class KotlinFileExtractor(
// we would need to compose generic type substitutions -- for example, if we're implementing
// T UnaryOperator<T>.apply(T t) here, we would need to compose substitutions so we can implement
// the real underlying R Function<T, R>.apply(T t).
forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e)))
forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e), modality = Modality.FINAL))
addModifiers(ids.function, "override")
if (st.isSuspendFunctionOrKFunction()) {
@ -5529,6 +5536,7 @@ open class KotlinFileExtractor(
val typeParameters: List<IrTypeParameter>? = null,
val isStatic: Boolean? = null,
val visibility: DescriptorVisibility? = null,
val modality: Modality? = null,
)
private fun peekDeclStackAsDeclarationParent(elementToReportOn: IrElement): IrDeclarationParent? {

Просмотреть файл

@ -0,0 +1,48 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The <code>Thread.sleep</code> method is used to pause the execution of current thread for
specified time. When the sleep time is user-controlled, especially in the web application context,
it can be abused to cause all of a server's threads to sleep, leading to denial of service.</p>
</overview>
<recommendation>
<p>To guard against this attack, consider specifying an upper range of allowed sleep time or adopting
the producer/consumer design pattern with <code>Object.wait</code> method to avoid performance
problems or even resource exhaustion. For more information, refer to the concurrency tutorial of Oracle
listed below or <code>java/ql/src/Likely Bugs/Concurrency</code> queries of CodeQL.</p>
</recommendation>
<example>
<p>The following example shows a bad situation and a good situation respectively. In the bad situation,
a thread sleep time comes directly from user input. In the good situation, an upper
range check on the maximum sleep time allowed is enforced.</p>
<sample src="ThreadResourceAbuse.java" />
</example>
<references>
<li>
Snyk:
<a href="https://snyk.io/vuln/SNYK-JAVA-COMGOOGLECODEGWTUPLOAD-569506">Denial of Service (DoS)
in com.googlecode.gwtupload:gwtupload</a>.
</li>
<li>
gwtupload:
<a href="https://github.com/manolo/gwtupload/issues/33">[Fix DOS issue] Updating the
AbstractUploadListener.java file</a>.
</li>
<li>
The blog of a gypsy engineer:
<a href="https://blog.gypsyengineer.com/en/security/cve-2019-17555-dos-via-retry-after-header-in-apache-olingo.html">
CVE-2019-17555: DoS via Retry-After header in Apache Olingo</a>.
</li>
<li>
Oracle:
<a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html">The Java Concurrency Tutorials</a>
</li>
</references>
</qhelp>

Просмотреть файл

@ -3,7 +3,7 @@
* @description Using user input directly to control a thread's sleep time could lead to
* performance problems or even resource exhaustion.
* @kind path-problem
* @id java/thread-resource-abuse
* @id java/local-thread-resource-abuse
* @problem.severity recommendation
* @tags security
* external/cwe/cwe-400

Просмотреть файл

@ -43,41 +43,41 @@ memberRefExprs
| samConversion.kt:5:27:5:31 | ...::... | samConversion.kt:5:27:5:31 | invoke | invoke(int,int) | samConversion.kt:5:27:5:31 | new Function2<Integer,Integer,Unit>(...) { ... } |
| samConversion.kt:41:13:41:16 | ...::... | samConversion.kt:41:13:41:16 | invoke | invoke(java.lang.Object[]) | samConversion.kt:41:13:41:16 | new FunctionN<Boolean>(...) { ... } |
lambda_modifiers
| delegatedProperties.kt:6:32:9:9 | ...->... | delegatedProperties.kt:6:32:9:9 | invoke | override, public |
| funcExprs.kt:22:26:22:33 | ...->... | funcExprs.kt:22:26:22:33 | invoke | override, public |
| funcExprs.kt:23:26:23:33 | ...->... | funcExprs.kt:23:26:23:33 | invoke | override, public |
| funcExprs.kt:24:26:24:33 | ...->... | funcExprs.kt:24:26:24:33 | invoke | override, public |
| funcExprs.kt:25:29:25:38 | ...->... | funcExprs.kt:25:29:25:38 | invoke | override, public |
| funcExprs.kt:26:29:26:34 | ...->... | funcExprs.kt:26:29:26:34 | invoke | override, public |
| funcExprs.kt:27:29:27:42 | ...->... | funcExprs.kt:27:29:27:42 | invoke | override, public |
| funcExprs.kt:29:29:29:37 | ...->... | funcExprs.kt:29:29:29:37 | invoke | override, public |
| funcExprs.kt:30:28:30:50 | ...->... | funcExprs.kt:30:28:30:50 | invoke | override, public |
| funcExprs.kt:31:28:31:40 | ...->... | funcExprs.kt:31:28:31:40 | invoke | override, public |
| funcExprs.kt:32:28:32:44 | ...->... | funcExprs.kt:32:28:32:44 | invoke | override, public |
| funcExprs.kt:33:28:33:51 | ...->... | funcExprs.kt:33:28:33:51 | invoke | override, public |
| funcExprs.kt:33:37:33:47 | ...->... | funcExprs.kt:33:37:33:47 | invoke | override, public |
| funcExprs.kt:35:29:35:112 | ...->... | funcExprs.kt:35:29:35:112 | invoke | override, public |
| delegatedProperties.kt:6:32:9:9 | ...->... | delegatedProperties.kt:6:32:9:9 | invoke | final, override, public |
| funcExprs.kt:22:26:22:33 | ...->... | funcExprs.kt:22:26:22:33 | invoke | final, override, public |
| funcExprs.kt:23:26:23:33 | ...->... | funcExprs.kt:23:26:23:33 | invoke | final, override, public |
| funcExprs.kt:24:26:24:33 | ...->... | funcExprs.kt:24:26:24:33 | invoke | final, override, public |
| funcExprs.kt:25:29:25:38 | ...->... | funcExprs.kt:25:29:25:38 | invoke | final, override, public |
| funcExprs.kt:26:29:26:34 | ...->... | funcExprs.kt:26:29:26:34 | invoke | final, override, public |
| funcExprs.kt:27:29:27:42 | ...->... | funcExprs.kt:27:29:27:42 | invoke | final, override, public |
| funcExprs.kt:29:29:29:37 | ...->... | funcExprs.kt:29:29:29:37 | invoke | final, override, public |
| funcExprs.kt:30:28:30:50 | ...->... | funcExprs.kt:30:28:30:50 | invoke | final, override, public |
| funcExprs.kt:31:28:31:40 | ...->... | funcExprs.kt:31:28:31:40 | invoke | final, override, public |
| funcExprs.kt:32:28:32:44 | ...->... | funcExprs.kt:32:28:32:44 | invoke | final, override, public |
| funcExprs.kt:33:28:33:51 | ...->... | funcExprs.kt:33:28:33:51 | invoke | final, override, public |
| funcExprs.kt:33:37:33:47 | ...->... | funcExprs.kt:33:37:33:47 | invoke | final, override, public |
| funcExprs.kt:35:29:35:112 | ...->... | funcExprs.kt:35:29:35:112 | invoke | final, override, public |
| funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | final, public |
| funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | override, public |
| funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | public |
| funcExprs.kt:75:12:75:22 | ...->... | funcExprs.kt:75:12:75:22 | invoke | override, public |
| funcExprs.kt:83:31:83:51 | ...->... | funcExprs.kt:83:31:83:51 | invoke | override, public |
| funcExprs.kt:86:39:86:59 | ...->... | funcExprs.kt:86:39:86:59 | invoke | override, public, suspend |
| funcExprs.kt:75:12:75:22 | ...->... | funcExprs.kt:75:12:75:22 | invoke | final, override, public |
| funcExprs.kt:83:31:83:51 | ...->... | funcExprs.kt:83:31:83:51 | invoke | final, override, public |
| funcExprs.kt:86:39:86:59 | ...->... | funcExprs.kt:86:39:86:59 | invoke | final, override, public, suspend |
| funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | final, public |
| funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | override, public |
| funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | public |
| funcExprs.kt:94:15:94:67 | ...->... | funcExprs.kt:94:15:94:67 | invoke | override, public, suspend |
| samConversion.kt:2:31:2:45 | ...->... | samConversion.kt:2:31:2:45 | invoke | override, public |
| samConversion.kt:4:27:4:42 | ...->... | samConversion.kt:4:27:4:42 | invoke | override, public |
| samConversion.kt:7:29:7:46 | ...->... | samConversion.kt:7:29:7:46 | invoke | override, public |
| samConversion.kt:9:33:11:5 | ...->... | samConversion.kt:9:33:11:5 | invoke | override, public |
| samConversion.kt:11:12:13:5 | ...->... | samConversion.kt:11:12:13:5 | invoke | override, public |
| funcExprs.kt:94:15:94:67 | ...->... | funcExprs.kt:94:15:94:67 | invoke | final, override, public, suspend |
| samConversion.kt:2:31:2:45 | ...->... | samConversion.kt:2:31:2:45 | invoke | final, override, public |
| samConversion.kt:4:27:4:42 | ...->... | samConversion.kt:4:27:4:42 | invoke | final, override, public |
| samConversion.kt:7:29:7:46 | ...->... | samConversion.kt:7:29:7:46 | invoke | final, override, public |
| samConversion.kt:9:33:11:5 | ...->... | samConversion.kt:9:33:11:5 | invoke | final, override, public |
| samConversion.kt:11:12:13:5 | ...->... | samConversion.kt:11:12:13:5 | invoke | final, override, public |
| samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | final, public |
| samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | override, public |
| samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | public |
| samConversion.kt:46:32:46:44 | ...->... | samConversion.kt:46:32:46:44 | invoke | override, public |
| samConversion.kt:58:30:58:45 | ...->... | samConversion.kt:58:30:58:45 | invoke | override, public, suspend |
| samConversion.kt:46:32:46:44 | ...->... | samConversion.kt:46:32:46:44 | invoke | final, override, public |
| samConversion.kt:58:30:58:45 | ...->... | samConversion.kt:58:30:58:45 | invoke | final, override, public, suspend |
anon_class_member_modifiers
| delegatedProperties.kt:6:24:9:9 | new KProperty0<Integer>(...) { ... } | delegatedProperties.kt:6:24:9:9 | get | override, public |
| delegatedProperties.kt:6:24:9:9 | new KProperty0<Integer>(...) { ... } | delegatedProperties.kt:6:24:9:9 | invoke | override, public |
| delegatedProperties.kt:6:32:9:9 | new Function0<Integer>(...) { ... } | delegatedProperties.kt:6:32:9:9 | invoke | override, public |
| delegatedProperties.kt:6:32:9:9 | new Function0<Integer>(...) { ... } | delegatedProperties.kt:6:32:9:9 | invoke | final, override, public |
| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0<Integer>(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public |
| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0<Integer>(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public |
| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0<Integer>(...) { ... } | delegatedProperties.kt:19:31:19:51 | invoke | override, public |
@ -86,8 +86,8 @@ anon_class_member_modifiers
| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0<Integer>(...) { ... } | delegatedProperties.kt:19:31:19:51 | set | override, public |
| delegatedProperties.kt:23:26:23:31 | new KProperty0<String>(...) { ... } | delegatedProperties.kt:23:26:23:31 | get | override, public |
| delegatedProperties.kt:23:26:23:31 | new KProperty0<String>(...) { ... } | delegatedProperties.kt:23:26:23:31 | invoke | override, public |
| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty<Object,Integer>(...) { ... } | delegatedProperties.kt:26:13:26:28 | getCurValue | public |
| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty<Object,Integer>(...) { ... } | delegatedProperties.kt:26:13:26:28 | setCurValue | public |
| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty<Object,Integer>(...) { ... } | delegatedProperties.kt:26:13:26:28 | getCurValue | final, public |
| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty<Object,Integer>(...) { ... } | delegatedProperties.kt:26:13:26:28 | setCurValue | final, public |
| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty<Object,Integer>(...) { ... } | delegatedProperties.kt:27:22:27:88 | getValue | override, public |
| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty<Object,Integer>(...) { ... } | delegatedProperties.kt:28:22:30:13 | setValue | override, public |
| delegatedProperties.kt:33:27:33:47 | new KProperty0<Integer>(...) { ... } | delegatedProperties.kt:33:27:33:47 | get | override, public |
@ -187,22 +187,22 @@ anon_class_member_modifiers
| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0<Integer>(...) { ... } | delegatedProperties.kt:87:34:87:46 | get | override, public |
| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0<Integer>(...) { ... } | delegatedProperties.kt:87:34:87:46 | invoke | override, public |
| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0<Integer>(...) { ... } | delegatedProperties.kt:87:34:87:46 | set | override, public |
| exprs.kt:195:16:197:9 | new Interface1(...) { ... } | exprs.kt:196:13:196:49 | getA3 | public |
| funcExprs.kt:22:26:22:33 | new Function0<Integer>(...) { ... } | funcExprs.kt:22:26:22:33 | invoke | override, public |
| funcExprs.kt:23:26:23:33 | new Function0<Object>(...) { ... } | funcExprs.kt:23:26:23:33 | invoke | override, public |
| funcExprs.kt:24:26:24:33 | new Function0<Object>(...) { ... } | funcExprs.kt:24:26:24:33 | invoke | override, public |
| funcExprs.kt:25:29:25:38 | new Function1<Integer,Integer>(...) { ... } | funcExprs.kt:25:29:25:38 | invoke | override, public |
| funcExprs.kt:26:29:26:34 | new Function1<Integer,Integer>(...) { ... } | funcExprs.kt:26:29:26:34 | invoke | override, public |
| funcExprs.kt:27:29:27:42 | new Function1<Integer,Integer>(...) { ... } | funcExprs.kt:27:29:27:42 | invoke | override, public |
| funcExprs.kt:29:29:29:37 | new Function1<Object,Object>(...) { ... } | funcExprs.kt:29:29:29:37 | invoke | override, public |
| funcExprs.kt:30:28:30:50 | new Function2<Integer,Integer,Integer>(...) { ... } | funcExprs.kt:30:28:30:50 | invoke | override, public |
| funcExprs.kt:31:28:31:40 | new Function2<Integer,Integer,Integer>(...) { ... } | funcExprs.kt:31:28:31:40 | invoke | override, public |
| funcExprs.kt:32:28:32:44 | new Function2<Integer,Integer,Integer>(...) { ... } | funcExprs.kt:32:28:32:44 | invoke | override, public |
| funcExprs.kt:33:28:33:51 | new Function1<Integer,Function1<Integer,Double>>(...) { ... } | funcExprs.kt:33:28:33:51 | invoke | override, public |
| funcExprs.kt:33:37:33:47 | new Function1<Integer,Double>(...) { ... } | funcExprs.kt:33:37:33:47 | invoke | override, public |
| funcExprs.kt:35:29:35:112 | new Function22<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Unit>(...) { ... } | funcExprs.kt:35:29:35:112 | invoke | override, public |
| exprs.kt:195:16:197:9 | new Interface1(...) { ... } | exprs.kt:196:13:196:49 | getA3 | final, public |
| funcExprs.kt:22:26:22:33 | new Function0<Integer>(...) { ... } | funcExprs.kt:22:26:22:33 | invoke | final, override, public |
| funcExprs.kt:23:26:23:33 | new Function0<Object>(...) { ... } | funcExprs.kt:23:26:23:33 | invoke | final, override, public |
| funcExprs.kt:24:26:24:33 | new Function0<Object>(...) { ... } | funcExprs.kt:24:26:24:33 | invoke | final, override, public |
| funcExprs.kt:25:29:25:38 | new Function1<Integer,Integer>(...) { ... } | funcExprs.kt:25:29:25:38 | invoke | final, override, public |
| funcExprs.kt:26:29:26:34 | new Function1<Integer,Integer>(...) { ... } | funcExprs.kt:26:29:26:34 | invoke | final, override, public |
| funcExprs.kt:27:29:27:42 | new Function1<Integer,Integer>(...) { ... } | funcExprs.kt:27:29:27:42 | invoke | final, override, public |
| funcExprs.kt:29:29:29:37 | new Function1<Object,Object>(...) { ... } | funcExprs.kt:29:29:29:37 | invoke | final, override, public |
| funcExprs.kt:30:28:30:50 | new Function2<Integer,Integer,Integer>(...) { ... } | funcExprs.kt:30:28:30:50 | invoke | final, override, public |
| funcExprs.kt:31:28:31:40 | new Function2<Integer,Integer,Integer>(...) { ... } | funcExprs.kt:31:28:31:40 | invoke | final, override, public |
| funcExprs.kt:32:28:32:44 | new Function2<Integer,Integer,Integer>(...) { ... } | funcExprs.kt:32:28:32:44 | invoke | final, override, public |
| funcExprs.kt:33:28:33:51 | new Function1<Integer,Function1<Integer,Double>>(...) { ... } | funcExprs.kt:33:28:33:51 | invoke | final, override, public |
| funcExprs.kt:33:37:33:47 | new Function1<Integer,Double>(...) { ... } | funcExprs.kt:33:37:33:47 | invoke | final, override, public |
| funcExprs.kt:35:29:35:112 | new Function22<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Unit>(...) { ... } | funcExprs.kt:35:29:35:112 | invoke | final, override, public |
| funcExprs.kt:36:29:36:117 | new FunctionN<String>(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | final, public |
| funcExprs.kt:36:29:36:117 | new FunctionN<String>(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | override, public |
| funcExprs.kt:36:29:36:117 | new FunctionN<String>(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | public |
| funcExprs.kt:38:26:38:38 | new Function0<Integer>(...) { ... } | funcExprs.kt:38:26:38:38 | invoke | override, public |
| funcExprs.kt:39:26:39:36 | new Function0<Integer>(...) { ... } | funcExprs.kt:39:26:39:36 | invoke | override, public |
| funcExprs.kt:40:29:40:41 | new Function1<Integer,Integer>(...) { ... } | funcExprs.kt:40:29:40:41 | invoke | override, public |
@ -214,37 +214,37 @@ anon_class_member_modifiers
| funcExprs.kt:46:30:46:41 | new FunctionN<String>(...) { ... } | funcExprs.kt:46:30:46:41 | invoke | override, public |
| funcExprs.kt:49:26:49:32 | new Function0<Integer>(...) { ... } | funcExprs.kt:49:26:49:32 | invoke | override, public |
| funcExprs.kt:51:8:51:16 | new Function0<FuncRef>(...) { ... } | funcExprs.kt:51:8:51:16 | invoke | override, public |
| funcExprs.kt:75:12:75:22 | new Function1<Generic<Generic<Integer>>,String>(...) { ... } | funcExprs.kt:75:12:75:22 | invoke | override, public |
| funcExprs.kt:83:31:83:51 | new Function1<Integer,String>(...) { ... } | funcExprs.kt:83:31:83:51 | invoke | override, public |
| funcExprs.kt:86:39:86:59 | new Function1<Integer,String>(...) { ... } | funcExprs.kt:86:39:86:59 | invoke | override, public, suspend |
| funcExprs.kt:75:12:75:22 | new Function1<Generic<Generic<Integer>>,String>(...) { ... } | funcExprs.kt:75:12:75:22 | invoke | final, override, public |
| funcExprs.kt:83:31:83:51 | new Function1<Integer,String>(...) { ... } | funcExprs.kt:83:31:83:51 | invoke | final, override, public |
| funcExprs.kt:86:39:86:59 | new Function1<Integer,String>(...) { ... } | funcExprs.kt:86:39:86:59 | invoke | final, override, public, suspend |
| funcExprs.kt:90:15:90:69 | new FunctionN<String>(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | final, public |
| funcExprs.kt:90:15:90:69 | new FunctionN<String>(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | override, public |
| funcExprs.kt:90:15:90:69 | new FunctionN<String>(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | public |
| funcExprs.kt:94:15:94:67 | new Function22<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,String>(...) { ... } | funcExprs.kt:94:15:94:67 | invoke | override, public, suspend |
| funcExprs.kt:94:15:94:67 | new Function22<Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,String>(...) { ... } | funcExprs.kt:94:15:94:67 | invoke | final, override, public, suspend |
| kFunctionInvoke.kt:8:44:8:47 | new Function1<String,Unit>(...) { ... } | kFunctionInvoke.kt:8:44:8:47 | invoke | override, public |
| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | override, public |
| samConversion.kt:2:31:2:45 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:2:31:2:45 | invoke | override, public |
| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | override, public |
| samConversion.kt:4:27:4:42 | new Function2<Integer,Integer,Unit>(...) { ... } | samConversion.kt:4:27:4:42 | invoke | override, public |
| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | override, public |
| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | final, override, public |
| samConversion.kt:2:31:2:45 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:2:31:2:45 | invoke | final, override, public |
| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | final, override, public |
| samConversion.kt:4:27:4:42 | new Function2<Integer,Integer,Unit>(...) { ... } | samConversion.kt:4:27:4:42 | invoke | final, override, public |
| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | final, override, public |
| samConversion.kt:5:27:5:31 | new Function2<Integer,Integer,Unit>(...) { ... } | samConversion.kt:5:27:5:31 | invoke | override, public |
| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | override, public |
| samConversion.kt:7:29:7:46 | new Function2<String,Integer,Boolean>(...) { ... } | samConversion.kt:7:29:7:46 | invoke | override, public |
| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | override, public |
| samConversion.kt:9:33:11:5 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:9:33:11:5 | invoke | override, public |
| samConversion.kt:11:12:13:5 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:11:12:13:5 | invoke | override, public |
| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | final, override, public |
| samConversion.kt:7:29:7:46 | new Function2<String,Integer,Boolean>(...) { ... } | samConversion.kt:7:29:7:46 | invoke | final, override, public |
| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | final, override, public |
| samConversion.kt:9:33:11:5 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:9:33:11:5 | invoke | final, override, public |
| samConversion.kt:11:12:13:5 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:11:12:13:5 | invoke | final, override, public |
| samConversion.kt:41:13:41:16 | new FunctionN<Boolean>(...) { ... } | samConversion.kt:41:13:41:16 | invoke | override, public |
| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | override, public |
| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | override, public |
| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | final, override, public |
| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | final, override, public |
| samConversion.kt:43:31:45:68 | new FunctionN<Boolean>(...) { ... } | samConversion.kt:43:31:45:68 | invoke | final, public |
| samConversion.kt:43:31:45:68 | new FunctionN<Boolean>(...) { ... } | samConversion.kt:43:31:45:68 | invoke | override, public |
| samConversion.kt:43:31:45:68 | new FunctionN<Boolean>(...) { ... } | samConversion.kt:43:31:45:68 | invoke | public |
| samConversion.kt:46:13:46:44 | new SomePredicate<Integer>(...) { ... } | samConversion.kt:46:13:46:44 | fn | override, public |
| samConversion.kt:46:32:46:44 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:46:32:46:44 | invoke | override, public |
| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | override, public, suspend |
| samConversion.kt:58:30:58:45 | new Function2<Integer,Integer,Unit>(...) { ... } | samConversion.kt:58:30:58:45 | invoke | override, public, suspend |
| samConversion.kt:75:17:75:33 | new IntGetter(...) { ... } | samConversion.kt:75:17:75:33 | f | override, public |
| samConversion.kt:46:13:46:44 | new SomePredicate<Integer>(...) { ... } | samConversion.kt:46:13:46:44 | fn | final, override, public |
| samConversion.kt:46:32:46:44 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:46:32:46:44 | invoke | final, override, public |
| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | final, override, public, suspend |
| samConversion.kt:58:30:58:45 | new Function2<Integer,Integer,Unit>(...) { ... } | samConversion.kt:58:30:58:45 | invoke | final, override, public, suspend |
| samConversion.kt:75:17:75:33 | new IntGetter(...) { ... } | samConversion.kt:75:17:75:33 | f | final, override, public |
| samConversion.kt:75:27:75:32 | new KProperty0<Integer>(...) { ... } | samConversion.kt:75:27:75:32 | get | override, public |
| samConversion.kt:75:27:75:32 | new KProperty0<Integer>(...) { ... } | samConversion.kt:75:27:75:32 | invoke | override, public |
| samConversion.kt:76:17:76:55 | new PropertyRefsGetter(...) { ... } | samConversion.kt:76:17:76:55 | f | override, public |
| samConversion.kt:76:17:76:55 | new PropertyRefsGetter(...) { ... } | samConversion.kt:76:17:76:55 | f | final, override, public |
| samConversion.kt:76:36:76:54 | new KProperty1<PropertyRefsTest,Integer>(...) { ... } | samConversion.kt:76:36:76:54 | get | override, public |
| samConversion.kt:76:36:76:54 | new KProperty1<PropertyRefsTest,Integer>(...) { ... } | samConversion.kt:76:36:76:54 | invoke | override, public |
nonOverrideInvoke

Просмотреть файл

@ -3,10 +3,14 @@ isInternal
| Kotlin.kt:2:11:3:2 | kotlinFun$main |
| Kotlin.kt:6:10:6:36 | topLevelKotlinFun |
modifiers_methods
| file://:0:0:0:0 | final | Kotlin.kt:2:11:3:2 | kotlinFun$main |
| file://:0:0:0:0 | final | Kotlin.kt:6:10:6:36 | topLevelKotlinFun |
| file://:0:0:0:0 | internal | Kotlin.kt:2:11:3:2 | kotlinFun$main |
| file://:0:0:0:0 | internal | Kotlin.kt:6:10:6:36 | topLevelKotlinFun |
| file://:0:0:0:0 | static | Kotlin.kt:6:10:6:36 | topLevelKotlinFun |
#select
| Kotlin.kt:2:11:3:2 | kotlinFun$main | final |
| Kotlin.kt:2:11:3:2 | kotlinFun$main | internal |
| Kotlin.kt:6:10:6:36 | topLevelKotlinFun | final |
| Kotlin.kt:6:10:6:36 | topLevelKotlinFun | internal |
| Kotlin.kt:6:10:6:36 | topLevelKotlinFun | static |

Просмотреть файл

@ -1,59 +1,59 @@
methods
| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:0:0:0:0 | <clinit> | <clinit>() | static | Compiler generated |
| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | getTopLevelInt | getTopLevelInt() | public, static | Compiler generated |
| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | setTopLevelInt | setTopLevelInt(int) | public, static | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component1 | component1() | public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component2 | component2() | public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | copy | copy(int,java.lang.String) | public | Compiler generated |
| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | getTopLevelInt | getTopLevelInt() | final, public, static | Compiler generated |
| clinit.kt:0:0:0:0 | ClinitKt | clinit.kt:3:1:3:24 | setTopLevelInt | setTopLevelInt(int) | final, public, static | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component1 | component1() | final, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | component2 | component2() | final, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | copy | copy(int,java.lang.String) | final, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | copy$default | copy$default(DataClass,int,java.lang.String,int,java.lang.Object) | public, static | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | equals | equals(java.lang.Object) | override, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | hashCode | hashCode() | override, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:0:0:0:0 | toString | toString() | override, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:22:1:31 | getX | getX() | public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | getY | getY() | public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | setY | setY(java.lang.String) | public | Compiler generated |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:4:18:6:5 | getLazyProp | getLazyProp() | public | Compiler generated |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | getObservableProp | getObservableProp() | public | Compiler generated |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | setObservableProp | setObservableProp(java.lang.String) | public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:22:1:31 | getX | getX() | final, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | getY | getY() | final, public | Compiler generated |
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | setY | setY(java.lang.String) | final, public | Compiler generated |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:4:18:6:5 | getLazyProp | getLazyProp() | final, public | Compiler generated |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | getObservableProp | getObservableProp() | final, public | Compiler generated |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | setObservableProp | setObservableProp(java.lang.String) | final, public | Compiler generated |
| delegates.kt:4:18:6:5 | new KProperty1<MyClass,Integer>(...) { ... } | delegates.kt:4:18:6:5 | get | get(MyClass) | override, public | |
| delegates.kt:4:18:6:5 | new KProperty1<MyClass,Integer>(...) { ... } | delegates.kt:4:18:6:5 | invoke | invoke(MyClass) | override, public | |
| delegates.kt:4:26:6:5 | new Function0<Integer>(...) { ... } | delegates.kt:4:26:6:5 | invoke | invoke() | override, public | |
| delegates.kt:4:26:6:5 | new Function0<Integer>(...) { ... } | delegates.kt:4:26:6:5 | invoke | invoke() | final, override, public | |
| delegates.kt:8:32:11:5 | new KMutableProperty1<MyClass,String>(...) { ... } | delegates.kt:8:32:11:5 | get | get(MyClass) | override, public | |
| delegates.kt:8:32:11:5 | new KMutableProperty1<MyClass,String>(...) { ... } | delegates.kt:8:32:11:5 | get | get(MyClass) | override, public | |
| delegates.kt:8:32:11:5 | new KMutableProperty1<MyClass,String>(...) { ... } | delegates.kt:8:32:11:5 | invoke | invoke(MyClass) | override, public | |
| delegates.kt:8:32:11:5 | new KMutableProperty1<MyClass,String>(...) { ... } | delegates.kt:8:32:11:5 | invoke | invoke(MyClass) | override, public | |
| delegates.kt:8:32:11:5 | new KMutableProperty1<MyClass,String>(...) { ... } | delegates.kt:8:32:11:5 | set | set(MyClass,java.lang.String) | override, public | |
| delegates.kt:8:32:11:5 | new KMutableProperty1<MyClass,String>(...) { ... } | delegates.kt:8:32:11:5 | set | set(MyClass,java.lang.String) | override, public | |
| delegates.kt:8:66:11:5 | new Function3<KProperty<?>,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | invoke | invoke(kotlin.reflect.KProperty,java.lang.String,java.lang.String) | override, public | |
| delegates.kt:8:66:11:5 | new Function3<KProperty<?>,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | invoke | invoke(kotlin.reflect.KProperty,java.lang.String,java.lang.String) | final, override, public | |
| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | <clinit> | <clinit>() | static | Compiler generated |
| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated |
| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated |
| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:22:1:31 | getV | getV() | public | Compiler generated |
| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated |
| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | final, public, static | Compiler generated |
| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:22:1:31 | getV | getV() | final, public | Compiler generated |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | <clinit> | <clinit>() | static | Compiler generated |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:13:12:13:29 | f | f(int) | public | |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:14:12:14:29 | g | g(int) | public | |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | values | values() | final, public, static | Compiler generated |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:13:12:13:29 | f | f(int) | abstract, public | |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:14:12:14:29 | g | g(int) | abstract, public | |
| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:9:14:9:30 | f | f(int) | override, public | |
| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:10:14:10:42 | g | g(int) | override, public | |
| methods2.kt:0:0:0:0 | Methods2Kt | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | fooBarTopLevelMethod(int,int) | public, static | |
| methods2.kt:7:1:10:1 | Class2 | methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) | public | |
| methods3.kt:0:0:0:0 | Methods3Kt | methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | public, static | |
| methods3.kt:5:1:7:1 | Class3 | methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | public | |
| methods4.kt:5:3:9:3 | InsideNestedTest | methods4.kt:7:5:7:34 | m | m(foo.bar.NestedTest.InsideNestedTest) | public | |
| methods5.kt:0:0:0:0 | Methods5Kt | methods5.kt:3:1:11:1 | x | x() | public, static | |
| methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | a | a(int) | public | |
| methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | f1 | f1(foo.bar.C1,int) | public | |
| methods6.kt:0:0:0:0 | Methods6Kt | methods6.kt:3:9:4:1 | s | s() | public, static, suspend | |
| methods.kt:0:0:0:0 | MethodsKt | methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) | public, static | |
| methods.kt:5:1:20:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | |
| methods.kt:5:1:20:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | |
| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun$main | internalFun$main() | internal | |
| methods.kt:5:1:20:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:19:12:19:29 | inlineFun | inlineFun() | inline, public | |
| methods2.kt:0:0:0:0 | Methods2Kt | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | fooBarTopLevelMethod(int,int) | final, public, static | |
| methods2.kt:7:1:10:1 | Class2 | methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) | final, public | |
| methods3.kt:0:0:0:0 | Methods3Kt | methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | final, public, static | |
| methods3.kt:5:1:7:1 | Class3 | methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | final, public | |
| methods4.kt:5:3:9:3 | InsideNestedTest | methods4.kt:7:5:7:34 | m | m(foo.bar.NestedTest.InsideNestedTest) | final, public | |
| methods5.kt:0:0:0:0 | Methods5Kt | methods5.kt:3:1:11:1 | x | x() | final, public, static | |
| methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | a | a(int) | final, public | |
| methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | f1 | f1(foo.bar.C1,int) | final, public | |
| methods6.kt:0:0:0:0 | Methods6Kt | methods6.kt:3:9:4:1 | s | s() | final, public, static, suspend | |
| methods.kt:0:0:0:0 | MethodsKt | methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) | final, public, static | |
| methods.kt:5:1:20:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | final, public | |
| methods.kt:5:1:20:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | final, public | |
| methods.kt:5:1:20:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | final, public | |
| methods.kt:5:1:20:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | final, protected | |
| methods.kt:5:1:20:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | final, private | |
| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun$main | internalFun$main() | final, internal | |
| methods.kt:5:1:20:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | final, public | |
| methods.kt:5:1:20:1 | Class | methods.kt:19:12:19:29 | inlineFun | inlineFun() | final, inline, public | |
constructors
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:6:1:47 | DataClass | DataClass(int,java.lang.String) |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:3:1:12:1 | MyClass | MyClass() |

Просмотреть файл

@ -3,18 +3,22 @@
| modifiers.kt:2:5:2:21 | a | Field | final |
| modifiers.kt:2:5:2:21 | a | Field | private |
| modifiers.kt:2:5:2:21 | a | Property | private |
| modifiers.kt:2:13:2:21 | getA$private | Method | final |
| modifiers.kt:2:13:2:21 | getA$private | Method | private |
| modifiers.kt:3:5:3:23 | b | Field | final |
| modifiers.kt:3:5:3:23 | b | Field | private |
| modifiers.kt:3:5:3:23 | b | Property | protected |
| modifiers.kt:3:15:3:23 | getB | Method | final |
| modifiers.kt:3:15:3:23 | getB | Method | protected |
| modifiers.kt:4:5:4:22 | c | Field | final |
| modifiers.kt:4:5:4:22 | c | Field | private |
| modifiers.kt:4:5:4:22 | c | Property | internal |
| modifiers.kt:4:14:4:22 | getC$main | Method | final |
| modifiers.kt:4:14:4:22 | getC$main | Method | internal |
| modifiers.kt:5:5:5:34 | d | Field | final |
| modifiers.kt:5:5:5:34 | d | Field | private |
| modifiers.kt:5:5:5:34 | d | Property | public |
| modifiers.kt:5:5:5:34 | getD | Method | final |
| modifiers.kt:5:5:5:34 | getD | Method | public |
| modifiers.kt:7:5:9:5 | Nested | Class | final |
| modifiers.kt:7:5:9:5 | Nested | Class | protected |
@ -22,29 +26,38 @@
| modifiers.kt:8:9:8:29 | e | Field | final |
| modifiers.kt:8:9:8:29 | e | Field | private |
| modifiers.kt:8:9:8:29 | e | Property | public |
| modifiers.kt:8:16:8:29 | getE | Method | final |
| modifiers.kt:8:16:8:29 | getE | Method | public |
| modifiers.kt:11:5:15:5 | fn1 | Method | final |
| modifiers.kt:11:5:15:5 | fn1 | Method | public |
| modifiers.kt:12:16:14:9 | | Constructor | public |
| modifiers.kt:12:16:14:9 | new Object(...) { ... } | AnonymousClass | final |
| modifiers.kt:12:16:14:9 | new Object(...) { ... } | AnonymousClass | private |
| modifiers.kt:12:16:14:9 | new Object(...) { ... } | LocalClass | final |
| modifiers.kt:12:16:14:9 | new Object(...) { ... } | LocalClass | private |
| modifiers.kt:13:13:13:23 | fn | Method | final |
| modifiers.kt:13:13:13:23 | fn | Method | public |
| modifiers.kt:17:5:20:5 | fn2 | Method | final |
| modifiers.kt:17:5:20:5 | fn2 | Method | public |
| modifiers.kt:18:9:18:24 | | Constructor | public |
| modifiers.kt:18:9:18:24 | | LocalClass | final |
| modifiers.kt:18:9:18:24 | | LocalClass | private |
| modifiers.kt:18:9:18:24 | fnLocal | Method | final |
| modifiers.kt:18:9:18:24 | fnLocal | Method | public |
| modifiers.kt:22:5:24:5 | fn3 | Method | final |
| modifiers.kt:22:5:24:5 | fn3 | Method | public |
| modifiers.kt:23:9:23:27 | localClass | Constructor | public |
| modifiers.kt:23:9:23:27 | localClass | LocalClass | final |
| modifiers.kt:23:9:23:27 | localClass | LocalClass | private |
| modifiers.kt:26:12:26:46 | fn4 | Method | final |
| modifiers.kt:26:12:26:46 | fn4 | Method | inline |
| modifiers.kt:26:12:26:46 | fn4 | Method | public |
| modifiers.kt:26:20:26:41 | f | Parameter | noinline |
| modifiers.kt:27:12:27:49 | fn5 | Method | final |
| modifiers.kt:27:12:27:49 | fn5 | Method | inline |
| modifiers.kt:27:12:27:49 | fn5 | Method | public |
| modifiers.kt:27:20:27:44 | f | Parameter | crossinline |
| modifiers.kt:28:12:28:39 | fn6 | Method | final |
| modifiers.kt:28:12:28:39 | fn6 | Method | inline |
| modifiers.kt:28:12:28:39 | fn6 | Method | public |
| modifiers.kt:28:17:28:25 | T | TypeVariable | reified |
@ -57,6 +70,7 @@
| modifiers.kt:31:1:33:1 | Y | ParameterizedType | public |
| modifiers.kt:31:9:31:13 | T1 | TypeVariable | in |
| modifiers.kt:31:16:31:21 | T2 | TypeVariable | out |
| modifiers.kt:32:5:32:32 | foo | Method | final |
| modifiers.kt:32:5:32:32 | foo | Method | public |
| modifiers.kt:35:1:41:1 | LateInit | Class | final |
| modifiers.kt:35:1:41:1 | LateInit | Class | public |
@ -64,7 +78,10 @@
| modifiers.kt:36:5:36:40 | test0 | Field | private |
| modifiers.kt:36:5:36:40 | test0 | Property | lateinit |
| modifiers.kt:36:5:36:40 | test0 | Property | private |
| modifiers.kt:36:22:36:40 | getTest0$private | Method | final |
| modifiers.kt:36:22:36:40 | getTest0$private | Method | private |
| modifiers.kt:36:22:36:40 | setTest0$private | Method | final |
| modifiers.kt:36:22:36:40 | setTest0$private | Method | private |
| modifiers.kt:38:5:40:5 | fn | Method | final |
| modifiers.kt:38:5:40:5 | fn | Method | public |
| modifiers.kt:39:22:39:26 | LateInit test1 | LocalVariableDecl | lateinit |

Просмотреть файл

@ -0,0 +1,44 @@
from pathlib import Path
import re
import sys
from typing import Dict, List, Optional
ID = re.compile(r" +\* +@id\s*(.*)")
def get_query_id(query_path: Path) -> Optional[str]:
with open(query_path) as f:
for line in f:
m = ID.match(line)
if m:
return m.group(1)
return None
def main():
# Map query IDs to paths of queries with those IDs. We want to check that this is a 1:1 map.
query_ids: Dict[str, List[str]] = {}
# Just check src folders for now to avoid churn
for query_path in Path().glob("**/src/**/*.ql"):
# Skip compiled query packs
if any(p == ".codeql" for p in query_path.parts):
continue
query_id = get_query_id(query_path)
if query_id is not None:
query_ids.setdefault(query_id, []).append(str(query_path))
fail = False
for query_id, query_paths in query_ids.items():
if len(query_paths) > 1:
fail = True
print(f"Query ID {query_id} is used in multiple queries:")
for query_path in query_paths:
print(f" - {query_path}")
if fail:
print("FAIL: duplicate query IDs found in src folders. Please assign these queries unique IDs.")
sys.exit(1)
else:
print("PASS: no duplicate query IDs found in src folders.")
if __name__ == "__main__":
main()

Просмотреть файл

@ -1,6 +1,7 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<!-- Disabled since it refers to examples which do not exist. -->
<qhelp>
<overview>

Просмотреть файл

@ -4,7 +4,7 @@
* destination file path is within the destination directory can cause files outside
* the destination directory to be overwritten.
* @kind path-problem
* @id py/tarslip
* @id py/tarslip-extended
* @problem.severity error
* @security-severity 7.5
* @precision high

Просмотреть файл

@ -6,7 +6,7 @@
* @problem.severity error
* @security-severity 2.9
* @sub-severity high
* @id py/reflective-xss
* @id py/reflective-xss-email
* @tags security
* external/cwe/cwe-079
* external/cwe/cwe-116

Просмотреть файл

@ -4,7 +4,9 @@ import codeql.ruby.AST
import codeql.ruby.DataFlow
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowDispatch
private import internal.DataFlowImplCommon as DataFlowImplCommon
private import internal.DataFlowPrivate
private import internal.FlowSummaryImplSpecific
// import all instances below
private module Summaries {
@ -127,6 +129,17 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari
*/
pragma[nomagic]
predicate propagatesFlowExt(string input, string output, boolean preservesValue) { none() }
/**
* Gets the synthesized parameter that results from an input specification
* that starts with `Argument[s]` for this library callable.
*/
DataFlow::ParameterNode getParameter(string s) {
exists(ParameterPosition pos |
DataFlowImplCommon::parameterNode(result, TLibraryCallable(this), pos) and
s = getParameterPositionCsv(pos)
)
}
}
/**

Просмотреть файл

@ -145,19 +145,32 @@ string getComponentSpecificCsv(SummaryComponent sc) { none() }
/** Gets the textual representation of a parameter position in the format used for flow summaries. */
string getParameterPositionCsv(ParameterPosition pos) {
pos.isSelf() and result = "self"
or
pos.isBlock() and result = "block"
or
exists(int i |
pos.isPositional(i) and
result = i.toString()
)
or
exists(int i |
pos.isPositionalLowerBound(i) and
result = i + ".."
)
or
exists(string name |
pos.isKeyword(name) and
result = name + ":"
)
or
pos.isSelf() and
result = "self"
or
pos.isBlock() and
result = "block"
or
pos.isAny() and
result = "any"
or
pos.isAnyNamed() and
result = "any-named"
}
/** Gets the textual representation of an argument position in the format used for flow summaries. */

Просмотреть файл

@ -12,7 +12,7 @@
#include "swift/extractor/translators/SwiftVisitor.h"
#include "swift/extractor/TargetTrapFile.h"
#include "swift/extractor/SwiftBuiltinSymbols.h"
#include "swift/extractor/infra/Path.h"
#include "swift/extractor/infra/file/Path.h"
using namespace codeql;
using namespace std::string_literals;
@ -28,27 +28,23 @@ static void ensureDirectory(const char* label, const fs::path& dir) {
}
static void archiveFile(const SwiftExtractorConfiguration& config, swift::SourceFile& file) {
ensureDirectory("TRAP", config.trapDir);
ensureDirectory("source archive", config.sourceArchiveDir);
auto source = codeql::resolvePath(file.getFilename());
auto destination = config.sourceArchiveDir / source.relative_path();
fs::path srcFilePath = codeql::getCodeQLPath(file.getFilename());
auto dstFilePath = config.sourceArchiveDir;
dstFilePath += srcFilePath;
ensureDirectory("source archive destination", dstFilePath.parent_path());
ensureDirectory("source archive destination", destination.parent_path());
std::error_code ec;
fs::copy(srcFilePath, dstFilePath, fs::copy_options::overwrite_existing, ec);
fs::copy(source, destination, fs::copy_options::overwrite_existing, ec);
if (ec) {
std::cerr << "Cannot archive source file " << srcFilePath << " -> " << dstFilePath << ": "
std::cerr << "Cannot archive source file " << source << " -> " << destination << ": "
<< ec.message() << "\n";
}
}
static fs::path getFilename(swift::ModuleDecl& module, swift::SourceFile* primaryFile) {
if (primaryFile) {
return primaryFile->getFilename().str();
return resolvePath(primaryFile->getFilename());
}
// PCM clang module
if (module.isNonSwiftModule()) {
@ -57,7 +53,7 @@ static fs::path getFilename(swift::ModuleDecl& module, swift::SourceFile* primar
// Moreover, pcm files may come from caches located in different directories, but are
// unambiguously identified by the base file name, so we can discard the absolute directory
fs::path filename = "/pcms";
filename /= getCodeQLPath(module.getModuleFilename()).filename();
filename /= fs::path{std::string_view{module.getModuleFilename()}}.filename();
filename += "-";
filename += module.getName().str();
return filename;
@ -66,13 +62,13 @@ static fs::path getFilename(swift::ModuleDecl& module, swift::SourceFile* primar
// The Builtin module has an empty filename, let's fix that
return "/__Builtin__";
}
auto filename = getCodeQLPath(module.getModuleFilename());
std::string_view filename = module.getModuleFilename();
// there is a special case of a module without an actual filename reporting `<imports>`: in this
// case we want to avoid the `<>` characters, in case a dirty DB is imported on Windows
if (filename == "<imports>") {
return "/__imports__";
}
return filename;
return resolvePath(filename);
}
/* The builtin module is special, as it does not publish any top-level declaration

Просмотреть файл

@ -1,7 +0,0 @@
#pragma once
#include <filesystem>
namespace codeql {
std::filesystem::path getCodeQLPath(std::string_view path);
}

Просмотреть файл

@ -5,7 +5,7 @@
#include "swift/extractor/trap/generated/TrapEntries.h"
#include "swift/extractor/trap/generated/TrapClasses.h"
#include "swift/extractor/infra/SwiftLocationExtractor.h"
#include "swift/extractor/infra/Path.h"
#include "swift/extractor/infra/file/Path.h"
using namespace codeql;
@ -17,7 +17,7 @@ void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceMa
// invalid locations seem to come from entities synthesized by the compiler
return;
}
auto file = getCodeQLPath(sourceManager.getDisplayNameForLoc(start));
auto file = resolvePath(sourceManager.getDisplayNameForLoc(start));
DbLocation entry{{}};
entry.file = fetchFileLabel(file);
std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start);
@ -30,7 +30,7 @@ void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceMa
}
void SwiftLocationExtractor::emitFile(llvm::StringRef path) {
fetchFileLabel(getCodeQLPath(path));
fetchFileLabel(resolvePath(path));
}
TrapLabel<FileTag> SwiftLocationExtractor::fetchFileLabel(const std::filesystem::path& file) {

Просмотреть файл

@ -1,4 +1,4 @@
#include "swift/extractor/infra/Path.h"
#include "swift/extractor/infra/file/Path.h"
#include <iostream>
#include <unistd.h>
@ -16,7 +16,7 @@ static bool shouldCanonicalize() {
return true;
}
std::filesystem::path getCodeQLPath(std::string_view path) {
std::filesystem::path resolvePath(std::string_view path) {
std::error_code ec;
std::filesystem::path ret = {};
static const auto canonicalize = shouldCanonicalize();
@ -28,7 +28,7 @@ std::filesystem::path getCodeQLPath(std::string_view path) {
if (ec) {
std::cerr << "Cannot get " << (canonicalize ? "canonical" : "absolute")
<< " path: " << std::quoted(path) << ": " << ec.message() << "\n";
return {};
return path;
}
return ret;
}

Просмотреть файл

@ -0,0 +1,7 @@
#pragma once
#include <filesystem>
namespace codeql {
std::filesystem::path resolvePath(std::string_view path);
}

Просмотреть файл

@ -5,4 +5,5 @@
| E.swift:0:0:0:0 | E.swift |
| F1.swift:0:0:0:0 | F1.swift |
| F2.swift:0:0:0:0 | F2.swift |
| G.swift:0:0:0:0 | G.swift |
| file://:0:0:0:0 | |

Просмотреть файл

Просмотреть файл

@ -16,3 +16,4 @@ $FRONTEND -frontend -c -primary-file E.swift Esup.swift -o E.o $SDK
$FRONTEND -frontend -emit-module -primary-file F1.swift F2.swift -module-name F -o F1.swiftmodule $SDK
$FRONTEND -frontend -emit-module F1.swift -primary-file F2.swift -module-name F -o F2.swiftmodule $SDK
$FRONTEND -frontend -merge-modules F1.swiftmodule F2.swiftmodule -o F.swiftmodule $SDK
( cd dir; $FRONTEND -frontend -c ../G.swift $SDK )

Просмотреть файл

Просмотреть файл

@ -9,19 +9,42 @@
import swift
import codeql.swift.dataflow.FlowSources
import codeql.swift.security.SensitiveExprs
import codeql.swift.dataflow.DataFlow
import codeql.swift.dataflow.TaintTracking
predicate statistic(string what, int value) {
what = "Files" and value = count(File f)
or
what = "Expressions" and value = count(Expr e | not e.getFile() instanceof UnknownFile)
or
what = "Local flow sources" and value = count(LocalFlowSource s)
or
what = "Remote flow sources" and value = count(RemoteFlowSource s)
or
what = "Sensitive expressions" and value = count(SensitiveExpr e)
/**
* A taint configuration for tainted data reaching any node.
*/
class TaintReachConfig extends TaintTracking::Configuration {
TaintReachConfig() { this = "TaintReachConfig" }
override predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
override predicate isSink(DataFlow::Node node) { any() }
}
from string what, int value
float taintReach() {
exists(TaintReachConfig config, int tainted, int total |
tainted = count(DataFlow::Node n | config.hasFlowTo(n)) and
total = count(DataFlow::Node n) and
result = (tainted * 1000000.0) / total
)
}
predicate statistic(string what, string value) {
what = "Files" and value = count(File f).toString()
or
what = "Expressions" and value = count(Expr e | not e.getFile() instanceof UnknownFile).toString()
or
what = "Local flow sources" and value = count(LocalFlowSource s).toString()
or
what = "Remote flow sources" and value = count(RemoteFlowSource s).toString()
or
what = "Sensitive expressions" and value = count(SensitiveExpr e).toString()
or
what = "Taint reach (per million nodes)" and value = taintReach().toString()
}
from string what, string value
where statistic(what, value)
select what, value

Просмотреть файл

@ -1,9 +1,3 @@
#-----| [ModuleDecl] __ObjC
#-----| [ModuleDecl] cfg
#-----| [ModuleDecl] declarations
#-----| [ModuleDecl] expressions
#-----| [ModuleDecl] patterns
#-----| [ModuleDecl] statements
cfg.swift:
# 1| [TopLevelCodeDecl] { ... }
# 1| getBody(): [BraceStmt] { ... }

Просмотреть файл

@ -10,5 +10,7 @@ import TestUtils
* The hook to customize the entities printed by this query.
*/
class PrintAstConfigurationOverride extends PrintAstConfiguration {
override predicate shouldPrint(Locatable e) { super.shouldPrint(e) and toBeTested(e) }
override predicate shouldPrint(Locatable e) {
super.shouldPrint(e) and toBeTested(e) and not e instanceof ModuleDecl
}
}