mirror of
https://github.com/github/codeql.git
synced 2026-01-27 05:13:00 +01:00
Merge pull request #1445 from esben-semmle/mb/rc-1.21/06-12
Approved by aschackmull, jbj, xiemaisi
This commit is contained in:
@@ -60,27 +60,14 @@ private cached module Cached {
|
||||
not n2 instanceof PrimitiveBasicBlock
|
||||
}
|
||||
|
||||
/** Returns the index of `node` in its `PrimitiveBasicBlock`. */
|
||||
private int getMemberIndex(Node node) {
|
||||
primitive_basic_block_entry_node(node) and
|
||||
result = 0
|
||||
or
|
||||
exists(Node prev |
|
||||
member_step(prev, node) and
|
||||
result = getMemberIndex(prev) + 1
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `node` is the `pos`th control-flow node in primitive basic block `bb`. */
|
||||
cached
|
||||
predicate primitive_basic_block_member(Node node, PrimitiveBasicBlock bb, int pos) {
|
||||
primitive_basic_block_entry_node(bb) and
|
||||
(
|
||||
pos = 0 and
|
||||
node = bb
|
||||
or
|
||||
pos = getMemberIndex(node) and
|
||||
member_step+(bb, node)
|
||||
primitive_basic_block_entry_node(bb) and node = bb and pos = 0
|
||||
or
|
||||
exists(Node prev |
|
||||
member_step(prev, node) and
|
||||
primitive_basic_block_member(prev, bb, pos - 1)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
54
java/ql/src/semmle/code/java/frameworks/android/Android.qll
Normal file
54
java/ql/src/semmle/code/java/frameworks/android/Android.qll
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Provides classes and predicates for working with Android components.
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.xml.AndroidManifest
|
||||
|
||||
/**
|
||||
* An Android component. That is, either an activity, a service,
|
||||
* a broadcast receiver, or a content provider.
|
||||
*/
|
||||
class AndroidComponent extends Class {
|
||||
AndroidComponent() {
|
||||
this.getASupertype*().hasQualifiedName("android.app", "Activity") or
|
||||
this.getASupertype*().hasQualifiedName("android.app", "Service") or
|
||||
this.getASupertype*().hasQualifiedName("android.content", "BroadcastReceiver") or
|
||||
this.getASupertype*().hasQualifiedName("android.content", "ContentProvider")
|
||||
}
|
||||
|
||||
/** The XML element corresponding to this Android component. */
|
||||
AndroidComponentXmlElement getAndroidComponentXmlElement() {
|
||||
result.getResolvedComponentName() = this.getQualifiedName()
|
||||
}
|
||||
|
||||
/** Holds if this Android component is configured as `exported` in an `AndroidManifest.xml` file. */
|
||||
predicate isExported() { getAndroidComponentXmlElement().isExported() }
|
||||
|
||||
/** Holds if this Android component has an intent filter configured in an `AndroidManifest.xml` file. */
|
||||
predicate hasIntentFilter() { exists(getAndroidComponentXmlElement().getAnIntentFilterElement()) }
|
||||
}
|
||||
|
||||
/** An Android activity. */
|
||||
class AndroidActivity extends AndroidComponent {
|
||||
AndroidActivity() { this.getASupertype*().hasQualifiedName("android.app", "Activity") }
|
||||
}
|
||||
|
||||
/** An Android service. */
|
||||
class AndroidService extends AndroidComponent {
|
||||
AndroidService() { this.getASupertype*().hasQualifiedName("android.app", "Service") }
|
||||
}
|
||||
|
||||
/** An Android broadcast receiver. */
|
||||
class AndroidBroadcastReceiver extends AndroidComponent {
|
||||
AndroidBroadcastReceiver() {
|
||||
this.getASupertype*().hasQualifiedName("android.content", "BroadcastReceiver")
|
||||
}
|
||||
}
|
||||
|
||||
/** An Android content provider. */
|
||||
class AndroidContentProvider extends AndroidComponent {
|
||||
AndroidContentProvider() {
|
||||
this.getASupertype*().hasQualifiedName("android.content", "ContentProvider")
|
||||
}
|
||||
}
|
||||
178
java/ql/src/semmle/code/xml/AndroidManifest.qll
Normal file
178
java/ql/src/semmle/code/xml/AndroidManifest.qll
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Provides classes and predicates for working with Android manifest files.
|
||||
*/
|
||||
|
||||
import XML
|
||||
|
||||
/**
|
||||
* An Android manifest file, named `AndroidManifest.xml`.
|
||||
*/
|
||||
class AndroidManifestXmlFile extends XMLFile {
|
||||
AndroidManifestXmlFile() {
|
||||
this.getBaseName() = "AndroidManifest.xml" and
|
||||
count(XMLElement e | e = this.getAChild()) = 1 and
|
||||
this.getAChild().getName() = "manifest"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the top-level `<manifest>` element in this Android manifest file.
|
||||
*/
|
||||
AndroidManifestXmlElement getManifestElement() { result = this.getAChild() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `<manifest>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidManifestXmlElement extends XMLElement {
|
||||
AndroidManifestXmlElement() {
|
||||
this.getParent() instanceof AndroidManifestXmlFile and this.getName() = "manifest"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `<application>` child element of this `<manifest>` element.
|
||||
*/
|
||||
AndroidApplicationXmlElement getApplicationElement() { result = this.getAChild() }
|
||||
|
||||
/**
|
||||
* Gets the value of the `package` attribute of this `<manifest>` element.
|
||||
*/
|
||||
string getPackageAttributeValue() { result = getAttributeValue("package") }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `<application>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidApplicationXmlElement extends XMLElement {
|
||||
AndroidApplicationXmlElement() {
|
||||
this.getParent() instanceof AndroidManifestXmlElement and this.getName() = "application"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a component child element of this `<application>` element.
|
||||
*/
|
||||
AndroidComponentXmlElement getAComponentElement() { result = this.getAChild() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `<activity>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidActivityXmlElement extends AndroidComponentXmlElement {
|
||||
AndroidActivityXmlElement() { this.getName() = "activity" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `<service>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidServiceXmlElement extends AndroidComponentXmlElement {
|
||||
AndroidServiceXmlElement() { this.getName() = "service" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `<receiver>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidReceiverXmlElement extends AndroidComponentXmlElement {
|
||||
AndroidReceiverXmlElement() { this.getName() = "receiver" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `<provider>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidProviderXmlElement extends AndroidComponentXmlElement {
|
||||
AndroidProviderXmlElement() { this.getName() = "provider" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An Android component element in an Android manifest file.
|
||||
*/
|
||||
class AndroidComponentXmlElement extends XMLElement {
|
||||
AndroidComponentXmlElement() {
|
||||
this.getParent() instanceof AndroidApplicationXmlElement and
|
||||
this.getName().regexpMatch("(activity|service|receiver|provider)")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an `<intent-filter>` child element of this component element.
|
||||
*/
|
||||
AndroidIntentFilterXmlElement getAnIntentFilterElement() { result = this.getAChild() }
|
||||
|
||||
/**
|
||||
* Gets the value of the `android:name` attribute of this component element.
|
||||
*/
|
||||
string getComponentName() {
|
||||
exists(XMLAttribute attr |
|
||||
attr = getAnAttribute() and
|
||||
attr.getNamespace().getPrefix() = "android" and
|
||||
attr.getName() = "name"
|
||||
|
|
||||
result = attr.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resolved value of the `android:name` attribute of this component element.
|
||||
*/
|
||||
string getResolvedComponentName() {
|
||||
if getComponentName().matches(".%")
|
||||
then
|
||||
result = getParent()
|
||||
.(XMLElement)
|
||||
.getParent()
|
||||
.(AndroidManifestXmlElement)
|
||||
.getPackageAttributeValue() + getComponentName()
|
||||
else result = getComponentName()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the `android:exported` attribute of this component element.
|
||||
*/
|
||||
string getExportedAttributeValue() {
|
||||
exists(XMLAttribute attr |
|
||||
attr = getAnAttribute() and
|
||||
attr.getNamespace().getPrefix() = "android" and
|
||||
attr.getName() = "exported"
|
||||
|
|
||||
result = attr.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `android:exported` attribute of this component element is `true`.
|
||||
*/
|
||||
predicate isExported() { getExportedAttributeValue() = "true" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `<intent-filter>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidIntentFilterXmlElement extends XMLElement {
|
||||
AndroidIntentFilterXmlElement() {
|
||||
this.getFile() instanceof AndroidManifestXmlFile and this.getName() = "intent-filter"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an `<action>` child element of this `<intent-filter>` element.
|
||||
*/
|
||||
AndroidActionXmlElement getAnActionElement() { result = this.getAChild() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `<action>` element in an Android manifest file.
|
||||
*/
|
||||
class AndroidActionXmlElement extends XMLElement {
|
||||
AndroidActionXmlElement() {
|
||||
this.getFile() instanceof AndroidManifestXmlFile and this.getName() = "action"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this action.
|
||||
*/
|
||||
string getActionName() {
|
||||
exists(XMLAttribute attr |
|
||||
attr = getAnAttribute() and
|
||||
attr.getNamespace().getPrefix() = "android" and
|
||||
attr.getName() = "name"
|
||||
|
|
||||
result = attr.getValue()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0"
|
||||
package="com.example.myapp">
|
||||
|
||||
<!-- Beware that these values are overridden by the build.gradle file -->
|
||||
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<!-- This name is resolved to com.example.myapp.MainActivity
|
||||
based upon the package attribute -->
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".DisplayMessageActivity"
|
||||
android:parentActivityName=".MainActivity" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
<!--
|
||||
/*
|
||||
* This file is licensed under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
@@ -0,0 +1 @@
|
||||
class Test {}
|
||||
@@ -0,0 +1 @@
|
||||
| com.example.myapp.MainActivity | android.intent.action.MAIN |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
import semmle.code.xml.AndroidManifest
|
||||
|
||||
from AndroidActivityXmlElement e
|
||||
select e.getResolvedComponentName(), e.getAnIntentFilterElement().getAnActionElement().getActionName()
|
||||
@@ -0,0 +1,3 @@
|
||||
| test1.js:13:16:13:30 | process.argv[2] | test1.js:6:15:6:15 | p |
|
||||
| test2.js:20:16:20:30 | process.argv[2] | test2.js:13:15:13:15 | p |
|
||||
| test3.js:19:16:19:30 | process.argv[2] | test3.js:12:15:12:15 | p |
|
||||
@@ -0,0 +1,17 @@
|
||||
import javascript
|
||||
|
||||
class CommandLineFileNameConfiguration extends TaintTracking::Configuration {
|
||||
CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink
|
||||
}
|
||||
}
|
||||
|
||||
from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink
|
||||
where cfg.hasFlow(source, sink)
|
||||
select source, sink
|
||||
@@ -0,0 +1,2 @@
|
||||
| test1.js:13:16:13:30 | process.argv[2] | test1.js:6:15:6:15 | p |
|
||||
| test3.js:19:16:19:30 | process.argv[2] | test3.js:12:15:12:15 | p |
|
||||
@@ -0,0 +1,21 @@
|
||||
import javascript
|
||||
|
||||
class CommandLineFileNameConfiguration extends TaintTracking::Configuration {
|
||||
CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node nd) {
|
||||
nd.(DataFlow::CallNode).getCalleeName() = "checkPath"
|
||||
}
|
||||
}
|
||||
|
||||
from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink
|
||||
where cfg.hasFlow(source, sink)
|
||||
select source, sink
|
||||
@@ -0,0 +1,2 @@
|
||||
| test1.js:13:16:13:30 | process.argv[2] | test1.js:6:15:6:15 | p |
|
||||
| test2.js:20:16:20:30 | process.argv[2] | test2.js:13:15:13:15 | p |
|
||||
@@ -0,0 +1,30 @@
|
||||
import javascript
|
||||
|
||||
class CheckPathSanitizerGuard extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode {
|
||||
CheckPathSanitizerGuard() { this.getCalleeName() = "checkPath" }
|
||||
|
||||
override predicate sanitizes(boolean outcome, Expr e) {
|
||||
outcome = true and
|
||||
e = getArgument(0).asExpr()
|
||||
}
|
||||
}
|
||||
|
||||
class CommandLineFileNameConfiguration extends TaintTracking::Configuration {
|
||||
CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode nd) {
|
||||
nd instanceof CheckPathSanitizerGuard
|
||||
}
|
||||
}
|
||||
|
||||
from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink
|
||||
where cfg.hasFlow(source, sink)
|
||||
select source, sink
|
||||
@@ -0,0 +1,4 @@
|
||||
| test1.js:13:16:13:30 | process.argv[2] | test1.js:6:15:6:15 | p |
|
||||
| test2.js:20:16:20:30 | process.argv[2] | test2.js:13:15:13:15 | p |
|
||||
| test3.js:19:16:19:30 | process.argv[2] | test3.js:12:15:12:15 | p |
|
||||
| test4.js:14:16:14:30 | process.argv[2] | test4.js:7:13:7:13 | p |
|
||||
@@ -0,0 +1,25 @@
|
||||
import javascript
|
||||
|
||||
class CommandLineFileNameConfiguration extends TaintTracking::Configuration {
|
||||
CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::CallNode c |
|
||||
c = DataFlow::moduleImport("resolve-symlinks").getACall() and
|
||||
pred = c.getArgument(0) and
|
||||
succ = c
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink
|
||||
where cfg.hasFlow(source, sink)
|
||||
select source, sink
|
||||
@@ -0,0 +1,4 @@
|
||||
| test1.js:13:16:13:30 | process.argv[2] | test1.js:6:15:6:15 | p |
|
||||
| test2.js:20:16:20:30 | process.argv[2] | test2.js:13:15:13:15 | p |
|
||||
| test3.js:19:16:19:30 | process.argv[2] | test3.js:12:15:12:15 | p |
|
||||
| test4.js:14:16:14:30 | process.argv[2] | test4.js:7:13:7:13 | p |
|
||||
@@ -0,0 +1,26 @@
|
||||
import javascript
|
||||
|
||||
class StepThroughResolveSymlinks extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
|
||||
StepThroughResolveSymlinks() { this = DataFlow::moduleImport("resolve-symlinks").getACall() }
|
||||
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
pred = this.getArgument(0) and
|
||||
succ = this
|
||||
}
|
||||
}
|
||||
|
||||
class CommandLineFileNameConfiguration extends TaintTracking::Configuration {
|
||||
CommandLineFileNameConfiguration() { this = "CommandLineFileNameConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyRead() = source
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
DataFlow::moduleMember("fs", "readFile").getACall().getArgument(0) = sink
|
||||
}
|
||||
}
|
||||
|
||||
from CommandLineFileNameConfiguration cfg, DataFlow::Node source, DataFlow::Node sink
|
||||
where cfg.hasFlow(source, sink)
|
||||
select source, sink
|
||||
@@ -0,0 +1,13 @@
|
||||
const fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
function readFileHelper(p) { // #2
|
||||
p = path.resolve(p); // #3
|
||||
fs.readFile(p, // #4
|
||||
'utf8', (err, data) => {
|
||||
if (err) throw err;
|
||||
console.log(data);
|
||||
});
|
||||
}
|
||||
|
||||
readFileHelper(process.argv[2]); // #1
|
||||
@@ -0,0 +1,20 @@
|
||||
const fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
function checkPath(p) {
|
||||
p = path.resolve(p);
|
||||
if (!p.startsWith(process.cwd() + path.sep))
|
||||
throw new Error("Invalid path " + p);
|
||||
return p;
|
||||
}
|
||||
|
||||
function readFileHelper(p) {
|
||||
p = checkPath(p);
|
||||
fs.readFile(p,
|
||||
'utf8', (err, data) => {
|
||||
if (err) throw err;
|
||||
console.log(data);
|
||||
});
|
||||
}
|
||||
|
||||
readFileHelper(process.argv[2]);
|
||||
@@ -0,0 +1,19 @@
|
||||
const fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
function checkPath(p) {
|
||||
p = path.resolve(p);
|
||||
return p.startsWith(process.cwd() + path.sep);
|
||||
}
|
||||
|
||||
function readFileHelper(p) {
|
||||
if (!checkPath(p))
|
||||
return;
|
||||
fs.readFile(p,
|
||||
'utf8', (err, data) => {
|
||||
if (err) throw err;
|
||||
console.log(data);
|
||||
});
|
||||
}
|
||||
|
||||
readFileHelper(process.argv[2]);
|
||||
@@ -0,0 +1,14 @@
|
||||
const fs = require('fs'),
|
||||
path = require('path'),
|
||||
resolveSymlinks = require('resolve-symlinks');
|
||||
|
||||
function readFileHelper(p) {
|
||||
p = resolveSymlinks(p);
|
||||
fs.readFile(p,
|
||||
'utf8', (err, data) => {
|
||||
if (err) throw err;
|
||||
console.log(data);
|
||||
});
|
||||
}
|
||||
|
||||
readFileHelper(process.argv[2]);
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.js:4:5:4:22 | firstArg |
|
||||
| test.js:4:16:4:22 | args[2] |
|
||||
| test.js:5:13:5:20 | firstArg |
|
||||
@@ -0,0 +1,7 @@
|
||||
import javascript
|
||||
|
||||
from DataFlow::MethodCallNode readFile, DataFlow::Node source
|
||||
where
|
||||
readFile.getMethodName() = "readFile" and
|
||||
source.getASuccessor*() = readFile.getArgument(0)
|
||||
select source
|
||||
@@ -0,0 +1 @@
|
||||
| test.js:4:16:4:22 | args[2] |
|
||||
@@ -0,0 +1,3 @@
|
||||
import javascript
|
||||
|
||||
select DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyReference()
|
||||
@@ -0,0 +1 @@
|
||||
| test.js:5:1:8:2 | fs.read ... ta);\\n}) |
|
||||
@@ -0,0 +1,3 @@
|
||||
import javascript
|
||||
|
||||
select DataFlow::moduleMember("fs", "readFile").getACall()
|
||||
@@ -0,0 +1 @@
|
||||
| test.js:4:16:4:22 | args[2] | test.js:5:1:8:2 | fs.read ... ta);\\n}) |
|
||||
@@ -0,0 +1,8 @@
|
||||
import javascript
|
||||
|
||||
from DataFlow::SourceNode arg, DataFlow::CallNode call
|
||||
where
|
||||
arg = DataFlow::globalVarRef("process").getAPropertyRead("argv").getAPropertyReference() and
|
||||
call = DataFlow::moduleMember("fs", "readFile").getACall() and
|
||||
arg.flowsTo(call.getArgument(0))
|
||||
select arg, call
|
||||
@@ -0,0 +1,8 @@
|
||||
var fs = require('fs');
|
||||
|
||||
var args = process.argv;
|
||||
var firstArg = args[2];
|
||||
fs.readFile(firstArg, 'utf8', (err, data) => {
|
||||
if (err) throw err;
|
||||
console.log(data);
|
||||
});
|
||||
@@ -356,7 +356,8 @@ cached module SsaSource {
|
||||
/** Holds if `v` is used as the receiver in a method call. */
|
||||
cached predicate method_call_refinement(Variable v, ControlFlowNode use, CallNode call) {
|
||||
use = v.getAUse() and
|
||||
call.getFunction().(AttrNode).getObject() = use
|
||||
call.getFunction().(AttrNode).getObject() = use and
|
||||
not test_contains(_, call)
|
||||
}
|
||||
|
||||
/** Holds if `v` is defined by assignment at `defn` and given `value`. */
|
||||
|
||||
@@ -155,7 +155,12 @@ class PackageObjectInternal extends ModuleObjectInternal, TPackageObject {
|
||||
|
||||
/** Gets the submodule `name` of this package */
|
||||
ModuleObjectInternal submodule(string name) {
|
||||
result.getName() = this.getName() + "." + name
|
||||
exists(string fullName, int lastDotIndex |
|
||||
fullName = result.getName() and
|
||||
lastDotIndex = max(fullName.indexOf(".")) and
|
||||
name = fullName.substring(lastDotIndex + 1, fullName.length()) and
|
||||
this.getName() = fullName.substring(0, lastDotIndex)
|
||||
)
|
||||
}
|
||||
|
||||
override int intValue() {
|
||||
|
||||
@@ -170,6 +170,11 @@ module PointsTo {
|
||||
|
||||
cached module PointsToInternal {
|
||||
|
||||
pragma[noinline]
|
||||
cached predicate importCtxPointsTo(ControlFlowNode f, ObjectInternal value, ControlFlowNode origin) {
|
||||
PointsToInternal::pointsTo(f, any(Context ctx | ctx.isImport()), value, origin)
|
||||
}
|
||||
|
||||
/** INTERNAL -- Use `f.refersTo(value, origin)` instead. */
|
||||
cached predicate pointsTo(ControlFlowNode f, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
points_to_candidate(f, context, value, origin) and
|
||||
@@ -695,7 +700,7 @@ private module InterModulePointsTo {
|
||||
predicate ofInterestInExports(ModuleObjectInternal mod, string name) {
|
||||
exists(ImportStarNode imp, ImportStarRefinement def, EssaVariable var |
|
||||
imp = def.getDefiningNode() and
|
||||
PointsToInternal::pointsTo(imp.getModule(), any(Context ctx | ctx.isImport()), mod, _) and
|
||||
PointsToInternal::importCtxPointsTo(imp.getModule(), mod, _) and
|
||||
var = def.getVariable()
|
||||
|
|
||||
if var.isMetaVariable() then (
|
||||
@@ -891,7 +896,7 @@ module InterProceduralPointsTo {
|
||||
/** Helper for parameter_points_to */
|
||||
pragma [noinline]
|
||||
private predicate default_parameter_points_to(ParameterDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
|
||||
exists(PointsToContext imp | imp.isImport() | PointsToInternal::pointsTo(def.getDefault(), imp, value, origin)) and
|
||||
PointsToInternal::importCtxPointsTo(def.getDefault(), value, origin) and
|
||||
context_for_default_value(def, context)
|
||||
}
|
||||
|
||||
@@ -2211,7 +2216,7 @@ cached module ModuleAttributes {
|
||||
private predicate importStarDef(ImportStarRefinement def, EssaVariable input, ModuleObjectInternal mod) {
|
||||
exists(ImportStarNode imp |
|
||||
def.getVariable().getName() = "$" and imp = def.getDefiningNode() and
|
||||
input = def.getInput() and PointsToInternal::pointsTo(imp.getModule(), any(Context ctx | ctx.isImport()), mod, _)
|
||||
input = def.getInput() and PointsToInternal::importCtxPointsTo(imp.getModule(), mod, _)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -46,14 +46,6 @@
|
||||
| Module six | iterlists | Function iterlists |
|
||||
| Module six | itervalues | Function itervalues |
|
||||
| Module six | moves | Module six.moves |
|
||||
| Module six | moves.__init__ | Module six.moves.__init__ |
|
||||
| Module six | moves.urllib | Module six.moves.urllib |
|
||||
| Module six | moves.urllib.__init__ | Module six.moves.urllib.__init__ |
|
||||
| Module six | moves.urllib_error | Module six.moves.urllib_error |
|
||||
| Module six | moves.urllib_parse | Module six.moves.urllib_parse |
|
||||
| Module six | moves.urllib_request | Module six.moves.urllib_request |
|
||||
| Module six | moves.urllib_response | Module six.moves.urllib_response |
|
||||
| Module six | moves.urllib_robotparser | Module six.moves.urllib_robotparser |
|
||||
| Module six | next | Builtin-function next |
|
||||
| Module six | operator | Module operator |
|
||||
| Module six | print_ | Function print_ |
|
||||
@@ -174,7 +166,6 @@
|
||||
| Module six.moves | tkinter_tksimpledialog | Module tkinter.simpledialog |
|
||||
| Module six.moves | tkinter_ttk | Module tkinter.ttk |
|
||||
| Module six.moves | urllib | Module six.moves.urllib |
|
||||
| Module six.moves | urllib.__init__ | Module six.moves.urllib.__init__ |
|
||||
| Module six.moves | urllib_error | Module six.moves.urllib_error |
|
||||
| Module six.moves | urllib_parse | Module six.moves.urllib_parse |
|
||||
| Module six.moves | urllib_request | Module six.moves.urllib_request |
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
| b_condition.py:0 | h_0 = ScopeEntryDefinition |
|
||||
| b_condition.py:0 | k_0 = ScopeEntryDefinition |
|
||||
| b_condition.py:0 | loop_0 = ScopeEntryDefinition |
|
||||
| b_condition.py:0 | method_check_0 = ScopeEntryDefinition |
|
||||
| b_condition.py:0 | not_or_not_0 = ScopeEntryDefinition |
|
||||
| b_condition.py:0 | odasa6261_0 = ScopeEntryDefinition |
|
||||
| b_condition.py:0 | split_bool1_0 = ScopeEntryDefinition |
|
||||
@@ -160,6 +161,13 @@
|
||||
| b_condition.py:104 | a_1 = Pi(a_0) [false] |
|
||||
| b_condition.py:105 | a_2 = Pi(a_1) [false] |
|
||||
| b_condition.py:107 | a_3 = Pi(a_2) [false] |
|
||||
| b_condition.py:109 | method_check_1 = FunctionExpr |
|
||||
| b_condition.py:109 | x_0 = ParameterDefinition |
|
||||
| b_condition.py:109 | x_5 = phi(x_2, x_4) |
|
||||
| b_condition.py:111 | x_1 = Pi(x_0) [true] |
|
||||
| b_condition.py:111 | x_2 = ArgumentRefinement(x_1) |
|
||||
| b_condition.py:113 | x_3 = Pi(x_0) [false] |
|
||||
| b_condition.py:113 | x_4 = ArgumentRefinement(x_3) |
|
||||
| d_globals.py:0 | D_0 = ScopeEntryDefinition |
|
||||
| d_globals.py:0 | Ugly_0 = ScopeEntryDefinition |
|
||||
| d_globals.py:0 | X_0 = ScopeEntryDefinition |
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
| b_condition.py:0 | Global Variable h | ScopeEntryDefinition |
|
||||
| b_condition.py:0 | Global Variable k | ScopeEntryDefinition |
|
||||
| b_condition.py:0 | Global Variable loop | ScopeEntryDefinition |
|
||||
| b_condition.py:0 | Global Variable method_check | ScopeEntryDefinition |
|
||||
| b_condition.py:0 | Global Variable not_or_not | ScopeEntryDefinition |
|
||||
| b_condition.py:0 | Global Variable odasa6261 | ScopeEntryDefinition |
|
||||
| b_condition.py:0 | Global Variable split_bool1 | ScopeEntryDefinition |
|
||||
@@ -136,6 +137,13 @@
|
||||
| b_condition.py:104 | Local Variable a | PyEdgeRefinement |
|
||||
| b_condition.py:105 | Local Variable a | PyEdgeRefinement |
|
||||
| b_condition.py:107 | Local Variable a | PyEdgeRefinement |
|
||||
| b_condition.py:109 | Global Variable method_check | AssignmentDefinition |
|
||||
| b_condition.py:109 | Local Variable x | ParameterDefinition |
|
||||
| b_condition.py:109 | Local Variable x | PhiFunction |
|
||||
| b_condition.py:111 | Local Variable x | ArgumentRefinement |
|
||||
| b_condition.py:111 | Local Variable x | PyEdgeRefinement |
|
||||
| b_condition.py:113 | Local Variable x | ArgumentRefinement |
|
||||
| b_condition.py:113 | Local Variable x | PyEdgeRefinement |
|
||||
| d_globals.py:0 | Global Variable D | ScopeEntryDefinition |
|
||||
| d_globals.py:0 | Global Variable Ugly | ScopeEntryDefinition |
|
||||
| d_globals.py:0 | Global Variable X | ScopeEntryDefinition |
|
||||
|
||||
@@ -162,6 +162,8 @@
|
||||
| Global Variable list | b_condition.py:101 | entry |
|
||||
| Global Variable loop | b_condition.py:42 | exit |
|
||||
| Global Variable loop | b_condition.py:43 | entry |
|
||||
| Global Variable method_check | b_condition.py:42 | exit |
|
||||
| Global Variable method_check | b_condition.py:43 | entry |
|
||||
| Global Variable not_or_not | b_condition.py:42 | exit |
|
||||
| Global Variable not_or_not | b_condition.py:43 | entry |
|
||||
| Global Variable object | b_condition.py:0 | entry |
|
||||
@@ -298,6 +300,10 @@
|
||||
| Global Variable use | b_condition.py:88 | exit |
|
||||
| Global Variable use | b_condition.py:90 | entry |
|
||||
| Global Variable use | b_condition.py:90 | exit |
|
||||
| Global Variable use | b_condition.py:109 | entry |
|
||||
| Global Variable use | b_condition.py:110 | exit |
|
||||
| Global Variable use | b_condition.py:111 | entry |
|
||||
| Global Variable use | b_condition.py:113 | entry |
|
||||
| Global Variable v2 | b_condition.py:42 | exit |
|
||||
| Global Variable v2 | b_condition.py:43 | entry |
|
||||
| Global Variable v2 | b_condition.py:44 | exit |
|
||||
@@ -372,6 +378,12 @@
|
||||
| Local Variable x | b_condition.py:88 | exit |
|
||||
| Local Variable x | b_condition.py:90 | entry |
|
||||
| Local Variable x | b_condition.py:90 | exit |
|
||||
| Local Variable x | b_condition.py:109 | entry |
|
||||
| Local Variable x | b_condition.py:110 | exit |
|
||||
| Local Variable x | b_condition.py:111 | entry |
|
||||
| Local Variable x | b_condition.py:111 | exit |
|
||||
| Local Variable x | b_condition.py:113 | entry |
|
||||
| Local Variable x | b_condition.py:113 | exit |
|
||||
| Local Variable y | b_condition.py:5 | entry |
|
||||
| Local Variable y | b_condition.py:5 | exit |
|
||||
| Local Variable y | b_condition.py:7 | exit |
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
| b_condition.py:0 | Module code.b_condition | h | Function h |
|
||||
| b_condition.py:0 | Module code.b_condition | k | Function k |
|
||||
| b_condition.py:0 | Module code.b_condition | loop | Function loop |
|
||||
| b_condition.py:0 | Module code.b_condition | method_check | Function method_check |
|
||||
| b_condition.py:0 | Module code.b_condition | not_or_not | Function not_or_not |
|
||||
| b_condition.py:0 | Module code.b_condition | odasa6261 | Function odasa6261 |
|
||||
| b_condition.py:0 | Module code.b_condition | split_bool1 | Function split_bool1 |
|
||||
|
||||
@@ -114,6 +114,13 @@
|
||||
| b_condition.py:99 | ControlFlowNode for use() | 99 |
|
||||
| b_condition.py:105 | ControlFlowNode for Subscript | 105 |
|
||||
| b_condition.py:105 | ControlFlowNode for UnaryExpr | 105 |
|
||||
| b_condition.py:110 | ControlFlowNode for Attribute | 110 |
|
||||
| b_condition.py:110 | ControlFlowNode for Attribute() | 110 |
|
||||
| b_condition.py:110 | ControlFlowNode for x | 109 |
|
||||
| b_condition.py:111 | ControlFlowNode for use | 111 |
|
||||
| b_condition.py:111 | ControlFlowNode for use() | 111 |
|
||||
| b_condition.py:113 | ControlFlowNode for use | 113 |
|
||||
| b_condition.py:113 | ControlFlowNode for use() | 113 |
|
||||
| c_tests.py:5 | ControlFlowNode for IfExp | 5 |
|
||||
| c_tests.py:5 | ControlFlowNode for cond | 5 |
|
||||
| c_tests.py:5 | ControlFlowNode for unknown | 5 |
|
||||
|
||||
@@ -185,6 +185,8 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
|
||||
| b_condition.py:106 | ControlFlowNode for Exception | builtin-class Exception | builtin-class type | 106 | runtime |
|
||||
| b_condition.py:106 | ControlFlowNode for Exception() | Exception() | builtin-class Exception | 106 | runtime |
|
||||
| b_condition.py:107 | ControlFlowNode for Str | 'Hello' | builtin-class str | 107 | runtime |
|
||||
| b_condition.py:109 | ControlFlowNode for FunctionExpr | Function method_check | builtin-class function | 109 | import |
|
||||
| b_condition.py:109 | ControlFlowNode for method_check | Function method_check | builtin-class function | 109 | import |
|
||||
| e_temporal.py:2 | ControlFlowNode for ImportExpr | Module sys | builtin-class module | 2 | import |
|
||||
| e_temporal.py:2 | ControlFlowNode for sys | Module sys | builtin-class module | 2 | import |
|
||||
| e_temporal.py:4 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | 4 | import |
|
||||
|
||||
@@ -185,6 +185,8 @@ WARNING: Predicate points_to has been deprecated and may be removed in future (P
|
||||
| b_condition.py:106 | ControlFlowNode for Exception | builtin-class Exception | builtin-class type | 106 |
|
||||
| b_condition.py:106 | ControlFlowNode for Exception() | Exception() | builtin-class Exception | 106 |
|
||||
| b_condition.py:107 | ControlFlowNode for Str | 'Hello' | builtin-class str | 107 |
|
||||
| b_condition.py:109 | ControlFlowNode for FunctionExpr | Function method_check | builtin-class function | 109 |
|
||||
| b_condition.py:109 | ControlFlowNode for method_check | Function method_check | builtin-class function | 109 |
|
||||
| d_globals.py:2 | ControlFlowNode for FunctionExpr | Function j | builtin-class function | 2 |
|
||||
| d_globals.py:2 | ControlFlowNode for j | Function j | builtin-class function | 2 |
|
||||
| d_globals.py:3 | ControlFlowNode for Tuple | Tuple | builtin-class tuple | 3 |
|
||||
|
||||
@@ -86,6 +86,7 @@ WARNING: Predicate ssa_variable_points_to has been deprecated and may be removed
|
||||
| b_condition.py:96 | y_6 = SingleSuccessorGuard(y_5) [false] | NoneType None | builtin-class NoneType |
|
||||
| b_condition.py:97 | x_3 = ArgumentRefinement(x_2) | NoneType None | builtin-class NoneType |
|
||||
| b_condition.py:101 | not_or_not_1 = FunctionExpr | Function not_or_not | builtin-class function |
|
||||
| b_condition.py:109 | method_check_1 = FunctionExpr | Function method_check | builtin-class function |
|
||||
| c_tests.py:0 | __name___0 = ScopeEntryDefinition | 'code.c_tests' | builtin-class str |
|
||||
| c_tests.py:4 | f_0 = FunctionExpr | Function f | builtin-class function |
|
||||
| c_tests.py:5 | x_0 = IfExp | NoneType None | builtin-class NoneType |
|
||||
|
||||
@@ -20,3 +20,4 @@
|
||||
| b_condition.py:102 | Local Variable a | ControlFlowNode for a |
|
||||
| b_condition.py:104 | Local Variable a | ControlFlowNode for a |
|
||||
| b_condition.py:105 | Local Variable a | ControlFlowNode for a |
|
||||
| b_condition.py:110 | Local Variable x | ControlFlowNode for x |
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
| b_condition.py:0 | Global Variable h | Entry node for Module code.b_condition | definition |
|
||||
| b_condition.py:0 | Global Variable k | Entry node for Module code.b_condition | definition |
|
||||
| b_condition.py:0 | Global Variable loop | Entry node for Module code.b_condition | definition |
|
||||
| b_condition.py:0 | Global Variable method_check | Entry node for Module code.b_condition | definition |
|
||||
| b_condition.py:0 | Global Variable not_or_not | Entry node for Module code.b_condition | definition |
|
||||
| b_condition.py:0 | Global Variable odasa6261 | Entry node for Module code.b_condition | definition |
|
||||
| b_condition.py:0 | Global Variable split_bool1 | Entry node for Module code.b_condition | definition |
|
||||
@@ -115,3 +116,7 @@
|
||||
| b_condition.py:101 | Global Variable not_or_not | ControlFlowNode for not_or_not | definition |
|
||||
| b_condition.py:101 | Local Variable a | ControlFlowNode for a | definition |
|
||||
| b_condition.py:101 | Local Variable a | Entry node for Function not_or_not | definition |
|
||||
| b_condition.py:109 | Global Variable method_check | ControlFlowNode for method_check | definition |
|
||||
| b_condition.py:109 | Local Variable x | ControlFlowNode for x | definition |
|
||||
| b_condition.py:111 | Local Variable x | ControlFlowNode for use() | refinement |
|
||||
| b_condition.py:113 | Local Variable x | ControlFlowNode for use() | refinement |
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
| b_condition.py:0 | h_1 | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | k_1 | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | loop_1 | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | method_check_1 | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | not_or_not_1 | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | odasa6261_1 | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | split_bool1_1 | Exit node for Module code.b_condition |
|
||||
@@ -91,6 +92,7 @@
|
||||
| b_condition.py:39 | h_0 | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | k_0 | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | loop_0 | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | method_check_0 | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | not_or_not_0 | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | odasa6261_0 | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | split_bool1_0 | ControlFlowNode for thing() |
|
||||
@@ -105,6 +107,7 @@
|
||||
| b_condition.py:43 | h_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | k_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | loop_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | method_check_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | not_or_not_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | odasa6261_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | split_bool1_0 | ControlFlowNode for use() |
|
||||
@@ -118,6 +121,7 @@
|
||||
| b_condition.py:44 | h_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | k_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | loop_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | method_check_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | not_or_not_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | odasa6261_0 | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | split_bool1_0 | ControlFlowNode for use() |
|
||||
@@ -168,6 +172,10 @@
|
||||
| b_condition.py:102 | a_0 | ControlFlowNode for a |
|
||||
| b_condition.py:104 | a_1 | ControlFlowNode for a |
|
||||
| b_condition.py:105 | a_2 | ControlFlowNode for a |
|
||||
| b_condition.py:109 | x_5 | Exit node for Function method_check |
|
||||
| b_condition.py:110 | x_0 | ControlFlowNode for x |
|
||||
| b_condition.py:111 | x_1 | ControlFlowNode for x |
|
||||
| b_condition.py:113 | x_3 | ControlFlowNode for x |
|
||||
| d_globals.py:0 | D_1 | Exit node for Module code.d_globals |
|
||||
| d_globals.py:0 | Ugly_1 | Exit node for Module code.d_globals |
|
||||
| d_globals.py:0 | X_1 | Exit node for Module code.d_globals |
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
| b_condition.py:106 | ControlFlowNode for Exception | runtime | builtin-class Exception | builtin-class type |
|
||||
| b_condition.py:106 | ControlFlowNode for Exception() | runtime | Exception() | builtin-class Exception |
|
||||
| b_condition.py:107 | ControlFlowNode for Str | runtime | 'Hello' | builtin-class str |
|
||||
| b_condition.py:109 | ControlFlowNode for FunctionExpr | import | Function method_check | builtin-class function |
|
||||
| e_temporal.py:2 | ControlFlowNode for ImportExpr | import | Module sys | builtin-class module |
|
||||
| e_temporal.py:4 | ControlFlowNode for FunctionExpr | import | Function f | builtin-class function |
|
||||
| e_temporal.py:5 | ControlFlowNode for Attribute | code/e_temporal.py:12 from import | list object | builtin-class list |
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
| b_condition.py:0 | k | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | list | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | loop | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | method_check | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | not_or_not | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | object | Exit node for Module code.b_condition |
|
||||
| b_condition.py:0 | odasa6261 | Exit node for Module code.b_condition |
|
||||
@@ -109,6 +110,7 @@
|
||||
| b_condition.py:39 | h | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | k | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | loop | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | method_check | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | not_or_not | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | odasa6261 | ControlFlowNode for thing() |
|
||||
| b_condition.py:39 | split_bool1 | ControlFlowNode for thing() |
|
||||
@@ -124,6 +126,7 @@
|
||||
| b_condition.py:43 | h | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | k | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | loop | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | method_check | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | not_or_not | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | odasa6261 | ControlFlowNode for use() |
|
||||
| b_condition.py:43 | split_bool1 | ControlFlowNode for use() |
|
||||
@@ -138,6 +141,7 @@
|
||||
| b_condition.py:44 | h | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | k | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | loop | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | method_check | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | not_or_not | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | odasa6261 | ControlFlowNode for use() |
|
||||
| b_condition.py:44 | split_bool1 | ControlFlowNode for use() |
|
||||
@@ -202,6 +206,12 @@
|
||||
| b_condition.py:104 | a | ControlFlowNode for a |
|
||||
| b_condition.py:105 | a | ControlFlowNode for a |
|
||||
| b_condition.py:106 | Exception | ControlFlowNode for Exception |
|
||||
| b_condition.py:109 | x | Exit node for Function method_check |
|
||||
| b_condition.py:110 | x | ControlFlowNode for x |
|
||||
| b_condition.py:111 | use | ControlFlowNode for use |
|
||||
| b_condition.py:111 | x | ControlFlowNode for x |
|
||||
| b_condition.py:113 | use | ControlFlowNode for use |
|
||||
| b_condition.py:113 | x | ControlFlowNode for x |
|
||||
| d_globals.py:0 | D | Exit node for Module code.d_globals |
|
||||
| d_globals.py:0 | Ugly | Exit node for Module code.d_globals |
|
||||
| d_globals.py:0 | X | Exit node for Module code.d_globals |
|
||||
|
||||
@@ -106,3 +106,10 @@ def not_or_not(*a):
|
||||
raise Exception()
|
||||
"Hello"
|
||||
|
||||
def method_check(x):
|
||||
if x.m():
|
||||
use(x)
|
||||
else:
|
||||
use(x)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user