Merge branch 'main' into rdmarsh2/fix-ir-globals

This commit is contained in:
Robert Marsh
2022-06-14 13:22:04 -04:00
92 changed files with 2063 additions and 418 deletions

View File

@@ -41,7 +41,7 @@ jobs:
git log -1 --format='%H'
working-directory: base
- name: Set up Python 3.8
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI

View File

@@ -22,7 +22,7 @@ jobs:
- name: Clone self (github/codeql)
uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: 3.8

View File

@@ -19,7 +19,7 @@ jobs:
path: codeqlModels
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI

View File

@@ -22,7 +22,7 @@ jobs:
path: ql
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI

View File

@@ -23,7 +23,7 @@ jobs:
path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
- name: Set up Python 3.8
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI

View File

@@ -23,7 +23,7 @@ jobs:
with:
path: codeql
- name: Set up Python 3.8
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI

View File

@@ -0,0 +1,49 @@
int *global_ptr;
const char *global_string = "hello, world";
void test1(int *ptr, int &ref)
{
const char *str;
int v, *p;
char c;
v = *ptr; // `ptr` dereferenced
v = ptr[0]; // `ptr` dereferenced
p = ptr;
*ptr = 0; // `ptr` dereferenced
ptr[0] = 0; // `ptr` dereferenced
ptr = 0;
(*ptr)++; // `ptr`, `*ptr` dereferenced
*(ptr++); // `ptr++` dereferenced
ptr++;
v = ref; // (`ref` implicitly dereferenced, not detected)
p = &ref;
ref = 0; // (`ref` implicitly dereferenced, not detected)
ref++; // (`ref` implicitly dereferenced, not detected)
*global_ptr; // `global_ptr` dereferenced
str = global_string;
c = global_string[5]; // `global_string` dereferenced
}
struct myStruct
{
int x;
void f() {};
void (*g)();
};
void test1(myStruct *ms)
{
void (*h)();
ms;
ms->x; // `ms` dereferenced
ms->f(); // `ms` dereferenced
ms->g(); // `ms` dereferenced
h = ms->g; // `ms` dereferenced
}

View File

@@ -0,0 +1,13 @@
| dereferenced.cpp:11:6:11:9 | * ... | dereferenced.cpp:11:7:11:9 | ptr |
| dereferenced.cpp:12:6:12:11 | access to array | dereferenced.cpp:12:6:12:8 | ptr |
| dereferenced.cpp:15:2:15:5 | * ... | dereferenced.cpp:15:3:15:5 | ptr |
| dereferenced.cpp:16:2:16:7 | access to array | dereferenced.cpp:16:2:16:4 | ptr |
| dereferenced.cpp:19:3:19:6 | * ... | dereferenced.cpp:19:4:19:6 | ptr |
| dereferenced.cpp:19:4:19:6 | ptr | dereferenced.cpp:19:3:19:6 | * ... |
| dereferenced.cpp:20:2:20:9 | * ... | dereferenced.cpp:20:4:20:8 | ... ++ |
| dereferenced.cpp:28:2:28:12 | * ... | dereferenced.cpp:28:3:28:12 | global_ptr |
| dereferenced.cpp:30:6:30:21 | access to array | dereferenced.cpp:30:6:30:18 | global_string |
| dereferenced.cpp:45:6:45:6 | x | dereferenced.cpp:45:2:45:3 | ms |
| dereferenced.cpp:46:6:46:6 | call to f | dereferenced.cpp:46:2:46:3 | ms |
| dereferenced.cpp:47:6:47:6 | g | dereferenced.cpp:47:2:47:3 | ms |
| dereferenced.cpp:48:10:48:10 | g | dereferenced.cpp:48:6:48:7 | ms |

View File

@@ -0,0 +1,6 @@
import cpp
import semmle.code.cpp.controlflow.Dereferenced
from Expr op, Expr e
where dereferencedByOperation(op, e) // => dereferenced(e)
select op, e

View File

@@ -4,3 +4,4 @@
*/
import semmle.javascript.dataflow.DataFlow::DataFlow as DataFlow
import semmle.javascript.security.CryptoAlgorithms as CryptoAlgorithms

View File

@@ -11,3 +11,79 @@
*/
private import ConceptsImports
/**
* Provides models for cryptographic concepts.
*
* Note: The `CryptographicAlgorithm` class currently doesn't take weak keys into
* consideration for the `isWeak` member predicate. So RSA is always considered
* secure, although using a low number of bits will actually make it insecure. We plan
* to improve our libraries in the future to more precisely capture this aspect.
*/
module Cryptography {
class CryptographicAlgorithm = CryptoAlgorithms::CryptographicAlgorithm;
class EncryptionAlgorithm = CryptoAlgorithms::EncryptionAlgorithm;
class HashingAlgorithm = CryptoAlgorithms::HashingAlgorithm;
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `CryptographicOperation::Range` instead.
*/
class CryptographicOperation extends DataFlow::Node instanceof CryptographicOperation::Range {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
DataFlow::Node getAnInput() { result = super.getAnInput() }
/**
* Gets the block mode used to perform this cryptographic operation.
* This may have no result - for example if the `CryptographicAlgorithm` used
* is a stream cipher rather than a block cipher.
*/
BlockMode getBlockMode() { result = super.getBlockMode() }
}
/** Provides classes for modeling new applications of a cryptographic algorithms. */
module CryptographicOperation {
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `CryptographicOperation` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
abstract CryptographicAlgorithm getAlgorithm();
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
abstract DataFlow::Node getAnInput();
/**
* Gets the block mode used to perform this cryptographic operation.
* This may have no result - for example if the `CryptographicAlgorithm` used
* is a stream cipher rather than a block cipher.
*/
abstract BlockMode getBlockMode();
}
}
/**
* A cryptographic block cipher mode of operation. This can be used to encrypt
* data of arbitrary length using a block encryption algorithm.
*/
class BlockMode extends string {
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR", "OPENPGP"] }
/** Holds if this block mode is considered to be insecure. */
predicate isWeak() { this = "ECB" }
}
}

View File

@@ -81,6 +81,9 @@ class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
/** Holds if this algorithm is a stream cipher. */
predicate isStreamCipher() { isStreamCipher(name) }
}
/**

View File

@@ -67,6 +67,6 @@ predicate isStrongPasswordHashingAlgorithm(string name) {
predicate isWeakPasswordHashingAlgorithm(string name) { name = "EVPKDF" }
/**
* Holds if `name` corresponds to a weak block cipher mode of operation.
* Holds if `name` corresponds to a stream cipher.
*/
predicate isWeakBlockMode(string name) { name = "ECB" }
predicate isStreamCipher(string name) { name = ["CHACHA", "RC4", "ARC4", "ARCFOUR", "RABBIT"] }

View File

@@ -1211,38 +1211,5 @@ module Cryptography {
}
}
import semmle.python.concepts.CryptoAlgorithms
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `CryptographicOperation::Range` instead.
*/
class CryptographicOperation extends DataFlow::Node instanceof CryptographicOperation::Range {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
DataFlow::Node getAnInput() { result = super.getAnInput() }
}
/** Provides classes for modeling new applications of a cryptographic algorithms. */
module CryptographicOperation {
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `CryptographicOperation` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
abstract CryptographicAlgorithm getAlgorithm();
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
abstract DataFlow::Node getAnInput();
}
}
import semmle.python.internal.ConceptsShared::Cryptography
}

View File

@@ -81,6 +81,9 @@ class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
/** Holds if this algorithm is a stream cipher. */
predicate isStreamCipher() { isStreamCipher(name) }
}
/**

View File

@@ -67,6 +67,6 @@ predicate isStrongPasswordHashingAlgorithm(string name) {
predicate isWeakPasswordHashingAlgorithm(string name) { name = "EVPKDF" }
/**
* Holds if `name` corresponds to a weak block cipher mode of operation.
* Holds if `name` corresponds to a stream cipher.
*/
predicate isWeakBlockMode(string name) { name = "ECB" }
predicate isStreamCipher(string name) { name = ["CHACHA", "RC4", "ARC4", "ARCFOUR", "RABBIT"] }

View File

@@ -108,20 +108,20 @@ private module CryptodomeModel {
DataFlow::CallCfgNode {
string methodName;
string cipherName;
API::CallNode newCall;
CryptodomeGenericCipherOperation() {
methodName in [
"encrypt", "decrypt", "verify", "update", "hexverify", "encrypt_and_digest",
"decrypt_and_verify"
] and
this =
newCall =
API::moduleImport(["Crypto", "Cryptodome"])
.getMember("Cipher")
.getMember(cipherName)
.getMember("new")
.getReturn()
.getMember(methodName)
.getACall()
.getACall() and
this = newCall.getReturn().getMember(methodName).getACall()
}
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(cipherName) }
@@ -155,6 +155,20 @@ private module CryptodomeModel {
this.getArgByName("mac_tag")
]
}
override Cryptography::BlockMode getBlockMode() {
// `modeName` is of the form "MODE_<BlockMode>"
exists(string modeName |
newCall.getArg(1) =
API::moduleImport(["Crypto", "Cryptodome"])
.getMember("Cipher")
.getMember(cipherName)
.getMember(modeName)
.getAUse()
|
result = modeName.splitAt("_", 1)
)
}
}
/**
@@ -192,6 +206,8 @@ private module CryptodomeModel {
result in [this.getArg(1), this.getArgByName("signature")]
)
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
@@ -215,5 +231,7 @@ private module CryptodomeModel {
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
override Cryptography::BlockMode getBlockMode() { none() }
}
}

View File

@@ -170,8 +170,19 @@ private module CryptographyModel {
.getMember(algorithmName)
}
/** Gets a reference to a `cryptography.hazmat.primitives.ciphers.modes` Class */
API::Node modeClassRef(string modeName) {
result =
API::moduleImport("cryptography")
.getMember("hazmat")
.getMember("primitives")
.getMember("ciphers")
.getMember("modes")
.getMember(modeName)
}
/** Gets a reference to a Cipher instance using algorithm with `algorithmName`. */
API::Node cipherInstance(string algorithmName) {
API::Node cipherInstance(string algorithmName, string modeName) {
exists(API::CallNode call | result = call.getReturn() |
call =
API::moduleImport("cryptography")
@@ -182,7 +193,12 @@ private module CryptographyModel {
.getACall() and
algorithmClassRef(algorithmName).getReturn().getAUse() in [
call.getArg(0), call.getArgByName("algorithm")
]
] and
exists(DataFlow::Node modeArg | modeArg in [call.getArg(1), call.getArgByName("mode")] |
if modeArg = modeClassRef(_).getReturn().getAUse()
then modeArg = modeClassRef(modeName).getReturn().getAUse()
else modeName = "<None or unknown>"
)
)
}
@@ -192,10 +208,11 @@ private module CryptographyModel {
class CryptographyGenericCipherOperation extends Cryptography::CryptographicOperation::Range,
DataFlow::MethodCallNode {
string algorithmName;
string modeName;
CryptographyGenericCipherOperation() {
this =
cipherInstance(algorithmName)
cipherInstance(algorithmName, modeName)
.getMember(["decryptor", "encryptor"])
.getReturn()
.getMember(["update", "update_into"])
@@ -207,6 +224,8 @@ private module CryptographyModel {
}
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
override Cryptography::BlockMode getBlockMode() { result = modeName }
}
}
@@ -257,6 +276,8 @@ private module CryptographyModel {
}
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
override Cryptography::BlockMode getBlockMode() { none() }
}
}
}

View File

@@ -41,6 +41,8 @@ private module Rsa {
override DataFlow::Node getAnInput() {
result in [this.getArg(0), this.getArgByName("message")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
@@ -54,6 +56,8 @@ private module Rsa {
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("crypto")] }
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
@@ -79,6 +83,8 @@ private module Rsa {
override DataFlow::Node getAnInput() {
result in [this.getArg(0), this.getArgByName("message")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
@@ -100,6 +106,8 @@ private module Rsa {
or
result in [this.getArg(1), this.getArgByName("signature")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
@@ -122,6 +130,8 @@ private module Rsa {
override DataFlow::Node getAnInput() {
result in [this.getArg(0), this.getArgByName("message")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
@@ -137,5 +147,7 @@ private module Rsa {
override DataFlow::Node getAnInput() {
result in [this.getArg(0), this.getArgByName("hash_value")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
}

View File

@@ -2671,6 +2671,8 @@ private module StdlibPrivate {
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").getARhs() }
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
@@ -2686,6 +2688,8 @@ private module StdlibPrivate {
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
override DataFlow::Node getAnInput() { result = this.getArg(0) }
override Cryptography::BlockMode getBlockMode() { none() }
}
/** Helper predicate for the `HashLibGenericHashOperation` charpred, to prevent a bad join order. */
@@ -2709,6 +2713,8 @@ private module StdlibPrivate {
HashlibGenericHashOperation() { hashClass = hashlibMember(hashName) }
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
override Cryptography::BlockMode getBlockMode() { none() }
}
/**

View File

@@ -4,3 +4,4 @@
*/
import semmle.python.dataflow.new.DataFlow
import semmle.python.concepts.CryptoAlgorithms as CryptoAlgorithms

View File

@@ -11,3 +11,79 @@
*/
private import ConceptsImports
/**
* Provides models for cryptographic concepts.
*
* Note: The `CryptographicAlgorithm` class currently doesn't take weak keys into
* consideration for the `isWeak` member predicate. So RSA is always considered
* secure, although using a low number of bits will actually make it insecure. We plan
* to improve our libraries in the future to more precisely capture this aspect.
*/
module Cryptography {
class CryptographicAlgorithm = CryptoAlgorithms::CryptographicAlgorithm;
class EncryptionAlgorithm = CryptoAlgorithms::EncryptionAlgorithm;
class HashingAlgorithm = CryptoAlgorithms::HashingAlgorithm;
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `CryptographicOperation::Range` instead.
*/
class CryptographicOperation extends DataFlow::Node instanceof CryptographicOperation::Range {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
DataFlow::Node getAnInput() { result = super.getAnInput() }
/**
* Gets the block mode used to perform this cryptographic operation.
* This may have no result - for example if the `CryptographicAlgorithm` used
* is a stream cipher rather than a block cipher.
*/
BlockMode getBlockMode() { result = super.getBlockMode() }
}
/** Provides classes for modeling new applications of a cryptographic algorithms. */
module CryptographicOperation {
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `CryptographicOperation` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
abstract CryptographicAlgorithm getAlgorithm();
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
abstract DataFlow::Node getAnInput();
/**
* Gets the block mode used to perform this cryptographic operation.
* This may have no result - for example if the `CryptographicAlgorithm` used
* is a stream cipher rather than a block cipher.
*/
abstract BlockMode getBlockMode();
}
}
/**
* A cryptographic block cipher mode of operation. This can be used to encrypt
* data of arbitrary length using a block encryption algorithm.
*/
class BlockMode extends string {
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR", "OPENPGP"] }
/** Holds if this block mode is considered to be insecure. */
predicate isWeak() { this = "ECB" }
}
}

View File

@@ -13,13 +13,18 @@
import python
import semmle.python.Concepts
from Cryptography::CryptographicOperation operation, Cryptography::CryptographicAlgorithm algorithm
from
Cryptography::CryptographicOperation operation, Cryptography::CryptographicAlgorithm algorithm,
string msgPrefix
where
algorithm = operation.getAlgorithm() and
algorithm.isWeak() and
// `Cryptography::HashingAlgorithm` and `Cryptography::PasswordHashingAlgorithm` are
// handled by `py/weak-sensitive-data-hashing`
algorithm instanceof Cryptography::EncryptionAlgorithm
select operation,
"The cryptographic algorithm " + algorithm.getName() +
" is broken or weak, and should not be used."
algorithm instanceof Cryptography::EncryptionAlgorithm and
(
algorithm.isWeak() and
msgPrefix = "The cryptographic algorithm " + operation.getAlgorithm().getName()
)
or
operation.getBlockMode().isWeak() and msgPrefix = "The block mode " + operation.getBlockMode()
select operation, msgPrefix + " is broken or weak, and should not be used."

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode.

View File

@@ -0,0 +1,23 @@
/**
* @name Reflected server-side cross-site scripting
* @description Writing user input directly to a web page
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 2.9
* @sub-severity high
* @id py/reflective-xss
* @tags security
* external/cwe/cwe-079
* external/cwe/cwe-116
*/
// determine precision above
import python
import experimental.semmle.python.security.dataflow.ReflectedXSS
import DataFlow::PathGraph
from ReflectedXssConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.",
source.getNode(), "a user-provided value"

View File

@@ -602,3 +602,77 @@ class JwtDecoding extends DataFlow::Node instanceof JwtDecoding::Range {
/** DEPRECATED: Alias for JwtDecoding */
deprecated class JWTDecoding = JwtDecoding;
/** Provides classes for modeling Email APIs. */
module EmailSender {
/**
* A data-flow node that sends an email.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `EmailSender` instead.
*/
abstract class Range extends DataFlow::Node {
/**
* Gets a data flow node holding the plaintext version of the email body.
*/
abstract DataFlow::Node getPlainTextBody();
/**
* Gets a data flow node holding the html version of the email body.
*/
abstract DataFlow::Node getHtmlBody();
/**
* Gets a data flow node holding the recipients of the email.
*/
abstract DataFlow::Node getTo();
/**
* Gets a data flow node holding the senders of the email.
*/
abstract DataFlow::Node getFrom();
/**
* Gets a data flow node holding the subject of the email.
*/
abstract DataFlow::Node getSubject();
}
}
/**
* A data-flow node that sends an email.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `EmailSender::Range` instead.
*/
class EmailSender extends DataFlow::Node instanceof EmailSender::Range {
/**
* Gets a data flow node holding the plaintext version of the email body.
*/
DataFlow::Node getPlainTextBody() { result = super.getPlainTextBody() }
/**
* Gets a data flow node holding the html version of the email body.
*/
DataFlow::Node getHtmlBody() { result = super.getHtmlBody() }
/**
* Gets a data flow node holding the recipients of the email.
*/
DataFlow::Node getTo() { result = super.getTo() }
/**
* Gets a data flow node holding the senders of the email.
*/
DataFlow::Node getFrom() { result = super.getFrom() }
/**
* Gets a data flow node holding the subject of the email.
*/
DataFlow::Node getSubject() { result = super.getSubject() }
/**
* Gets a data flow node that refers to the HTML body or plaintext body of the email.
*/
DataFlow::Node getABody() { result in [super.getPlainTextBody(), super.getHtmlBody()] }
}

View File

@@ -15,3 +15,6 @@ private import experimental.semmle.python.libraries.Python_JWT
private import experimental.semmle.python.libraries.Authlib
private import experimental.semmle.python.libraries.PythonJose
private import experimental.semmle.python.frameworks.CopyFile
private import experimental.semmle.python.frameworks.Sendgrid
private import experimental.semmle.python.libraries.FlaskMail
private import experimental.semmle.python.libraries.SmtpLib

View File

@@ -8,8 +8,8 @@ private import semmle.python.frameworks.Django
private import semmle.python.dataflow.new.DataFlow
private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.Concepts
import semmle.python.dataflow.new.RemoteFlowSources
private module ExperimentalPrivateDjango {
private module DjangoMod {
@@ -189,5 +189,90 @@ private module ExperimentalPrivateDjango {
}
}
}
module Email {
/** https://docs.djangoproject.com/en/3.2/topics/email/ */
private API::Node djangoMail() {
result = API::moduleImport("django").getMember("core").getMember("mail")
}
/**
* Gets a call to `django.core.mail.send_mail()`.
*
* Given the following example:
*
* ```py
* send_mail("Subject", "plain-text body", "from@example.com", ["to@example.com"], html_message=django.http.request.GET.get("html"))
* ```
*
* * `this` would be `send_mail("Subject", "plain-text body", "from@example.com", ["to@example.com"], html_message=django.http.request.GET.get("html"))`.
* * `getPlainTextBody()`'s result would be `"plain-text body"`.
* * `getHtmlBody()`'s result would be `django.http.request.GET.get("html")`.
* * `getTo()`'s result would be `["to@example.com"]`.
* * `getFrom()`'s result would be `"from@example.com"`.
* * `getSubject()`'s result would be `"Subject"`.
*/
private class DjangoSendMail extends DataFlow::CallCfgNode, EmailSender::Range {
DjangoSendMail() { this = djangoMail().getMember("send_mail").getACall() }
override DataFlow::Node getPlainTextBody() {
result in [this.getArg(1), this.getArgByName("message")]
}
override DataFlow::Node getHtmlBody() {
result in [this.getArg(8), this.getArgByName("html_message")]
}
override DataFlow::Node getTo() {
result in [this.getArg(3), this.getArgByName("recipient_list")]
}
override DataFlow::Node getFrom() {
result in [this.getArg(2), this.getArgByName("from_email")]
}
override DataFlow::Node getSubject() {
result in [this.getArg(0), this.getArgByName("subject")]
}
}
/**
* Gets a call to `django.core.mail.mail_admins()` or `django.core.mail.mail_managers()`.
*
* Given the following example:
*
* ```py
* mail_admins("Subject", "plain-text body", html_message=django.http.request.GET.get("html"))
* ```
*
* * `this` would be `mail_admins("Subject", "plain-text body", html_message=django.http.request.GET.get("html"))`.
* * `getPlainTextBody()`'s result would be `"plain-text body"`.
* * `getHtmlBody()`'s result would be `django.http.request.GET.get("html")`.
* * `getTo()`'s result would be `none`.
* * `getFrom()`'s result would be `none`.
* * `getSubject()`'s result would be `"Subject"`.
*/
private class DjangoMailInternal extends DataFlow::CallCfgNode, EmailSender::Range {
DjangoMailInternal() {
this = djangoMail().getMember(["mail_admins", "mail_managers"]).getACall()
}
override DataFlow::Node getPlainTextBody() {
result in [this.getArg(1), this.getArgByName("message")]
}
override DataFlow::Node getHtmlBody() {
result in [this.getArg(4), this.getArgByName("html_message")]
}
override DataFlow::Node getTo() { none() }
override DataFlow::Node getFrom() { none() }
override DataFlow::Node getSubject() {
result in [this.getArg(0), this.getArgByName("subject")]
}
}
}
}
}

View File

@@ -0,0 +1,187 @@
/**
* Provides classes modeling security-relevant aspects of the `sendgrid` PyPI package.
* See https://github.com/sendgrid/sendgrid-python.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
private module Sendgrid {
/** Gets a reference to the `sendgrid` module. */
private API::Node sendgrid() { result = API::moduleImport("sendgrid") }
/** Gets a reference to `sendgrid.helpers.mail` */
private API::Node sendgridMailHelper() {
result = sendgrid().getMember("helpers").getMember("mail")
}
/** Gets a reference to `sendgrid.helpers.mail.Mail` */
private API::Node sendgridMailInstance() { result = sendgridMailHelper().getMember("Mail") }
/** Gets a reference to a `SendGridAPIClient` instance. */
private API::Node sendgridApiClient() {
result = sendgrid().getMember("SendGridAPIClient").getReturn()
}
/** Gets a reference to a `SendGridAPIClient` instance call with `send` or `post`. */
private DataFlow::CallCfgNode sendgridApiSendCall() {
result = sendgridApiClient().getMember("send").getACall()
or
result =
sendgridApiClient()
.getMember("client")
.getMember("mail")
.getMember("send")
.getMember("post")
.getACall()
}
/**
* Gets a reference to `sg.send()` and `sg.client.mail.send.post()`.
*
* Given the following example:
*
* ```py
* from_email = Email("from@example.com")
* to_email = To("to@example.com")
* subject = "Sending with SendGrid is Fun"
* content = Content("text/html", request.args["html_content"])
*
* mail = Mail(from_email, to_email, subject, content)
*
* sg = SendGridAPIClient(api_key='SENDGRID_API_KEY')
* response = sg.client.mail.send.post(request_body=mail.get())
* ```
*
* * `this` would be `sg.client.mail.send.post(request_body=mail.get())`.
* * `getPlainTextBody()`'s result would be `none()`.
* * `getHtmlBody()`'s result would be `request.args["html_content"]`.
* * `getTo()`'s result would be `"to@example.com"`.
* * `getFrom()`'s result would be `"from@example.com"`.
* * `getSubject()`'s result would be `"Sending with SendGrid is Fun"`.
*/
private class SendGridMail extends DataFlow::CallCfgNode, EmailSender::Range {
SendGridMail() { this = sendgridApiSendCall() }
private DataFlow::CallCfgNode getMailCall() {
exists(DataFlow::Node n |
n in [this.getArg(0), this.getArgByName("request_body")] and
result = [n, n.(DataFlow::MethodCallNode).getObject()].getALocalSource()
)
}
private DataFlow::Node sendgridContent(DataFlow::CallCfgNode contentCall, string mime) {
mime in ["text/plain", "text/html", "text/x-amp-html"] and
exists(StrConst mimeNode |
mimeNode.getText() = mime and
DataFlow::exprNode(mimeNode).(DataFlow::LocalSourceNode).flowsTo(contentCall.getArg(0)) and
result = contentCall.getArg(1)
)
}
private DataFlow::Node sendgridWrite(string attributeName) {
attributeName in ["plain_text_content", "html_content", "from_email", "subject"] and
exists(DataFlow::AttrWrite attrWrite |
attrWrite.getObject().getALocalSource() = this.getMailCall() and
attrWrite.getAttributeName() = attributeName and
result = attrWrite.getValue()
)
}
override DataFlow::Node getPlainTextBody() {
result in [
this.getMailCall().getArg(3), this.getMailCall().getArgByName("plain_text_content")
]
or
result in [
this.sendgridContent([
this.getMailCall().getArg(3), this.getMailCall().getArgByName("plain_text_content")
].getALocalSource(), "text/plain"),
this.sendgridContent(sendgridMailInstance().getMember("add_content").getACall(),
"text/plain")
]
or
result = this.sendgridWrite("plain_text_content")
}
override DataFlow::Node getHtmlBody() {
result in [this.getMailCall().getArg(4), this.getMailCall().getArgByName("html_content")]
or
result = this.getMailCall().getAMethodCall("set_html").getArg(0)
or
result =
this.sendgridContent([
this.getMailCall().getArg(4), this.getMailCall().getArgByName("html_content")
].getALocalSource(), ["text/html", "text/x-amp-html"])
or
result = this.sendgridWrite("html_content")
or
exists(KeyValuePair content, Dict generalDict, KeyValuePair typePair, KeyValuePair valuePair |
content.getKey().(StrConst).getText() = "content" and
content.getValue().(List).getAnElt() = generalDict and
// declare KeyValuePairs keys and values
typePair.getKey().(StrConst).getText() = "type" and
typePair.getValue().(StrConst).getText() = ["text/html", "text/x-amp-html"] and
valuePair.getKey().(StrConst).getText() = "value" and
result.asExpr() = valuePair.getValue() and
// correlate generalDict with previously set KeyValuePairs
generalDict.getAnItem() in [typePair, valuePair] and
[this.getArg(0), this.getArgByName("request_body")].getALocalSource().asExpr() =
any(Dict d | d.getAnItem() = content)
)
or
exists(KeyValuePair footer, Dict generalDict, KeyValuePair enablePair, KeyValuePair htmlPair |
footer.getKey().(StrConst).getText() = ["footer", "subscription_tracking"] and
footer.getValue() = generalDict and
// check footer is enabled
enablePair.getKey().(StrConst).getText() = "enable" and
exists(enablePair.getValue().(True)) and
// get html content
htmlPair.getKey().(StrConst).getText() = "html" and
result.asExpr() = htmlPair.getValue() and
// correlate generalDict with previously set KeyValuePairs
generalDict.getAnItem() in [enablePair, htmlPair] and
exists(KeyValuePair k |
k.getKey() =
[this.getArg(0), this.getArgByName("request_body")]
.getALocalSource()
.asExpr()
.(Dict)
.getAKey() and
k.getValue() = any(Dict d | d.getAKey() = footer.getKey())
)
)
}
override DataFlow::Node getTo() {
result in [this.getMailCall().getArg(1), this.getMailCall().getArgByName("to_emails")]
or
result = this.getMailCall().getAMethodCall("To").getArg(0)
or
result =
this.getMailCall()
.getAMethodCall(["to", "add_to", "cc", "add_cc", "bcc", "add_bcc"])
.getArg(0)
}
override DataFlow::Node getFrom() {
result in [this.getMailCall().getArg(0), this.getMailCall().getArgByName("from_email")]
or
result = this.getMailCall().getAMethodCall("Email").getArg(0)
or
result = this.getMailCall().getAMethodCall(["from_email", "set_from"]).getArg(0)
or
result = this.sendgridWrite("from_email")
}
override DataFlow::Node getSubject() {
result in [this.getMailCall().getArg(2), this.getMailCall().getArgByName("subject")]
or
result = this.getMailCall().getAMethodCall(["subject", "set_subject"]).getArg(0)
or
result = this.sendgridWrite("subject")
}
}
}

View File

@@ -0,0 +1,81 @@
/**
* Provides classes modeling security-relevant aspects of the `flask` PyPI package.
* See https://flask.palletsprojects.com/en/1.1.x/.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
/** https://pythonhosted.org/Flask-Mail/#module-flask_mail */
private module FlaskMail {
/** Gets a reference to `flask_mail`, `flask_sendmail` and `flask.ext.sendmail`. */
private API::Node flaskMail() {
result = API::moduleImport(["flask_mail", "flask_sendmail", "flask.ext.sendmail"])
}
/** Gets a reference to `flask_mail.Mail()`, `flask_sendmail.Mail()` and `flask.ext.sendmail.Mail()`. */
private API::Node flaskMailInstance() { result = flaskMail().getMember("Mail").getReturn() }
/**
* Gets a call to `mail.send()`.
*
* Given the following example:
*
* ```py
* msg = Message(subject="Subject",
* sender="from@example.com",
* recipients=["to@example.com"],
* body="plain-text body",
* html=request.args["html"])
* mail.send(msg)
* ```
*
* * `this` would be `mail.send(msg)`.
* * `getPlainTextBody()`'s result would be `"plain-text body"`.
* * `getHtmlBody()`'s result would be `request.args["html"]`.
* * `getTo()`'s result would be `["to@example.com"]`.
* * `getFrom()`'s result would be `"from@example.com"`.
* * `getSubject()`'s result would be `"Subject"`.
*/
private class FlaskMail extends DataFlow::CallCfgNode, EmailSender::Range {
FlaskMail() {
this =
[flaskMailInstance(), flaskMailInstance().getMember("connect").getReturn()]
.getMember(["send", "send_message"])
.getACall()
}
private DataFlow::CallCfgNode getMessage() { result = this.getArg(0).getALocalSource() }
bindingset[argumentPosition]
private DataFlow::Node getFlaskMailArgument(int argumentPosition, string argumentName) {
argumentPosition in [[0 .. 3], 5] and
argumentName in ["body", "html", "recipients", "sender", "subject"] and
result in [
this.getMessage().getArg(argumentPosition), this.getMessage().getArgByName(argumentName)
]
or
exists(DataFlow::AttrWrite write |
write.getObject().getALocalSource() = this.getMessage() and
write.getAttributeName() = argumentName and
result = write.getValue()
)
}
override DataFlow::Node getPlainTextBody() { result = this.getFlaskMailArgument(2, "body") }
override DataFlow::Node getHtmlBody() { result = this.getFlaskMailArgument(3, "html") }
override DataFlow::Node getTo() {
result = this.getFlaskMailArgument(1, "recipients")
or
result = this.getMessage().getAMethodCall("add_recipient").getACall().getArg(0)
}
override DataFlow::Node getFrom() { result = this.getFlaskMailArgument(5, "sender") }
override DataFlow::Node getSubject() { result = this.getFlaskMailArgument(0, "subject") }
}
}

View File

@@ -0,0 +1,177 @@
private import python
private import semmle.python.dataflow.new.DataFlow
private import experimental.semmle.python.Concepts
private import semmle.python.ApiGraphs
private import semmle.python.dataflow.new.TaintTracking2
module SmtpLib {
/** Gets a reference to `smtplib.SMTP_SSL` */
private API::Node smtpConnectionInstance() {
result = API::moduleImport("smtplib").getMember("SMTP_SSL")
}
/** Gets a reference to `email.mime.multipart.MIMEMultipart` */
private API::Node smtpMimeMultipartInstance() {
result =
API::moduleImport("email").getMember("mime").getMember("multipart").getMember("MIMEMultipart")
}
/** Gets a reference to `email.mime.text.MIMEText` */
private API::Node smtpMimeTextInstance() {
result = API::moduleImport("email").getMember("mime").getMember("text").getMember("MIMEText")
}
private DataFlow::CallCfgNode mimeText(string mimetype) {
result = smtpMimeTextInstance().getACall() and
[result.getArg(1), result.getArgByName("_subtype")].asExpr().(StrConst).getText() = mimetype
}
/**
* Gets flow from `MIMEText()` to `MIMEMultipart(_subparts=(part1, part2))`'s `_subparts`
* argument. Used because of the impossibility to get local source nodes from `_subparts`'
* `(List|Tuple)` elements.
*/
private class SMTPMessageConfig extends TaintTracking2::Configuration {
SMTPMessageConfig() { this = "SMTPMessageConfig" }
override predicate isSource(DataFlow::Node source) { source = mimeText(_) }
override predicate isSink(DataFlow::Node sink) {
sink = smtpMimeMultipartInstance().getACall().getArgByName("_subparts")
}
}
/**
* Using the `MimeText` call retrieves the content argument whose type argument equals `mimetype`.
* This call flows into `MIMEMultipart`'s `_subparts` argument or the `.attach()` method call
* and both local source nodes correlate to `smtp`'s `sendmail` call 3rd argument's local source.
*
* Given the following example with `getSmtpMessage(any(SmtpLibSendMail s), "html")`:
*
* ```py
* part1 = MIMEText(text, "plain")
* part2 = MIMEText(html, "html")
* message = MIMEMultipart(_subparts=(part1, part2))
* server.sendmail(sender_email, receiver_email, message.as_string())
* ```
*
* * `source` would be `MIMEText(text, "html")`.
* * `sink` would be `MIMEMultipart(_subparts=(part1, part2))`.
* * Then `message` local source node is correlated to `sink`.
* * Then the flow from `source` to `_subparts` is checked.
*
* Given the following example with `getSmtpMessage(any(SmtpLibSendMail s), "html")`:
*
* ```py
* part1 = MIMEText(text, "plain")
* part2 = MIMEText(html, "html")
* message = MIMEMultipart("alternative")
* message.attach(part1)
* message.attach(part2)
* server.sendmail(sender_email, receiver_email, message.as_string())
* ```
*
* * `source` would be `MIMEText(text, "html")`.
* * `sink` would be `message.attach(part2)`.
* * Then `sink`'s object (`message`) local source is correlated to `server.sendmail`
* 3rd argument local source (`MIMEMultipart("alternative")`).
* * Then the flow from `source` to `sink` 1st argument is checked.
*/
bindingset[mimetype]
private DataFlow::Node getSmtpMessage(DataFlow::CallCfgNode sendCall, string mimetype) {
exists(DataFlow::Node source, DataFlow::Node sink |
source = mimeText(mimetype) and
(
// via _subparts
sink = smtpMimeMultipartInstance().getACall() and
sink =
[sendCall.getArg(2), sendCall.getArg(2).(DataFlow::MethodCallNode).getObject()]
.getALocalSource() and
any(SMTPMessageConfig a)
.hasFlow(source, sink.(DataFlow::CallCfgNode).getArgByName("_subparts"))
or
// via .attach()
sink = smtpMimeMultipartInstance().getReturn().getMember("attach").getACall() and
sink.(DataFlow::MethodCallNode).getObject().getALocalSource() =
[sendCall.getArg(2), sendCall.getArg(2).(DataFlow::MethodCallNode).getObject()]
.getALocalSource() and
source.(DataFlow::CallCfgNode).flowsTo(sink.(DataFlow::CallCfgNode).getArg(0))
) and
result = source.(DataFlow::CallCfgNode).getArg(0)
)
}
/**
* Gets a message subscript write by correlating subscript's object local source with
* `smtp`'s `sendmail` call 3rd argument's local source.
*
* Given the following example with `getSMTPSubscriptByIndex(any(SmtpLibSendMail s), "Subject")`:
*
* ```py
* message = MIMEMultipart("alternative")
* message["Subject"] = "multipart test"
* server.sendmail(sender_email, receiver_email, message.as_string())
* ```
*
* * `def` would be `message["Subject"]` (`DefinitionNode`)
* * `sub` would be `message["Subject"]` (`Subscript`)
* * `result` would be `"multipart test"`
*/
private DataFlow::Node getSMTPSubscriptByIndex(DataFlow::CallCfgNode sendCall, string index) {
exists(DefinitionNode def, Subscript sub |
sub = def.getNode() and
DataFlow::exprNode(sub.getObject()).getALocalSource() =
[sendCall.getArg(2), sendCall.getArg(2).(DataFlow::MethodCallNode).getObject()]
.getALocalSource() and
sub.getIndex().(StrConst).getText() = index and
result.asCfgNode() = def.getValue()
)
}
/**
* Gets a reference to `smtplib.SMTP_SSL().sendmail()`.
*
* Given the following example:
*
* ```py
* part1 = MIMEText(text, "plain")
* part2 = MIMEText(html, "html")
*
* message = MIMEMultipart(_subparts=(part1, part2))
* message["Subject"] = "multipart test"
* message["From"] = sender_email
* message["To"] = receiver_email
*
* server.login(sender_email, "SERVER_PASSWORD")
* server.sendmail(sender_email, receiver_email, message.as_string())
* ```
*
* * `this` would be `server.sendmail(sender_email, receiver_email, message.as_string())`.
* * `getPlainTextBody()`'s result would be `text`.
* * `getHtmlBody()`'s result would be `html`.
* * `getTo()`'s result would be `receiver_email`.
* * `getFrom()`'s result would be `sender_email`.
* * `getSubject()`'s result would be `"multipart test"`.
*/
private class SmtpLibSendMail extends DataFlow::CallCfgNode, EmailSender::Range {
SmtpLibSendMail() {
this = smtpConnectionInstance().getReturn().getMember("sendmail").getACall()
}
override DataFlow::Node getPlainTextBody() { result = getSmtpMessage(this, "plain") }
override DataFlow::Node getHtmlBody() { result = getSmtpMessage(this, "html") }
override DataFlow::Node getTo() {
result in [this.getArg(1), getSMTPSubscriptByIndex(this, "To")]
}
override DataFlow::Node getFrom() {
result in [this.getArg(0), getSMTPSubscriptByIndex(this, "From")]
}
override DataFlow::Node getSubject() {
result in [this.getArg(2), getSMTPSubscriptByIndex(this, "Subject")]
}
}
}

View File

@@ -0,0 +1,46 @@
/**
* Provides a taint-tracking configuration for detecting reflected server-side
* cross-site scripting vulnerabilities.
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.RemoteFlowSources
import semmle.python.dataflow.new.BarrierGuards
import experimental.semmle.python.Concepts
import semmle.python.Concepts
import semmle.python.ApiGraphs
/**
* A taint-tracking configuration for detecting reflected server-side cross-site
* scripting vulnerabilities.
*/
class ReflectedXssConfiguration extends TaintTracking::Configuration {
ReflectedXssConfiguration() { this = "ReflectedXssConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink = any(EmailSender email).getHtmlBody() }
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof StringConstCompare
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
sanitizer = any(HtmlEscaping esc).getOutput()
}
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
exists(DataFlow::CallCfgNode htmlContentCall |
htmlContentCall =
API::moduleImport("sendgrid")
.getMember("helpers")
.getMember("mail")
.getMember("HtmlContent")
.getACall() and
nodeTo = htmlContentCall and
nodeFrom = htmlContentCall.getArg(0)
)
}
}

View File

@@ -487,7 +487,8 @@ class CryptographicOperationTest extends InlineExpectationsTest {
override string getARelevantTag() {
result in [
"CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm"
"CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm",
"CryptographicOperationBlockMode"
]
}
@@ -507,6 +508,10 @@ class CryptographicOperationTest extends InlineExpectationsTest {
element = cryptoOperation.toString() and
value = cryptoOperation.getAlgorithm().getName() and
tag = "CryptographicOperationAlgorithm"
or
element = cryptoOperation.toString() and
value = cryptoOperation.getBlockMode() and
tag = "CryptographicOperationBlockMode"
)
)
}

View File

@@ -0,0 +1,96 @@
edges
| flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute |
| flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute |
| flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript |
| flask_mail.py:18:14:18:20 | ControlFlowNode for request | flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute |
| flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript |
| flask_mail.py:31:24:31:30 | ControlFlowNode for request | flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute |
| flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript |
| sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute |
| sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript |
| sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:34:26:45 | ControlFlowNode for Attribute |
| sendgrid_mail.py:26:34:26:45 | ControlFlowNode for Attribute | sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript |
| sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() |
| sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute |
| sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:62 | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:61 | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:62 | ControlFlowNode for Attribute | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:78 | ControlFlowNode for Subscript |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:78 | ControlFlowNode for Subscript | sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() |
| sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:61 | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:61 | ControlFlowNode for Attribute | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:76 | ControlFlowNode for Subscript |
| sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:76 | ControlFlowNode for Subscript | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() |
| sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript |
| sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() |
| smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute |
| smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript |
| smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html |
| smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute |
| smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript |
| smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html |
nodes
| django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| flask_mail.py:13:22:13:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_mail.py:18:14:18:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_mail.py:31:24:31:30 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | semmle.label | ControlFlowNode for HtmlContent() |
| sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| sendgrid_mail.py:26:34:26:45 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:62 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:78 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:61 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:76 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | semmle.label | ControlFlowNode for html |
| smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | semmle.label | ControlFlowNode for html |
subpaths
#select
| django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | a user-provided value |
| django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | a user-provided value |
| django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | a user-provided value |
| flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:13:22:13:28 | ControlFlowNode for request | a user-provided value |
| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:13:22:13:28 | ControlFlowNode for request | a user-provided value |
| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:18:14:18:20 | ControlFlowNode for request | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:18:14:18:20 | ControlFlowNode for request | a user-provided value |
| flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | flask_mail.py:31:24:31:30 | ControlFlowNode for request | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:31:24:31:30 | ControlFlowNode for request | a user-provided value |
| sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | a user-provided value |
| sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | a user-provided value |
| sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | a user-provided value |
| sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value |
| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value |
| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | a user-provided value |
| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value |
| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | a user-provided value |
| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | a user-provided value |
| smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | a user-provided value |
| smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | a user-provided value |

View File

@@ -0,0 +1 @@
experimental/Security/CWE-079/ReflectedXSS.ql

View File

@@ -0,0 +1,25 @@
import django.http
from django.core.mail import send_mail, mail_admins, mail_managers
def django_response(request):
"""
The Django.core.mail#send_mail function source code can be found in the link below:
https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L38
send_mass_mail does not provide html_message as an argument to it's function. See the link below for more info:
https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L64
"""
send_mail("Subject", "plain-text body", "from@example.com",
["to@example.com"], html_message=django.http.request.GET.get("html"))
def django_response(request):
"""
The Django.core.mail#mail_admins and Django.core.mail#mail_managers functions source code can be found in the link below:
https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L90-L121
"""
mail_admins("Subject", "plain-text body",
html_message=django.http.request.GET.get("html"))
mail_managers("Subject", "plain-text body",
html_message=django.http.request.GET.get("html"))

View File

@@ -0,0 +1,32 @@
from flask import request, Flask
from flask_mail import Mail, Message
app = Flask(__name__)
mail = Mail(app)
@app.route("/send")
def send():
msg = Message(subject="Subject",
sender="from@example.com",
recipients=["to@example.com"],
body="plain-text body",
html=request.args["html"])
# The message can contain a body and/or HTML:
msg.body = "plain-text body"
# The email's HTML can be set via msg.html or as an initialize argument when creating a Message object.
msg.html = request.args["html"]
mail.send(msg)
@app.route("/connect")
def connect():
"""
Minimal example to test mail.connect() usage
"""
with mail.connect() as conn:
msg = Message(subject="Subject",
sender="from@example.com",
recipients=["to@example.com"],
html=request.args["html"])
conn.send(msg)

View File

@@ -0,0 +1,57 @@
from flask import request, Flask
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail, Email, To, Content, MimeType, HtmlContent
app = Flask(__name__)
@app.route("/send")
def send():
message = Mail(
from_email='from_email@example.com',
to_emails='to@example.com',
subject='Sending with Twilio SendGrid is Fun',
html_content=request.args["html_content"])
sg = SendGridAPIClient('SENDGRID_API_KEY')
sg.send(message)
@app.route("/send-HtmlContent")
def send():
message = Mail(
from_email='from_email@example.com',
to_emails='to@example.com',
subject='Sending with Twilio SendGrid is Fun',
html_content=HtmlContent(request.args["html_content"]))
sg = SendGridAPIClient('SENDGRID_API_KEY')
sg.send(message)
@app.route("/send_post")
def send_post():
from_email = Email("test@example.com")
to_email = To("test@example.com")
subject = "Sending with SendGrid is Fun"
html_content = Content("text/html", request.args["html_content"])
plain_content = Content("text/plain", request.args["plain_content"])
mail = Mail(from_email, to_email, subject, plain_content, html_content)
sg = SendGridAPIClient(api_key='SENDGRID_API_KEY')
response = sg.client.mail.send.post(request_body=mail.get())
@app.route("/send_post2")
def send_post2():
from_email = Email("test@example.com")
to_email = To("test@example.com")
subject = "Sending with SendGrid is Fun"
html_content = Content(MimeType.html, request.args["html_content"])
plain_content = Content(MimeType.text, request.args["plain_content"])
mail = Mail(from_email, to_email, subject, plain_content, html_content)
sg = SendGridAPIClient(api_key='SENDGRID_API_KEY')
response = sg.client.mail.send.post(request_body=mail.get())

View File

@@ -0,0 +1,48 @@
import sendgrid
import os
from flask import request, Flask
app = Flask(__name__)
@app.route("/sendgrid")
def send():
sg = sendgrid.SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
data = {
"content": [
{
"type": "text/html",
"value": "<html>{}</html>".format(request.args["html_content"])
}
],
"from": {
"email": "sam.smith@example.com",
"name": "Sam Smith"
},
"headers": {},
"mail_settings": {
"footer": {
"enable": True,
"html": "<html>{}</html>".format(request.args["html_footer"]),
"text": "Thanks,/n The SendGrid Team"
},
},
"reply_to": {
"email": "sam.smith@example.com",
"name": "Sam Smith"
},
"send_at": 1409348513,
"subject": "Hello, World!",
"template_id": "[YOUR TEMPLATE ID GOES HERE]",
"tracking_settings": {
"subscription_tracking": {
"enable": True,
"html": "<html>{}</html>".format(request.args["html_tracking"]),
"substitution_tag": "<%click here%>",
"text": "If you would like to unsubscribe and stop receiving these emails <% click here %>."
}
}
}
response = sg.client.mail.send.post(request_body=data)

View File

@@ -0,0 +1,42 @@
# This test checks that the developer doesn't pass a MIMEText instance to a MIMEMultipart initializer via the subparts parameter.
from flask import Flask, request
import json
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
app = Flask(__name__)
@app.route("/")
def email_person():
sender_email = "sender@gmail.com"
receiver_email = "receiver@example.com"
name = request.args['search']
# Create the plain-text and HTML version of your message
text = "hello there"
html = f"hello {name}"
# Turn these into plain/html MIMEText objects
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message = MIMEMultipart(_subparts=(part1, part2))
message["Subject"] = "multipart test"
message["From"] = sender_email
message["To"] = receiver_email
# Create secure connection with server and send email
context = ssl.create_default_context()
server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context)
server.login(sender_email, "SERVER_PASSWORD")
server.sendmail(
sender_email, receiver_email, message.as_string()
)
# if __name__ == "__main__":
# app.run(debug=True)

View File

@@ -0,0 +1,45 @@
# This test checks that the developer doesn't pass a MIMEText instance to a MIMEMultipart message.
from flask import Flask, request
import json
import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
app = Flask(__name__)
@app.route("/")
def email_person():
sender_email = "sender@gmail.com"
receiver_email = "receiver@example.com"
message = MIMEMultipart("alternative")
message["Subject"] = "multipart test"
message["From"] = sender_email
message["To"] = receiver_email
name = request.args['name']
# Create the plain-text and HTML version of your message
text = "hello there"
html = f"hello {name}"
# Turn these into plain/html MIMEText objects
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
# Add HTML/plain-text parts to MIMEMultipart message
# The email client will try to render the last part first
message.attach(part1)
message.attach(part2)
# Create secure connection with server and send email
context = ssl.create_default_context()
server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context)
server.login(sender_email, "SERVER_PASSWORD")
server.sendmail(
sender_email, receiver_email, message.as_string()
)
# if __name__ == "__main__":
# app.run(debug=True)

View File

@@ -21,14 +21,14 @@ padding = b"\0"*padding_len
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
# using separate .encrypt calls on individual lines does not work
whole_plantext = secret_message + padding
encrypted = cipher.encrypt(whole_plantext) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=whole_plantext
encrypted = cipher.encrypt(whole_plantext) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=whole_plantext CryptographicOperationBlockMode=CBC
print("encrypted={}".format(encrypted))
print()
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
decrypted = cipher.decrypt(encrypted) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=encrypted
decrypted = cipher.decrypt(encrypted) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=encrypted CryptographicOperationBlockMode=CBC
decrypted = decrypted[:-padding_len]

View File

@@ -21,14 +21,14 @@ padding = b"\0"*padding_len
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
# using separate .encrypt calls on individual lines does not work
whole_plantext = secret_message + padding
encrypted = cipher.encrypt(whole_plantext) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=whole_plantext
encrypted = cipher.encrypt(whole_plantext) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=whole_plantext CryptographicOperationBlockMode=CBC
print("encrypted={}".format(encrypted))
print()
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
decrypted = cipher.decrypt(encrypted) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=encrypted
decrypted = cipher.decrypt(encrypted) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=encrypted CryptographicOperationBlockMode=CBC
decrypted = decrypted[:-padding_len]

View File

@@ -22,8 +22,8 @@ padding = b"\0"*padding_len
encryptor = cipher.encryptor()
print(padding_len)
encrypted = encryptor.update(secret_message) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=secret_message
encrypted += encryptor.update(padding) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=padding
encrypted = encryptor.update(secret_message) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=secret_message CryptographicOperationBlockMode=CBC
encrypted += encryptor.update(padding) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=padding CryptographicOperationBlockMode=CBC
encrypted += encryptor.finalize()
print("encrypted={}".format(encrypted))
@@ -31,7 +31,7 @@ print("encrypted={}".format(encrypted))
print()
decryptor = cipher.decryptor()
decrypted = decryptor.update(encrypted) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=encrypted
decrypted = decryptor.update(encrypted) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationInput=encrypted CryptographicOperationBlockMode=CBC
decrypted += decryptor.finalize()
decrypted = decrypted[:-padding_len]

View File

@@ -1,2 +1,4 @@
| test_cryptodome.py:11:13:11:42 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 is broken or weak, and should not be used. |
| test_cryptodome.py:16:13:16:42 | ControlFlowNode for Attribute() | The block mode ECB is broken or weak, and should not be used. |
| test_cryptography.py:13:13:13:44 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 is broken or weak, and should not be used. |
| test_cryptography.py:22:13:22:58 | ControlFlowNode for Attribute() | The block mode ECB is broken or weak, and should not be used. |

View File

@@ -1,5 +1,5 @@
# snippet from python/ql/test/experimental/library-tests/frameworks/cryptodome/test_rc4.py
from Cryptodome.Cipher import ARC4
from Cryptodome.Cipher import ARC4, AES
import os
@@ -11,3 +11,8 @@ cipher = ARC4.new(key)
encrypted = cipher.encrypt(secret_message) # NOT OK
print(secret_message, encrypted)
cipher = AES.new(key, AES.MODE_ECB)
encrypted = cipher.encrypt(secret_message) # NOT OK
print(secret_message, encrypted)

View File

@@ -1,5 +1,5 @@
# snippet from python/ql/test/experimental/library-tests/frameworks/cryptography/test_rc4.py
from cryptography.hazmat.primitives.ciphers import algorithms, Cipher
from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher
import os
key = os.urandom(256//8)
@@ -14,3 +14,12 @@ encrypted = encryptor.update(secret_message) # NOT OK
encrypted += encryptor.finalize()
print(secret_message, encrypted)
algorithm = algorithms.AES(key)
cipher = Cipher(algorithm, mode=modes.ECB())
encryptor = cipher.encryptor()
encrypted = encryptor.update(secret_message + b'\x80\x00') # NOT OK
encrypted += encryptor.finalize()
print(secret_message, encrypted)

BIN
ruby/Cargo.lock generated

Binary file not shown.

View File

@@ -17,4 +17,4 @@ tracing = "0.1"
tracing-subscriber = { version = "0.3.3", features = ["env-filter"] }
rayon = "1.5.0"
num_cpus = "1.13.0"
regex = "1.4.3"
regex = "1.5.5"

View File

@@ -826,7 +826,19 @@ module Logging {
* to improve our libraries in the future to more precisely capture this aspect.
*/
module Cryptography {
import security.CryptoAlgorithms
// Since we still rely on `isWeak` predicate on `CryptographicOperation` in Ruby, we
// modify that part of the shared concept... which means we have to explicitly
// re-export everything else.
// Using SC shorthand for "Shared Cryptography"
import codeql.ruby.internal.ConceptsShared::Cryptography as SC
class CryptographicAlgorithm = SC::CryptographicAlgorithm;
class EncryptionAlgorithm = SC::EncryptionAlgorithm;
class HashingAlgorithm = SC::HashingAlgorithm;
class PasswordHashingAlgorithm = SC::PasswordHashingAlgorithm;
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
@@ -835,15 +847,9 @@ module Cryptography {
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `CryptographicOperation::Range` instead.
*/
class CryptographicOperation extends DataFlow::Node instanceof CryptographicOperation::Range {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
DataFlow::Node getAnInput() { result = super.getAnInput() }
/** Holds if this encryption operation is known to be weak. */
predicate isWeak() { super.isWeak() }
class CryptographicOperation extends SC::CryptographicOperation instanceof CryptographicOperation::Range {
/** DEPRECATED: Use `getAlgorithm().isWeak() or getBlockMode().isWeak()` instead */
deprecated predicate isWeak() { super.isWeak() }
}
/** Provides classes for modeling new applications of a cryptographic algorithms. */
@@ -855,15 +861,11 @@ module Cryptography {
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `CryptographicOperation` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
abstract CryptographicAlgorithm getAlgorithm();
abstract class Range extends SC::CryptographicOperation::Range {
/** DEPRECATED: Use `getAlgorithm().isWeak() or getBlockMode().isWeak()` instead */
deprecated predicate isWeak() { this.getAlgorithm().isWeak() or this.getBlockMode().isWeak() }
}
}
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
abstract DataFlow::Node getAnInput();
/** Holds if this encryption operation is known to be weak. */
abstract predicate isWeak();
}
}
class BlockMode = SC::BlockMode;
}

View File

@@ -1,3 +1,3 @@
This directory contains QL modules that model classes and modules in the Ruby standard library.
Files are named after the most common or top-level class in each library.
See https://docs.ruby-lang.org/en/3.1/doc/standard_library_rdoc.html for a full list.
See https://docs.ruby-lang.org/en/3.1/standard_library_rdoc.html for a full list.

View File

@@ -4,3 +4,4 @@
*/
import codeql.ruby.DataFlow
import codeql.ruby.security.CryptoAlgorithms as CryptoAlgorithms

View File

@@ -11,3 +11,79 @@
*/
private import ConceptsImports
/**
* Provides models for cryptographic concepts.
*
* Note: The `CryptographicAlgorithm` class currently doesn't take weak keys into
* consideration for the `isWeak` member predicate. So RSA is always considered
* secure, although using a low number of bits will actually make it insecure. We plan
* to improve our libraries in the future to more precisely capture this aspect.
*/
module Cryptography {
class CryptographicAlgorithm = CryptoAlgorithms::CryptographicAlgorithm;
class EncryptionAlgorithm = CryptoAlgorithms::EncryptionAlgorithm;
class HashingAlgorithm = CryptoAlgorithms::HashingAlgorithm;
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `CryptographicOperation::Range` instead.
*/
class CryptographicOperation extends DataFlow::Node instanceof CryptographicOperation::Range {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
DataFlow::Node getAnInput() { result = super.getAnInput() }
/**
* Gets the block mode used to perform this cryptographic operation.
* This may have no result - for example if the `CryptographicAlgorithm` used
* is a stream cipher rather than a block cipher.
*/
BlockMode getBlockMode() { result = super.getBlockMode() }
}
/** Provides classes for modeling new applications of a cryptographic algorithms. */
module CryptographicOperation {
/**
* A data-flow node that is an application of a cryptographic algorithm. For example,
* encryption, decryption, signature-validation.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `CryptographicOperation` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
abstract CryptographicAlgorithm getAlgorithm();
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
abstract DataFlow::Node getAnInput();
/**
* Gets the block mode used to perform this cryptographic operation.
* This may have no result - for example if the `CryptographicAlgorithm` used
* is a stream cipher rather than a block cipher.
*/
abstract BlockMode getBlockMode();
}
}
/**
* A cryptographic block cipher mode of operation. This can be used to encrypt
* data of arbitrary length using a block encryption algorithm.
*/
class BlockMode extends string {
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR", "OPENPGP"] }
/** Holds if this block mode is considered to be insecure. */
predicate isWeak() { this = "ECB" }
}
}

View File

@@ -81,6 +81,9 @@ class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
/** Holds if this algorithm is a stream cipher. */
predicate isStreamCipher() { isStreamCipher(name) }
}
/**

View File

@@ -29,7 +29,9 @@ private string rankedInsecureAlgorithm(int i) {
// weak hash algorithms and block modes as well.
result =
rank[i](string s |
isWeakEncryptionAlgorithm(s) or isWeakHashingAlgorithm(s) or isWeakBlockMode(s)
isWeakEncryptionAlgorithm(s) or
isWeakHashingAlgorithm(s) or
s.(Cryptography::BlockMode).isWeak()
)
}
@@ -329,13 +331,9 @@ private API::Node cipherApi() {
result = API::getTopLevelMember("OpenSSL").getMember("Cipher").getMember("Cipher")
}
private class BlockMode extends string {
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR"] }
}
private newtype TCipherMode =
TStreamCipher() or
TBlockMode(BlockMode blockMode)
TBlockMode(Cryptography::BlockMode blockMode)
/**
* Represents the mode used by this stream cipher.
@@ -343,7 +341,8 @@ private newtype TCipherMode =
* block mode.
*/
private class CipherMode extends TCipherMode {
private BlockMode getBlockMode() { this = TBlockMode(result) }
/** Gets the underlying block mode, if any. */
Cryptography::BlockMode getBlockMode() { this = TBlockMode(result) }
/** Gets a textual representation of this node. */
string toString() {
@@ -360,7 +359,7 @@ private class CipherMode extends TCipherMode {
predicate isBlockMode(string s) { this.getBlockMode() = s.toUpperCase() }
/** Holds if this cipher mode is a weak block mode. */
predicate isWeak() { isWeakBlockMode(this.getBlockMode()) }
predicate isWeak() { this.getBlockMode().isWeak() }
}
private string getStringArgument(DataFlow::CallNode call, int i) {
@@ -371,6 +370,25 @@ private int getIntArgument(DataFlow::CallNode call, int i) {
result = call.getArgument(i).asExpr().getConstantValue().getInt()
}
bindingset[blockCipherName]
private Cryptography::BlockMode getCandidateBlockModeFromCipherName(string blockCipherName) {
result = blockCipherName.splitAt("-", [1, 2]).toUpperCase()
}
/**
* Gets the block mode specified as part of a block cipher name used to
* instantiate an `OpenSSL::Cipher` instance. If the block mode is not
* explicitly specified, this defaults to "CBC".
*/
bindingset[blockCipherName]
private Cryptography::BlockMode getBlockModeFromCipherName(string blockCipherName) {
// Extract the block mode from the cipher name
result = getCandidateBlockModeFromCipherName(blockCipherName)
or
// Fall back on the OpenSSL default of CBC if the block mode is unspecified
not exists(getCandidateBlockModeFromCipherName(blockCipherName)) and result = "CBC"
}
/**
* Holds if `call` is a call to `OpenSSL::Cipher.new` that instantiates a
* `cipher` instance with mode `cipherMode`.
@@ -382,8 +400,9 @@ private predicate cipherInstantiationGeneric(
// `OpenSSL::Cipher.new('<cipherName>')`
call = cipherApi().getAnInstantiation() and
cipherName = getStringArgument(call, 0) and
// CBC is used by default
cipherMode.isBlockMode("CBC")
if cipher.getAlgorithm().isStreamCipher()
then cipherMode = TStreamCipher()
else cipherMode.isBlockMode(getBlockModeFromCipherName(cipherName))
)
}
@@ -398,12 +417,12 @@ private predicate cipherInstantiationAES(
exists(string cipherName | cipher.matchesName(cipherName) |
// `OpenSSL::Cipher::AES` instantiations
call = cipherApi().getMember("AES").getAnInstantiation() and
exists(string keyLength, string blockMode |
exists(string keyLength, Cryptography::BlockMode blockMode |
// `OpenSSL::Cipher::AES.new('<keyLength-blockMode>')
exists(string arg0 |
arg0 = getStringArgument(call, 0) and
keyLength = arg0.splitAt("-", 0) and
blockMode = arg0.splitAt("-", 1).toUpperCase()
blockMode = getBlockModeFromCipherName(arg0)
)
or
// `OpenSSL::Cipher::AES.new(<keyLength>, '<blockMode>')`
@@ -419,7 +438,7 @@ private predicate cipherInstantiationAES(
call = cipherApi().getMember(mod).getAnInstantiation() and
// Canonical representation is `AES-<keyLength>`
blockAlgo = "AES-" + mod.suffix(3) and
exists(string blockMode |
exists(Cryptography::BlockMode blockMode |
if exists(getStringArgument(call, 0))
then
// `OpenSSL::Cipher::<blockAlgo>.new('<blockMode>')`
@@ -446,7 +465,7 @@ private predicate cipherInstantiationSpecific(
// Block ciphers with dedicated modules
exists(string blockAlgo | blockAlgo = ["BF", "CAST5", "DES", "IDEA", "RC2"] |
call = cipherApi().getMember(blockAlgo).getAnInstantiation() and
exists(string blockMode |
exists(Cryptography::BlockMode blockMode |
if exists(getStringArgument(call, 0))
then
// `OpenSSL::Cipher::<blockAlgo>.new('<blockMode>')`
@@ -546,8 +565,7 @@ private class CipherOperation extends Cryptography::CryptographicOperation::Rang
result = this.getArgument(0)
}
override predicate isWeak() {
cipherNode.getCipher().isWeak() or
cipherNode.getCipherMode().isWeak()
override Cryptography::BlockMode getBlockMode() {
result = cipherNode.getCipherMode().getBlockMode()
}
}

View File

@@ -67,6 +67,6 @@ predicate isStrongPasswordHashingAlgorithm(string name) {
predicate isWeakPasswordHashingAlgorithm(string name) { name = "EVPKDF" }
/**
* Holds if `name` corresponds to a weak block cipher mode of operation.
* Holds if `name` corresponds to a stream cipher.
*/
predicate isWeakBlockMode(string name) { name = "ECB" }
predicate isStreamCipher(string name) { name = ["CHACHA", "RC4", "ARC4", "ARCFOUR", "RABBIT"] }

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode.

View File

@@ -13,8 +13,10 @@
import ruby
import codeql.ruby.Concepts
from Cryptography::CryptographicOperation operation
where operation.isWeak()
select operation,
"The cryptographic algorithm " + operation.getAlgorithm().getName() +
" is broken or weak, and should not be used."
from Cryptography::CryptographicOperation operation, string msgPrefix
where
operation.getAlgorithm().isWeak() and
msgPrefix = "The cryptographic algorithm " + operation.getAlgorithm().getName()
or
operation.getBlockMode().isWeak() and msgPrefix = "The block mode " + operation.getBlockMode()
select operation, msgPrefix + " is broken or weak, and should not be used."

View File

@@ -0,0 +1,33 @@
import ruby
import codeql.ruby.Concepts
import TestUtilities.InlineExpectationsTest
class CryptographicOperationTest extends InlineExpectationsTest {
CryptographicOperationTest() { this = "CryptographicOperationTest" }
override string getARelevantTag() {
result in [
"CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm",
"CryptographicOperationBlockMode"
]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Cryptography::CryptographicOperation cryptoOperation |
location = cryptoOperation.getLocation() and
(
element = cryptoOperation.toString() and
value = "" and
tag = "CryptographicOperation"
or
element = cryptoOperation.toString() and
value = cryptoOperation.getAlgorithm().getName() and
tag = "CryptographicOperationAlgorithm"
or
element = cryptoOperation.toString() and
value = cryptoOperation.getBlockMode() and
tag = "CryptographicOperationBlockMode"
)
)
}
}

View File

@@ -0,0 +1,11 @@
require 'openssl'
strong = OpenSSL::Cipher.new 'AES-128-CBC' # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationBlockMode=CBC
weak_algorithm = OpenSSL::Cipher::DES.new # $ CryptographicOperation CryptographicOperationAlgorithm=DES CryptographicOperationBlockMode=CBC
weak_block_mode = OpenSSL::Cipher::AES.new(128, :ecb) # $ CryptographicOperation CryptographicOperationAlgorithm=AES CryptographicOperationBlockMode=ECB
weak_block_mode = OpenSSL::Cipher.new 'bf-ecb' # $ CryptographicOperation CryptographicOperationAlgorithm=BF CryptographicOperationBlockMode=ECB
stream_cipher = OpenSSL::Cipher.new 'chacha' # $ CryptographicOperation CryptographicOperationAlgorithm=CHACHA

View File

@@ -1,17 +1,18 @@
| broken_crypto.rb:4:8:4:34 | call to new | The cryptographic algorithm DES is broken or weak, and should not be used. |
| broken_crypto.rb:8:1:8:18 | call to update | The cryptographic algorithm DES is broken or weak, and should not be used. |
| broken_crypto.rb:12:8:12:43 | call to new | The cryptographic algorithm AES is broken or weak, and should not be used. |
| broken_crypto.rb:16:1:16:18 | call to update | The cryptographic algorithm AES is broken or weak, and should not be used. |
| broken_crypto.rb:28:1:28:35 | call to new | The cryptographic algorithm AES is broken or weak, and should not be used. |
| broken_crypto.rb:37:1:37:33 | call to new | The cryptographic algorithm AES is broken or weak, and should not be used. |
| broken_crypto.rb:42:1:42:33 | call to new | The cryptographic algorithm AES is broken or weak, and should not be used. |
| broken_crypto.rb:47:1:47:33 | call to new | The cryptographic algorithm AES is broken or weak, and should not be used. |
| broken_crypto.rb:52:1:52:29 | call to new | The cryptographic algorithm BF is broken or weak, and should not be used. |
| broken_crypto.rb:57:1:57:32 | call to new | The cryptographic algorithm CAST5 is broken or weak, and should not be used. |
| broken_crypto.rb:12:8:12:43 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:16:1:16:18 | call to update | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:28:1:28:35 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:37:1:37:33 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:42:1:42:33 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:47:1:47:33 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:52:1:52:29 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:57:1:57:32 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:60:1:60:24 | call to new | The cryptographic algorithm DES is broken or weak, and should not be used. |
| broken_crypto.rb:62:1:62:30 | call to new | The cryptographic algorithm DES is broken or weak, and should not be used. |
| broken_crypto.rb:67:1:67:31 | call to new | The cryptographic algorithm IDEA is broken or weak, and should not be used. |
| broken_crypto.rb:67:1:67:31 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:70:1:70:24 | call to new | The cryptographic algorithm RC2 is broken or weak, and should not be used. |
| broken_crypto.rb:72:1:72:30 | call to new | The block mode ECB is broken or weak, and should not be used. |
| broken_crypto.rb:72:1:72:30 | call to new | The cryptographic algorithm RC2 is broken or weak, and should not be used. |
| broken_crypto.rb:75:1:75:24 | call to new | The cryptographic algorithm RC4 is broken or weak, and should not be used. |
| broken_crypto.rb:77:1:77:29 | call to new | The cryptographic algorithm RC4 is broken or weak, and should not be used. |

View File

@@ -36,6 +36,7 @@ IterableDeclContext:
members: Decl*
ExtensionDecl:
extended_type_decl: NominalTypeDecl
_extends:
- GenericContext
- IterableDeclContext
@@ -470,6 +471,7 @@ OptionalEvaluationExpr:
sub_expr: Expr
OtherConstructorDeclRefExpr:
constructor_decl: ConstructorDecl
_extends: Expr
OverloadSetRefExpr:
@@ -1103,6 +1105,7 @@ ConcreteVarDecl:
ParamDecl:
_extends: VarDecl
is_inout: predicate
AssociatedTypeDecl:
_extends: AbstractTypeParamDecl

View File

@@ -66,6 +66,9 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
void visitParamDecl(swift::ParamDecl* decl) {
auto label = dispatcher_.assignNewLabel(decl);
dispatcher_.emit(ParamDeclsTrap{label});
if (decl->isInOut()) {
dispatcher_.emit(ParamDeclIsInoutTrap{label});
}
emitVarDecl(decl, label);
}
@@ -190,6 +193,14 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
emitAbstractStorageDecl(decl, label);
}
void visitExtensionDecl(swift::ExtensionDecl* decl) {
auto label = dispatcher_.assignNewLabel(decl);
auto typeLabel = dispatcher_.fetchLabel(decl->getExtendedNominal());
dispatcher_.emit(ExtensionDeclsTrap{label, typeLabel});
emitGenericContext(decl, label);
emitIterableDeclContext(decl, label);
}
private:
void emitConstructorDecl(swift::ConstructorDecl* decl, TrapLabel<ConstructorDeclTag> label) {
emitAbstractFunctionDecl(decl, label);

View File

@@ -525,6 +525,14 @@ class ExprVisitor : public AstVisitorBase<ExprVisitor> {
dispatcher_.emit(KeyPathApplicationExprsTrap{label, baseLabel, keyPathLabel});
}
void visitOtherConstructorDeclRefExpr(swift::OtherConstructorDeclRefExpr* expr) {
auto label = dispatcher_.assignNewLabel(expr);
assert(expr->getDecl() && "OtherConstructorDeclRefExpr has getDecl()");
auto ctorLabel = dispatcher_.fetchLabel(expr->getDecl());
dispatcher_.emit(OtherConstructorDeclRefExprsTrap{label, ctorLabel});
}
private:
TrapLabel<ArgumentTag> emitArgument(const swift::Argument& arg) {
auto argLabel = dispatcher_.createLabel<ArgumentTag>();

View File

@@ -102,3 +102,15 @@ class ExprCfgNode extends AstCfgNode {
/** Gets the underlying expression. */
Expr getExpr() { result = e }
}
class ApplyExprCfgNode extends ExprCfgNode {
override ApplyExpr e;
ExprCfgNode getArgument(int index) {
result.getNode().asAstNode() = e.getArgument(index).getExpr()
}
}
class CallExprCfgNode extends ApplyExprCfgNode {
override CallExpr e;
}

View File

@@ -1292,6 +1292,10 @@ module Exprs {
DeclRefExprLValueTree() { isLValue(ast) }
}
class OtherConstructorDeclRefTree extends AstLeafTree {
override OtherConstructorDeclRefExpr ast;
}
abstract class DeclRefExprRValueTree extends AstControlFlowTree {
override DeclRefExpr ast;

View File

@@ -71,6 +71,19 @@ module Ssa {
value.getNode().asAstNode() = var.getParentInitializer()
)
}
cached
predicate isInoutDef(ExprCfgNode argument) {
exists(
CallExpr c, BasicBlock bb, int blockIndex, int argIndex, VarDecl v, InOutExpr argExpr // TODO: use CFG node for assignment expr
|
this.definesAt(v, bb, blockIndex) and
bb.getNode(blockIndex).getNode().asAstNode() = c and
c.getArgument(argIndex).getExpr() = argExpr and
argExpr = argument.getNode().asAstNode() and
argExpr.getSubExpr() = v.getAnAccess() // TODO: fields?
)
}
}
cached

View File

@@ -3,7 +3,9 @@ private import DataFlowPrivate
private import DataFlowPublic
private import codeql.swift.controlflow.ControlFlowGraph
newtype TReturnKind = TNormalReturnKind()
newtype TReturnKind =
TNormalReturnKind() or
TParamReturnKind(int i) { exists(ParamDecl param | param.getIndex() = i) }
/**
* Gets a node that can read the value returned from `call` with return kind
@@ -28,16 +30,33 @@ class NormalReturnKind extends ReturnKind, TNormalReturnKind {
override string toString() { result = "return" }
}
/**
* A value returned from a callable using an `inout` parameter.
*/
class ParamReturnKind extends ReturnKind, TParamReturnKind {
int index;
ParamReturnKind() { this = TParamReturnKind(index) }
int getIndex() { result = index }
override string toString() { result = "param(" + index + ")" }
}
/**
* A callable. This includes callables from source code, as well as callables
* defined in library code.
*/
class DataFlowCallable extends TDataFlowCallable {
AbstractFunctionDecl func;
DataFlowCallable() { this = TDataFlowFunc(func) }
/** Gets a textual representation of this callable. */
string toString() { none() }
string toString() { result = func.toString() }
/** Gets the location of this callable. */
Location getLocation() { none() }
Location getLocation() { result = func.getLocation() }
}
/**
@@ -48,7 +67,7 @@ class DataFlowCall extends ExprNode {
DataFlowCall() { this.asExpr() instanceof CallExpr }
/** Gets the enclosing callable. */
DataFlowCallable getEnclosingCallable() { none() }
DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(this.getCfgNode().getScope()) }
}
cached

View File

@@ -1,6 +1,7 @@
private import swift
private import DataFlowPublic
private import DataFlowDispatch
private import codeql.swift.controlflow.ControlFlowGraph
private import codeql.swift.controlflow.CfgNodes
private import codeql.swift.dataflow.Ssa
private import codeql.swift.controlflow.BasicBlocks
@@ -20,7 +21,7 @@ predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos)
}
abstract class NodeImpl extends Node {
DataFlowCallable getEnclosingCallable() { none() }
abstract DataFlowCallable getEnclosingCallable();
/** Do not call: use `getLocation()` instead. */
abstract Location getLocationImpl();
@@ -60,7 +61,21 @@ private module Cached {
cached
newtype TNode =
TExprNode(ExprCfgNode e) or
TSsaDefinitionNode(Ssa::Definition def)
TSsaDefinitionNode(Ssa::Definition def) or
TInoutReturnNode(ParamDecl param) { param.isInout() } or
TInOutUpdateNode(ParamDecl param, CallExpr call) {
param.isInout() and
call.getStaticTarget() = param.getDeclaringFunction()
}
private predicate localSsaFlowStepUseUse(Ssa::Definition def, Node nodeFrom, Node nodeTo) {
def.adjacentReadPair(nodeFrom.getCfgNode(), nodeTo.getCfgNode()) and
(
nodeTo instanceof InoutReturnNode
implies
nodeTo.(InoutReturnNode).getParameter() = def.getSourceVariable()
)
}
private predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
exists(Ssa::Definition def |
@@ -70,14 +85,34 @@ private module Cached {
or
// step from def to first read
nodeFrom.asDefinition() = def and
nodeTo.getCfgNode() = def.getAFirstRead()
nodeTo.getCfgNode() = def.getAFirstRead() and
(
nodeTo instanceof InoutReturnNode
implies
nodeTo.(InoutReturnNode).getParameter() = def.getSourceVariable()
)
or
// use-use flow
def.adjacentReadPair(nodeFrom.getCfgNode(), nodeTo.getCfgNode())
localSsaFlowStepUseUse(def, nodeFrom, nodeTo)
or
//localSsaFlowStepUseUse(def, nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
//or
// step from previous read to Phi node
localFlowSsaInput(nodeFrom, def, nodeTo.asDefinition())
)
or
exists(ParamReturnKind kind, ExprCfgNode arg |
arg =
nodeFrom
.(InOutUpdateNode)
.getCall(kind)
.getCfgNode()
.(CallExprCfgNode)
.getArgument(kind.getIndex()) and
nodeTo.asDefinition().(Ssa::WriteDefinition).isInoutDef(arg)
)
or
nodeFrom.asExpr() = nodeTo.asExpr().(InOutExpr).getSubExpr()
}
/**
@@ -172,6 +207,31 @@ private module ReturnNodes {
override ReturnKind getKind() { result instanceof NormalReturnKind }
}
class InoutReturnNodeImpl extends ReturnNode, TInoutReturnNode, NodeImpl {
ParamDecl param;
ControlFlowNode exit;
InoutReturnNodeImpl() {
this = TInoutReturnNode(param) and
exit instanceof ExitNode and
exit.getScope() = param.getDeclaringFunction()
}
override ReturnKind getKind() { result.(ParamReturnKind).getIndex() = param.getIndex() }
override ControlFlowNode getCfgNode() { result = exit }
override DataFlowCallable getEnclosingCallable() {
result = TDataFlowFunc(param.getDeclaringFunction())
}
ParamDecl getParameter() { result = param }
override Location getLocationImpl() { result = exit.getLocation() }
override string toStringImpl() { result = param.toString() + "[return]" }
}
}
import ReturnNodes
@@ -188,6 +248,26 @@ private module OutNodes {
result = this and kind instanceof NormalReturnKind
}
}
class InOutUpdateNode extends OutNode, TInOutUpdateNode, NodeImpl {
ParamDecl param;
CallExpr call;
InOutUpdateNode() { this = TInOutUpdateNode(param, call) }
override DataFlowCall getCall(ReturnKind kind) {
result.asExpr() = call and
kind.(ParamReturnKind).getIndex() = param.getIndex()
}
override DataFlowCallable getEnclosingCallable() {
result = TDataFlowFunc(this.getCall(_).getCfgNode().getScope())
}
override Location getLocationImpl() { result = call.getLocation() }
override string toStringImpl() { result = param.toString() }
}
}
import OutNodes

View File

@@ -81,6 +81,10 @@ class SsaDefinitionNode extends Node, TSsaDefinitionNode {
override Ssa::Definition asDefinition() { result = def }
}
class InoutReturnNode extends Node instanceof InoutReturnNodeImpl {
ParamDecl getParameter() { result = super.getParameter() }
}
/**
* A node associated with an object after an operation that might have
* changed its state.

View File

@@ -3,6 +3,7 @@
private import swift
private import codeql.swift.controlflow.BasicBlocks as BasicBlocks
private import codeql.swift.controlflow.ControlFlowGraph
private import codeql.swift.controlflow.CfgNodes
class BasicBlock = BasicBlocks::BasicBlock;
@@ -28,6 +29,14 @@ predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain)
certain = true
)
or
exists(CallExpr call, Argument arg |
arg.getExpr().(InOutExpr).getSubExpr() = v.getAnAccess() and
call.getAnArgument() = arg and
call.getStaticTarget().getParam(arg.getIndex()).isInout() and
bb.getNode(i).getNode().asAstNode() = call and
certain = false
)
or
v instanceof ParamDecl and
bb.getNode(i).getNode().asAstNode() = v and
certain = true
@@ -42,4 +51,12 @@ predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain)
v = ref.getDecl() and
certain = true
)
or
exists(ExitNode exit, AbstractFunctionDecl func |
bb.getNode(i) = exit and
v.(ParamDecl).isInout() and
func.getAParam() = v and
bb.getScope() = func and
certain = true
)
}

View File

@@ -17,6 +17,4 @@ class Element extends ElementBase {
class UnknownElement extends Element {
UnknownElement() { isUnknown() }
override string toString() { result = "TBD (" + getPrimaryQlClasses() + ")" }
}

View File

@@ -1,4 +1,10 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
private import codeql.swift.generated.decl.ParamDecl
private import codeql.swift.elements.decl.AbstractFunctionDecl
class ParamDecl extends ParamDeclBase { }
class ParamDecl extends ParamDeclBase {
/** Gets the function which declares this parameter. */
AbstractFunctionDecl getDeclaringFunction() { result.getAParam() = this }
/** Gets the index of this parameter in its declaring function's parameter list. */
int getIndex() { exists(AbstractFunctionDecl func | func.getParam(result) = this) }
}

View File

@@ -2,7 +2,15 @@
import codeql.swift.elements.decl.Decl
import codeql.swift.elements.decl.GenericContext
import codeql.swift.elements.decl.IterableDeclContext
import codeql.swift.elements.decl.NominalTypeDecl
class ExtensionDeclBase extends @extension_decl, Decl, GenericContext, IterableDeclContext {
override string getAPrimaryQlClass() { result = "ExtensionDecl" }
NominalTypeDecl getExtendedTypeDecl() {
exists(NominalTypeDecl x |
extension_decls(this, x) and
result = x.resolve()
)
}
}

View File

@@ -3,4 +3,6 @@ import codeql.swift.elements.decl.VarDecl
class ParamDeclBase extends @param_decl, VarDecl {
override string getAPrimaryQlClass() { result = "ParamDecl" }
predicate isInout() { param_decl_is_inout(this) }
}

View File

@@ -1,6 +1,14 @@
// generated by codegen/codegen.py
import codeql.swift.elements.decl.ConstructorDecl
import codeql.swift.elements.expr.Expr
class OtherConstructorDeclRefExprBase extends @other_constructor_decl_ref_expr, Expr {
override string getAPrimaryQlClass() { result = "OtherConstructorDeclRefExpr" }
ConstructorDecl getConstructorDecl() {
exists(ConstructorDecl x |
other_constructor_decl_ref_exprs(this, x) and
result = x.resolve()
)
}
}

View File

@@ -98,7 +98,8 @@ iterable_decl_context_members(
);
extension_decls(
unique int id: @extension_decl
unique int id: @extension_decl,
int extended_type_decl: @nominal_type_decl ref
);
@nominal_type_decl =
@@ -974,7 +975,8 @@ optional_evaluation_exprs(
);
other_constructor_decl_ref_exprs(
unique int id: @other_constructor_decl_ref_expr
unique int id: @other_constructor_decl_ref_expr,
int constructor_decl: @constructor_decl ref
);
@overload_set_ref_expr =
@@ -2062,6 +2064,11 @@ param_decls(
unique int id: @param_decl
);
#keyset[id]
param_decl_is_inout(
int id: @param_decl ref
);
associated_type_decls(
unique int id: @associated_type_decl
);

View File

@@ -205,3 +205,7 @@
| declarations.swift:132:5:132:5 | newValue |
| declarations.swift:132:5:132:15 | willSet |
| declarations.swift:134:5:134:14 | didSet |
| declarations.swift:138:1:142:1 | extension |
| declarations.swift:139:3:141:3 | id |
| declarations.swift:139:8:139:8 | self |
| declarations.swift:144:1:144:7 | { ... } |

View File

@@ -134,3 +134,12 @@ struct HasPropertyAndObserver {
didSet { }
}
}
extension Int {
func id() -> Int {
return self
}
}
42.id()

View File

@@ -55,3 +55,4 @@
| declarations.swift:131:7:131:7 | set | (unnamed function decl) |
| declarations.swift:132:5:132:15 | willSet | (unnamed function decl) |
| declarations.swift:134:5:134:14 | didSet | (unnamed function decl) |
| declarations.swift:139:3:141:3 | id | id |

View File

@@ -50,3 +50,4 @@
| declarations.swift:131:7:131:7 | set | declarations.swift:131:7:131:7 | { ... } |
| declarations.swift:132:5:132:15 | willSet | declarations.swift:132:13:132:15 | { ... } |
| declarations.swift:134:5:134:14 | didSet | declarations.swift:134:12:134:14 | { ... } |
| declarations.swift:139:3:141:3 | id | declarations.swift:139:20:141:3 | { ... } |

View File

@@ -32,7 +32,6 @@
| expressions.swift:15:14:15:14 | 0 |
| expressions.swift:16:11:16:11 | AnError.Type |
| expressions.swift:16:11:16:19 | (Error) ... |
| expressions.swift:16:11:16:19 | (TBD (ExistentialType)) ... |
| expressions.swift:16:11:16:19 | call to ... |
| expressions.swift:16:19:16:19 | failed |
| expressions.swift:20:1:20:16 | try! ... |
@@ -77,7 +76,6 @@
| expressions.swift:35:6:35:6 | default terminator |
| expressions.swift:35:7:35:7 | d |
| expressions.swift:35:7:35:12 | (Any) ... |
| expressions.swift:35:7:35:12 | (TBD (ProtocolCompositionType)) ... |
| expressions.swift:35:7:35:12 | ...[...] |
| expressions.swift:35:7:35:12 | [...] |
| expressions.swift:35:7:35:12 | [...] |
@@ -125,7 +123,7 @@
| expressions.swift:54:1:54:1 | _ |
| expressions.swift:54:1:54:8 | ... = ... |
| expressions.swift:54:5:54:8 | #keyPath(...) |
| expressions.swift:54:6:54:8 | TBD (UnresolvedDotExpr) |
| expressions.swift:54:6:54:8 | UnresolvedDotExpr |
| expressions.swift:58:16:58:16 | 1234 |
| expressions.swift:59:1:59:1 | unsafeFunction |
| expressions.swift:59:1:59:34 | call to unsafeFunction |
@@ -162,7 +160,6 @@
| expressions.swift:79:5:79:11 | call to ... |
| expressions.swift:79:5:79:21 | call to ... |
| expressions.swift:79:5:79:21 | self = ... |
| expressions.swift:79:11:79:11 | TBD (OtherConstructorDeclRefExpr) |
| expressions.swift:79:11:79:11 | call to ... |
| expressions.swift:79:19:79:19 | 22 |
| expressions.swift:83:15:83:15 | Derived.Type |
@@ -244,4 +241,4 @@
| expressions.swift:154:22:154:56 | \\...[...] |
| expressions.swift:154:33:154:33 | keyPathB |
| expressions.swift:154:52:154:55 | #keyPath(...) |
| expressions.swift:154:53:154:55 | TBD (UnresolvedDotExpr) |
| expressions.swift:154:53:154:55 | UnresolvedDotExpr |

View File

@@ -13,7 +13,7 @@
| patterns.swift:12:14:12:21 | (...) |
| patterns.swift:12:15:12:15 | xx |
| patterns.swift:12:19:12:19 | yy |
| patterns.swift:16:10:16:14 | TBD (SequenceExpr) |
| patterns.swift:16:10:16:14 | SequenceExpr |
| patterns.swift:17:10:17:10 | _ |
| patterns.swift:24:9:24:9 | v |
| patterns.swift:24:9:24:12 | ... as ... |

View File

@@ -5,14 +5,9 @@
| types.swift:3:6:3:6 | default terminator | String |
| types.swift:3:7:3:7 | x | Int |
| types.swift:3:7:3:11 | (Any) ... | Any |
| types.swift:3:7:3:11 | (Any) ... | TBD (ProtocolCompositionType) |
| types.swift:3:7:3:11 | (TBD (ProtocolCompositionType)) ... | Any |
| types.swift:3:7:3:11 | (TBD (ProtocolCompositionType)) ... | TBD (ProtocolCompositionType) |
| types.swift:3:7:3:11 | ... call to + ... | Int |
| types.swift:3:7:3:11 | [...] | Any... |
| types.swift:3:7:3:11 | [...] | Any... |
| types.swift:3:7:3:11 | [...] | TBD (VariadicSequenceType) |
| types.swift:3:7:3:11 | [...] | TBD (VariadicSequenceType) |
| types.swift:3:9:3:9 | + | (Int.Type) -> (Int, Int) -> Int |
| types.swift:3:9:3:9 | Int.Type | Int.Type |
| types.swift:3:9:3:9 | call to + | (Int, Int) -> Int |

View File

@@ -99,12 +99,8 @@ cfg.swift:
# 19| (Error) ...
#-----| -> throw ...
# 19| (TBD (ExistentialType)) ...
#-----| -> throw ...
# 19| call to ...
#-----| -> (Error) ...
#-----| -> (TBD (ExistentialType)) ...
# 19| error1
#-----| -> MyError.Type
@@ -146,12 +142,8 @@ cfg.swift:
# 22| (Error) ...
#-----| -> throw ...
# 22| (TBD (ExistentialType)) ...
#-----| -> throw ...
# 22| call to ...
#-----| -> (Error) ...
#-----| -> (TBD (ExistentialType)) ...
# 22| error3
#-----| -> MyError.Type
@@ -218,12 +210,8 @@ cfg.swift:
# 29| (Any) ...
#-----| -> [...]
# 29| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 29| Did not throw.
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 29| [...]
#-----| -> default separator
@@ -293,13 +281,13 @@ cfg.swift:
#-----| -> ... is ...
# 37| ... is ...
#-----| -> TBD (SimpleIdentTypeRepr)
#-----| -> SimpleIdentTypeRepr
# 37| ... is ...
#-----| match -> print
#-----| no-match -> case ...
# 37| TBD (SimpleIdentTypeRepr)
# 37| SimpleIdentTypeRepr
#-----| -> ... is ...
# 38| print
@@ -317,12 +305,8 @@ cfg.swift:
# 38| (Any) ...
#-----| -> [...]
# 38| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 38| MyError
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 38| [...]
#-----| -> default separator
@@ -356,14 +340,10 @@ cfg.swift:
# 40| "..."
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 40| (Any) ...
#-----| -> [...]
# 40| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 40| [...]
#-----| -> default separator
@@ -890,7 +870,6 @@ cfg.swift:
# 112| n2
#-----| match -> .self
#-----| match -> TBD (DotSelfExpr)
# 112| n2
#-----| -> n3
@@ -898,9 +877,6 @@ cfg.swift:
# 112| .self
#-----| -> getter for .myInt
# 112| TBD (DotSelfExpr)
#-----| -> getter for .myInt
# 112| getter for .myInt
#-----| -> var ... = ...
@@ -937,9 +913,6 @@ cfg.swift:
# 114| .self
#-----| -> call to getMyInt
# 114| TBD (DotSelfExpr)
#-----| -> call to getMyInt
# 114| call to getMyInt
#-----| -> call to ...
@@ -948,7 +921,6 @@ cfg.swift:
# 114| getMyInt
#-----| -> .self
#-----| -> TBD (DotSelfExpr)
# 116| var ... = ...
#-----| -> n5
@@ -970,7 +942,6 @@ cfg.swift:
# 117| n6
#-----| match -> .self
#-----| match -> TBD (DotSelfExpr)
# 117| n6
#-----| -> n7
@@ -978,9 +949,6 @@ cfg.swift:
# 117| .self
#-----| -> getter for .myInt
# 117| TBD (DotSelfExpr)
#-----| -> getter for .myInt
# 117| getter for .myInt
#-----| -> var ... = ...
@@ -1017,9 +985,6 @@ cfg.swift:
# 119| .self
#-----| -> call to getMyInt
# 119| TBD (DotSelfExpr)
#-----| -> call to getMyInt
# 119| call to getMyInt
#-----| -> call to ...
@@ -1028,7 +993,6 @@ cfg.swift:
# 119| getMyInt
#-----| -> .self
#-----| -> TBD (DotSelfExpr)
# 121| var ... = ...
#-----| -> n9
@@ -1053,7 +1017,6 @@ cfg.swift:
# 122| n10
#-----| match -> .self
#-----| match -> TBD (DotSelfExpr)
# 122| n10
#-----| -> n11
@@ -1064,9 +1027,6 @@ cfg.swift:
# 122| .self
#-----| -> (C) ...
# 122| TBD (DotSelfExpr)
#-----| -> (C) ...
# 122| getter for .myInt
#-----| -> var ... = ...
@@ -1109,9 +1069,6 @@ cfg.swift:
# 124| .self
#-----| -> (C) ...
# 124| TBD (DotSelfExpr)
#-----| -> (C) ...
# 124| call to getMyInt
#-----| -> call to ...
@@ -1120,7 +1077,6 @@ cfg.swift:
# 124| getMyInt
#-----| -> .self
#-----| -> TBD (DotSelfExpr)
# 126| var ... = ...
#-----| -> n13
@@ -1145,7 +1101,6 @@ cfg.swift:
# 127| n14
#-----| match -> .self
#-----| match -> TBD (DotSelfExpr)
# 127| n14
#-----| -> n15
@@ -1153,9 +1108,6 @@ cfg.swift:
# 127| .self
#-----| -> getter for .myInt
# 127| TBD (DotSelfExpr)
#-----| -> getter for .myInt
# 127| getter for .myInt
#-----| -> var ... = ...
@@ -1195,9 +1147,6 @@ cfg.swift:
# 129| .self
#-----| -> call to getMyInt
# 129| TBD (DotSelfExpr)
#-----| -> call to getMyInt
# 129| call to getMyInt
#-----| -> call to ...
@@ -1206,7 +1155,6 @@ cfg.swift:
# 129| getMyInt
#-----| -> .self
#-----| -> TBD (DotSelfExpr)
# 131| var ... = ...
#-----| -> n17
@@ -1237,7 +1185,6 @@ cfg.swift:
# 132| n18
#-----| match -> .self
#-----| match -> TBD (DotSelfExpr)
# 132| n18
#-----| -> n19
@@ -1245,9 +1192,6 @@ cfg.swift:
# 132| .self
#-----| -> getter for .myInt
# 132| TBD (DotSelfExpr)
#-----| -> getter for .myInt
# 132| (Int?) ...
#-----| -> OptionalEvaluationExpr
@@ -1299,9 +1243,6 @@ cfg.swift:
# 134| .self
#-----| -> call to getMyInt
# 134| TBD (DotSelfExpr)
#-----| -> call to getMyInt
# 134| call to getMyInt
#-----| -> call to ...
@@ -1316,7 +1257,6 @@ cfg.swift:
# 134| getMyInt
#-----| -> .self
#-----| -> TBD (DotSelfExpr)
# 137| enter patterns
#-----| -> patterns
@@ -1461,12 +1401,8 @@ cfg.swift:
# 166| (Any) ...
#-----| -> [...]
# 166| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 166| 4
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 166| [...]
#-----| -> default separator
@@ -1492,12 +1428,8 @@ cfg.swift:
# 170| (Any) ...
#-----| -> [...]
# 170| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 170| 3
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 170| [...]
#-----| -> default separator
@@ -1523,12 +1455,8 @@ cfg.swift:
# 174| (Any) ...
#-----| -> [...]
# 174| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 174| 1
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 174| [...]
#-----| -> default separator
@@ -1554,12 +1482,8 @@ cfg.swift:
# 176| (Any) ...
#-----| -> [...]
# 176| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 176| 2
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 176| [...]
#-----| -> default separator
@@ -1621,9 +1545,6 @@ cfg.swift:
# 183| (Any) ...
#-----| -> [...]
# 183| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 183| [...]
#-----| -> default separator
@@ -1632,7 +1553,6 @@ cfg.swift:
# 183| x is greater than 2
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 185| if ... then { ... } else { ... }
#-----| -> StmtCondition
@@ -1746,9 +1666,6 @@ cfg.swift:
# 186| (Any) ...
#-----| -> [...]
# 186| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 186| [...]
#-----| -> default separator
@@ -1757,7 +1674,6 @@ cfg.swift:
# 186| x is 1
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 189| print
#-----| -> I can't guess the number
@@ -1774,12 +1690,8 @@ cfg.swift:
# 189| (Any) ...
#-----| -> [...]
# 189| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 189| I can't guess the number
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 189| [...]
#-----| -> default separator
@@ -2125,9 +2037,6 @@ cfg.swift:
# 231| (Any) ...
#-----| -> [...]
# 231| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 231| [...]
#-----| -> default separator
@@ -2136,7 +2045,6 @@ cfg.swift:
# 231| true
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 233| { ... }
#-----| -> print
@@ -2156,9 +2064,6 @@ cfg.swift:
# 234| (Any) ...
#-----| -> [...]
# 234| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 234| [...]
#-----| -> default separator
@@ -2167,7 +2072,6 @@ cfg.swift:
# 234| done
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 237| disjunct
#-----| -> b1
@@ -2235,9 +2139,6 @@ cfg.swift:
# 239| (Any) ...
#-----| -> [...]
# 239| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 239| [...]
#-----| -> default separator
@@ -2246,7 +2147,6 @@ cfg.swift:
# 239| b1 or b2
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 243| binaryExprs
#-----| -> a
@@ -3961,15 +3861,11 @@ cfg.swift:
# 301| default terminator
#-----| -> call to print
# 301| (Int) ...
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 301| (Any) ...
#-----| -> [...]
# 301| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 301| (Int) ...
#-----| -> (Any) ...
# 301| [...]
#-----| -> default separator
@@ -4055,15 +3951,11 @@ cfg.swift:
# 308| default terminator
#-----| -> call to print
# 308| (Int) ...
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 308| (Any) ...
#-----| -> [...]
# 308| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 308| (Int) ...
#-----| -> (Any) ...
# 308| [...]
#-----| -> default separator
@@ -4172,12 +4064,8 @@ cfg.swift:
# 316| (Any) ...
#-----| -> [...]
# 316| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 316| Iter
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 316| [...]
#-----| -> default separator
@@ -4200,12 +4088,8 @@ cfg.swift:
# 318| (Any) ...
#-----| -> [...]
# 318| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 318| Done
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 318| [...]
#-----| -> default separator
@@ -4295,15 +4179,11 @@ cfg.swift:
# 324| default terminator
#-----| -> call to print
# 324| (Int) ...
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 324| (Any) ...
#-----| -> [...]
# 324| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 324| (Int) ...
#-----| -> (Any) ...
# 324| [...]
#-----| -> default separator
@@ -4412,12 +4292,8 @@ cfg.swift:
# 332| (Any) ...
#-----| -> [...]
# 332| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 332| Iter
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 332| [...]
#-----| -> default separator
@@ -4440,12 +4316,8 @@ cfg.swift:
# 334| (Any) ...
#-----| -> [...]
# 334| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 334| Done
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 334| [...]
#-----| -> default separator
@@ -4482,15 +4354,11 @@ cfg.swift:
# 340| default terminator
#-----| -> call to print
# 340| (Int) ...
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 340| (Any) ...
#-----| -> [...]
# 340| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 340| (Int) ...
#-----| -> (Any) ...
# 340| [...]
#-----| -> default separator
@@ -4944,7 +4812,6 @@ cfg.swift:
# 378| init
#-----| -> call to ...
#-----| -> TBD (OtherConstructorDeclRefExpr)
# 379| super
#-----| -> call to ...
@@ -4961,9 +4828,6 @@ cfg.swift:
# 379| call to ...
#-----| -> super
# 379| TBD (OtherConstructorDeclRefExpr)
#-----| -> super
# 379| 0
#-----| -> call to ...
@@ -5014,12 +4878,8 @@ cfg.swift:
# 386| (Any) ...
#-----| -> [...]
# 386| (TBD (ProtocolCompositionType)) ...
#-----| -> [...]
# 386| Did not throw.
#-----| -> (Any) ...
#-----| -> (TBD (ProtocolCompositionType)) ...
# 386| [...]
#-----| -> default separator
@@ -5324,14 +5184,14 @@ cfg.swift:
#-----| -> var ... = ...
# 419| enter #keyPath(...)
#-----| -> TBD (UnresolvedDotExpr)
#-----| -> UnresolvedDotExpr
# 419| exit #keyPath(...)
# 419| exit #keyPath(...) (normal)
#-----| -> exit #keyPath(...)
# 419| TBD (UnresolvedDotExpr)
# 419| UnresolvedDotExpr
#-----| -> exit #keyPath(...) (normal)
# 420| var ... = ...
@@ -5347,14 +5207,14 @@ cfg.swift:
#-----| -> var ... = ...
# 420| enter #keyPath(...)
#-----| -> TBD (UnresolvedDotExpr)
#-----| -> UnresolvedDotExpr
# 420| exit #keyPath(...)
# 420| exit #keyPath(...) (normal)
#-----| -> exit #keyPath(...)
# 420| TBD (UnresolvedDotExpr)
# 420| UnresolvedDotExpr
#-----| -> exit #keyPath(...) (normal)
# 421| var ... = ...
@@ -5370,14 +5230,14 @@ cfg.swift:
#-----| -> var ... = ...
# 421| enter #keyPath(...)
#-----| -> TBD (UnresolvedDotExpr)
#-----| -> UnresolvedDotExpr
# 421| exit #keyPath(...)
# 421| exit #keyPath(...) (normal)
#-----| -> exit #keyPath(...)
# 421| TBD (UnresolvedDotExpr)
# 421| UnresolvedDotExpr
#-----| -> exit #keyPath(...) (normal)
# 422| var ... = ...
@@ -5393,7 +5253,7 @@ cfg.swift:
#-----| -> var ... = ...
# 422| enter #keyPath(...)
#-----| -> TBD (UnresolvedDotExpr)
#-----| -> UnresolvedDotExpr
# 422| exit #keyPath(...)
@@ -5403,7 +5263,7 @@ cfg.swift:
# 422| OptionalEvaluationExpr
#-----| -> exit #keyPath(...) (normal)
# 422| TBD (UnresolvedDotExpr)
# 422| UnresolvedDotExpr
#-----| -> OptionalEvaluationExpr
# 424| var ... = ...

View File

@@ -12,6 +12,23 @@ edges
| test.swift:29:26:29:29 | y : | test.swift:31:15:31:15 | y |
| test.swift:35:12:35:19 | call to source : | test.swift:39:15:39:29 | call to callee_source |
| test.swift:43:19:43:26 | call to source : | test.swift:50:15:50:15 | t |
| test.swift:53:1:56:1 | arg[return] : | test.swift:61:5:61:24 | arg : |
| test.swift:54:11:54:18 | call to source : | test.swift:53:1:56:1 | arg[return] : |
| test.swift:61:5:61:24 | arg : | test.swift:62:15:62:15 | x |
| test.swift:65:16:65:28 | WriteDef : | test.swift:65:1:70:1 | arg2[return] : |
| test.swift:65:16:65:28 | arg1 : | test.swift:65:1:70:1 | arg2[return] : |
| test.swift:73:18:73:25 | call to source : | test.swift:75:21:75:22 | &... : |
| test.swift:75:5:75:33 | arg2 : | test.swift:77:15:77:15 | y |
| test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | WriteDef : |
| test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | arg1 : |
| test.swift:75:21:75:22 | &... : | test.swift:75:5:75:33 | arg2 : |
| test.swift:80:1:82:1 | arg[return] : | test.swift:97:9:97:41 | arg : |
| test.swift:81:11:81:18 | call to source : | test.swift:80:1:82:1 | arg[return] : |
| test.swift:84:1:91:1 | arg[return] : | test.swift:104:9:104:54 | arg : |
| test.swift:86:15:86:22 | call to source : | test.swift:84:1:91:1 | arg[return] : |
| test.swift:89:15:89:22 | call to source : | test.swift:84:1:91:1 | arg[return] : |
| test.swift:97:9:97:41 | arg : | test.swift:98:19:98:19 | x |
| test.swift:104:9:104:54 | arg : | test.swift:105:19:105:19 | x |
nodes
| test.swift:6:19:6:26 | call to source : | semmle.label | call to source : |
| test.swift:7:15:7:15 | t1 | semmle.label | t1 |
@@ -33,12 +50,41 @@ nodes
| test.swift:39:15:39:29 | call to callee_source | semmle.label | call to callee_source |
| test.swift:43:19:43:26 | call to source : | semmle.label | call to source : |
| test.swift:50:15:50:15 | t | semmle.label | t |
| test.swift:53:1:56:1 | arg[return] : | semmle.label | arg[return] : |
| test.swift:54:11:54:18 | call to source : | semmle.label | call to source : |
| test.swift:61:5:61:24 | arg : | semmle.label | arg : |
| test.swift:62:15:62:15 | x | semmle.label | x |
| test.swift:65:1:70:1 | arg2[return] : | semmle.label | arg2[return] : |
| test.swift:65:16:65:28 | WriteDef : | semmle.label | WriteDef : |
| test.swift:65:16:65:28 | WriteDef : | semmle.label | arg1 : |
| test.swift:65:16:65:28 | arg1 : | semmle.label | WriteDef : |
| test.swift:65:16:65:28 | arg1 : | semmle.label | arg1 : |
| test.swift:73:18:73:25 | call to source : | semmle.label | call to source : |
| test.swift:75:5:75:33 | arg2 : | semmle.label | arg2 : |
| test.swift:75:21:75:22 | &... : | semmle.label | &... : |
| test.swift:77:15:77:15 | y | semmle.label | y |
| test.swift:80:1:82:1 | arg[return] : | semmle.label | arg[return] : |
| test.swift:81:11:81:18 | call to source : | semmle.label | call to source : |
| test.swift:84:1:91:1 | arg[return] : | semmle.label | arg[return] : |
| test.swift:86:15:86:22 | call to source : | semmle.label | call to source : |
| test.swift:89:15:89:22 | call to source : | semmle.label | call to source : |
| test.swift:97:9:97:41 | arg : | semmle.label | arg : |
| test.swift:98:19:98:19 | x | semmle.label | x |
| test.swift:104:9:104:54 | arg : | semmle.label | arg : |
| test.swift:105:19:105:19 | x | semmle.label | x |
subpaths
| test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | WriteDef : | test.swift:65:1:70:1 | arg2[return] : | test.swift:75:5:75:33 | arg2 : |
| test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | arg1 : | test.swift:65:1:70:1 | arg2[return] : | test.swift:75:5:75:33 | arg2 : |
#select
| test.swift:6:19:6:26 | call to source : | test.swift:7:15:7:15 | t1 |
| test.swift:6:19:6:26 | call to source : | test.swift:9:15:9:15 | t1 |
| test.swift:6:19:6:26 | call to source : | test.swift:10:15:10:15 | t2 |
| test.swift:25:20:25:27 | call to source : | test.swift:30:15:30:15 | x |
| test.swift:26:26:26:33 | call to source : | test.swift:31:15:31:15 | y |
| test.swift:35:12:35:19 | call to source : | test.swift:39:15:39:29 | call to callee_source |
| test.swift:43:19:43:26 | call to source : | test.swift:50:15:50:15 | t |
| test.swift:7:15:7:15 | t1 | test.swift:6:19:6:26 | call to source : | test.swift:7:15:7:15 | t1 | result |
| test.swift:9:15:9:15 | t1 | test.swift:6:19:6:26 | call to source : | test.swift:9:15:9:15 | t1 | result |
| test.swift:10:15:10:15 | t2 | test.swift:6:19:6:26 | call to source : | test.swift:10:15:10:15 | t2 | result |
| test.swift:30:15:30:15 | x | test.swift:25:20:25:27 | call to source : | test.swift:30:15:30:15 | x | result |
| test.swift:31:15:31:15 | y | test.swift:26:26:26:33 | call to source : | test.swift:31:15:31:15 | y | result |
| test.swift:39:15:39:29 | call to callee_source | test.swift:35:12:35:19 | call to source : | test.swift:39:15:39:29 | call to callee_source | result |
| test.swift:50:15:50:15 | t | test.swift:43:19:43:26 | call to source : | test.swift:50:15:50:15 | t | result |
| test.swift:62:15:62:15 | x | test.swift:54:11:54:18 | call to source : | test.swift:62:15:62:15 | x | result |
| test.swift:77:15:77:15 | y | test.swift:73:18:73:25 | call to source : | test.swift:77:15:77:15 | y | result |
| test.swift:98:19:98:19 | x | test.swift:81:11:81:18 | call to source : | test.swift:98:19:98:19 | x | result |
| test.swift:105:19:105:19 | x | test.swift:86:15:86:22 | call to source : | test.swift:105:19:105:19 | x | result |
| test.swift:105:19:105:19 | x | test.swift:89:15:89:22 | call to source : | test.swift:105:19:105:19 | x | result |

View File

@@ -1,3 +1,7 @@
/**
* @kind path-problem
*/
import swift
import codeql.swift.dataflow.DataFlow
import DataFlow::PathGraph
@@ -21,4 +25,4 @@ class TestConfiguration extends DataFlow::Configuration {
from DataFlow::PathNode src, DataFlow::PathNode sink, TestConfiguration test
where test.hasFlowPath(src, sink)
select src, sink
select sink, src, sink, "result"

View File

@@ -23,7 +23,54 @@
| test.swift:48:9:48:13 | WriteDef | test.swift:50:5:50:5 | Phi |
| test.swift:48:13:48:13 | 1 | test.swift:48:9:48:13 | WriteDef |
| test.swift:50:5:50:5 | Phi | test.swift:50:15:50:15 | t |
| test.swift:58:9:58:12 | WriteDef | test.swift:59:15:59:15 | x |
| test.swift:58:18:58:18 | 0 | test.swift:58:9:58:12 | WriteDef |
| test.swift:59:15:59:15 | x | test.swift:60:23:60:23 | x |
| test.swift:60:23:60:23 | x | test.swift:61:15:61:15 | x |
| test.swift:54:5:54:18 | WriteDef | test.swift:53:1:56:1 | arg[return] |
| test.swift:54:11:54:18 | call to source | test.swift:54:5:54:18 | WriteDef |
| test.swift:59:9:59:12 | WriteDef | test.swift:60:15:60:15 | x |
| test.swift:59:18:59:18 | 0 | test.swift:59:9:59:12 | WriteDef |
| test.swift:60:15:60:15 | x | test.swift:61:23:61:23 | x |
| test.swift:61:5:61:24 | WriteDef | test.swift:62:15:62:15 | x |
| test.swift:61:5:61:24 | arg | test.swift:61:5:61:24 | WriteDef |
| test.swift:61:23:61:23 | x | test.swift:61:22:61:23 | &... |
| test.swift:65:16:65:28 | WriteDef | test.swift:66:21:66:21 | arg1 |
| test.swift:65:16:65:28 | arg1 | test.swift:66:21:66:21 | arg1 |
| test.swift:65:33:65:45 | WriteDef | test.swift:67:12:67:12 | arg2 |
| test.swift:65:33:65:45 | arg2 | test.swift:67:12:67:12 | arg2 |
| test.swift:66:9:66:15 | WriteDef | test.swift:68:12:68:12 | temp |
| test.swift:66:21:66:21 | arg1 | test.swift:66:9:66:15 | WriteDef |
| test.swift:67:5:67:12 | WriteDef | test.swift:65:1:70:1 | arg1[return] |
| test.swift:67:12:67:12 | arg2 | test.swift:67:5:67:12 | WriteDef |
| test.swift:68:5:68:12 | WriteDef | test.swift:65:1:70:1 | arg2[return] |
| test.swift:68:12:68:12 | temp | test.swift:68:5:68:12 | WriteDef |
| test.swift:73:9:73:12 | WriteDef | test.swift:75:22:75:22 | x |
| test.swift:73:18:73:25 | call to source | test.swift:73:9:73:12 | WriteDef |
| test.swift:74:9:74:12 | WriteDef | test.swift:75:32:75:32 | y |
| test.swift:74:18:74:18 | 0 | test.swift:74:9:74:12 | WriteDef |
| test.swift:75:5:75:33 | WriteDef | test.swift:76:15:76:15 | x |
| test.swift:75:5:75:33 | WriteDef | test.swift:77:15:77:15 | y |
| test.swift:75:5:75:33 | arg1 | test.swift:75:5:75:33 | WriteDef |
| test.swift:75:5:75:33 | arg2 | test.swift:75:5:75:33 | WriteDef |
| test.swift:75:22:75:22 | x | test.swift:75:21:75:22 | &... |
| test.swift:75:32:75:32 | y | test.swift:75:31:75:32 | &... |
| test.swift:81:5:81:18 | WriteDef | test.swift:80:1:82:1 | arg[return] |
| test.swift:81:11:81:18 | call to source | test.swift:81:5:81:18 | WriteDef |
| test.swift:84:1:91:1 | Phi | test.swift:84:1:91:1 | arg[return] |
| test.swift:84:48:84:54 | WriteDef | test.swift:85:8:85:8 | bool |
| test.swift:84:48:84:54 | bool | test.swift:85:8:85:8 | bool |
| test.swift:86:9:86:22 | WriteDef | test.swift:84:1:91:1 | Phi |
| test.swift:86:15:86:22 | call to source | test.swift:86:9:86:22 | WriteDef |
| test.swift:89:9:89:22 | WriteDef | test.swift:84:1:91:1 | Phi |
| test.swift:89:15:89:22 | call to source | test.swift:89:9:89:22 | WriteDef |
| test.swift:93:17:93:23 | WriteDef | test.swift:104:50:104:50 | bool |
| test.swift:93:17:93:23 | bool | test.swift:104:50:104:50 | bool |
| test.swift:95:13:95:16 | WriteDef | test.swift:96:19:96:19 | x |
| test.swift:95:22:95:22 | 0 | test.swift:95:13:95:16 | WriteDef |
| test.swift:96:19:96:19 | x | test.swift:97:40:97:40 | x |
| test.swift:97:9:97:41 | WriteDef | test.swift:98:19:98:19 | x |
| test.swift:97:9:97:41 | arg | test.swift:97:9:97:41 | WriteDef |
| test.swift:97:40:97:40 | x | test.swift:97:39:97:40 | &... |
| test.swift:102:13:102:16 | WriteDef | test.swift:103:19:103:19 | x |
| test.swift:102:22:102:22 | 0 | test.swift:102:13:102:16 | WriteDef |
| test.swift:103:19:103:19 | x | test.swift:104:41:104:41 | x |
| test.swift:104:9:104:54 | WriteDef | test.swift:105:19:105:19 | x |
| test.swift:104:9:104:54 | arg | test.swift:104:9:104:54 | WriteDef |
| test.swift:104:41:104:41 | x | test.swift:104:40:104:41 | &... |

View File

@@ -52,6 +52,7 @@ func branching(b: Bool) -> Void {
func inoutSource(arg: inout Int) -> Void {
arg = source()
return
}
func inoutUser() {
@@ -60,3 +61,47 @@ func inoutUser() {
inoutSource(arg: &x)
sink(arg: x)
}
func inoutSwap(arg1: inout Int, arg2: inout Int) -> Void {
var temp: Int = arg1
arg1 = arg2
arg2 = temp
return
}
func swapUser() {
var x: Int = source()
var y: Int = 0
inoutSwap(arg1: &x, arg2: &y)
sink(arg: x)
sink(arg: y)
}
func inoutSourceWithoutReturn(arg: inout Int) {
arg = source()
}
func inoutSourceMultipleReturn(arg: inout Int, bool: Bool) {
if(bool) {
arg = source()
return
} else {
arg = source()
}
}
func inoutUser2(bool: Bool) {
do {
var x: Int = 0
sink(arg: x) // clean
inoutSourceWithoutReturn(arg: &x)
sink(arg: x) // tainted
}
do {
var x: Int = 0
sink(arg: x) // clean
inoutSourceMultipleReturn(arg: &x, bool: bool)
sink(arg: x) // tainted by two sources
}
}

View File

@@ -134,3 +134,12 @@ struct HasPropertyAndObserver {
didSet { }
}
}
extension Int {
func id() -> Int {
return self
}
}
42.id()

View File

@@ -22,13 +22,13 @@
| declarations.swift:3:7:3:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr |
| declarations.swift:3:7:3:7 | { ... } | BraceStmt | declarations.swift:3:7:3:7 | yield ... | YieldStmt |
| declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:7:3:7 | next | NamedPattern |
| declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:14:3:14 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:14:3:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:4:5:4:24 | get | AccessorDecl | declarations.swift:4:9:4:24 | { ... } | BraceStmt |
| declarations.swift:4:9:4:24 | { ... } | BraceStmt | declarations.swift:4:11:4:22 | return ... | ReturnStmt |
| declarations.swift:4:11:4:22 | return ... | ReturnStmt | declarations.swift:4:18:4:22 | ... call to + ... | BinaryExpr |
| declarations.swift:4:18:4:18 | .x | MemberRefExpr | declarations.swift:4:18:4:18 | self | DeclRefExpr |
| declarations.swift:4:18:4:22 | ... call to + ... | BinaryExpr | declarations.swift:4:20:4:20 | call to + | DotSyntaxCallExpr |
| declarations.swift:4:20:4:20 | Int.Type | TypeExpr | declarations.swift:4:20:4:20 | TBD (FixedTypeRepr) | FixedTypeRepr |
| declarations.swift:4:20:4:20 | Int.Type | TypeExpr | declarations.swift:4:20:4:20 | FixedTypeRepr | FixedTypeRepr |
| declarations.swift:4:20:4:20 | call to + | DotSyntaxCallExpr | declarations.swift:4:20:4:20 | + | DeclRefExpr |
| declarations.swift:5:5:5:38 | set | AccessorDecl | declarations.swift:5:9:5:9 | newValue | ParamDecl |
| declarations.swift:5:5:5:38 | set | AccessorDecl | declarations.swift:5:19:5:38 | { ... } | BraceStmt |
@@ -37,7 +37,7 @@
| declarations.swift:5:21:5:36 | ... = ... | AssignExpr | declarations.swift:5:21:5:21 | .x | MemberRefExpr |
| declarations.swift:5:21:5:36 | ... = ... | AssignExpr | declarations.swift:5:25:5:36 | ... call to - ... | BinaryExpr |
| declarations.swift:5:25:5:36 | ... call to - ... | BinaryExpr | declarations.swift:5:34:5:34 | call to - | DotSyntaxCallExpr |
| declarations.swift:5:34:5:34 | Int.Type | TypeExpr | declarations.swift:5:34:5:34 | TBD (FixedTypeRepr) | FixedTypeRepr |
| declarations.swift:5:34:5:34 | Int.Type | TypeExpr | declarations.swift:5:34:5:34 | FixedTypeRepr | FixedTypeRepr |
| declarations.swift:5:34:5:34 | call to - | DotSyntaxCallExpr | declarations.swift:5:34:5:34 | - | DeclRefExpr |
| declarations.swift:9:7:9:7 | deinit | DestructorDecl | declarations.swift:9:7:9:7 | { ... } | BraceStmt |
| declarations.swift:9:7:9:7 | init | ConstructorDecl | declarations.swift:9:7:9:7 | { ... } | BraceStmt |
@@ -56,7 +56,7 @@
| declarations.swift:9:17:9:17 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| declarations.swift:9:17:9:17 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:17:9:17 | x | NamedPattern |
| declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:21:9:21 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:21:9:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:12:5:12:18 | case ... | EnumCaseDecl | declarations.swift:12:10:12:10 | value1 | EnumElementDecl |
| declarations.swift:12:5:12:18 | case ... | EnumCaseDecl | declarations.swift:12:18:12:18 | value2 | EnumElementDecl |
| declarations.swift:13:5:13:26 | case ... | EnumCaseDecl | declarations.swift:13:10:13:10 | value3 | EnumElementDecl |
@@ -75,12 +75,12 @@
| declarations.swift:23:9:23:9 | mustBeSettable | ConcreteVarDecl | declarations.swift:23:31:23:31 | get | AccessorDecl |
| declarations.swift:23:9:23:9 | mustBeSettable | ConcreteVarDecl | declarations.swift:23:35:23:35 | set | AccessorDecl |
| declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:9:23:9 | mustBeSettable | NamedPattern |
| declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:25:23:25 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:25:23:25 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:23:35:23:35 | set | AccessorDecl | declarations.swift:23:35:23:35 | newValue | ParamDecl |
| declarations.swift:24:5:24:44 | var ... = ... | PatternBindingDecl | declarations.swift:24:9:24:34 | ... as ... | TypedPattern |
| declarations.swift:24:9:24:9 | doesNotNeedToBeSettable | ConcreteVarDecl | declarations.swift:24:40:24:40 | get | AccessorDecl |
| declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:9:24:9 | doesNotNeedToBeSettable | NamedPattern |
| declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:34:24:34 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:34:24:34 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:28:1:28:37 | a_function | ConcreteFuncDecl | declarations.swift:28:17:28:31 | a_parameter | ParamDecl |
| declarations.swift:28:1:28:37 | a_function | ConcreteFuncDecl | declarations.swift:28:36:28:37 | { ... } | BraceStmt |
| declarations.swift:30:1:30:18 | var ... = ... | PatternBindingDecl | declarations.swift:30:5:30:5 | a_variable | NamedPattern |
@@ -93,7 +93,7 @@
| declarations.swift:31:5:31:5 | a_property | ConcreteVarDecl | declarations.swift:32:3:34:3 | get | AccessorDecl |
| declarations.swift:31:5:31:5 | a_property | ConcreteVarDecl | declarations.swift:35:3:35:18 | set | AccessorDecl |
| declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:5:31:5 | a_property | NamedPattern |
| declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:18:31:18 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:18:31:18 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:32:3:34:3 | get | AccessorDecl | declarations.swift:32:7:34:3 | { ... } | BraceStmt |
| declarations.swift:32:7:34:3 | { ... } | BraceStmt | declarations.swift:33:5:33:12 | return ... | ReturnStmt |
| declarations.swift:33:5:33:12 | return ... | ReturnStmt | declarations.swift:33:12:33:12 | here | StringLiteralExpr |
@@ -103,9 +103,7 @@
| declarations.swift:38:1:38:33 | { ... } | BraceStmt | declarations.swift:38:1:38:33 | call to print | CallExpr |
| declarations.swift:38:1:38:33 | { ... } | TopLevelCodeDecl | declarations.swift:38:1:38:33 | { ... } | BraceStmt |
| declarations.swift:38:7:38:7 | (Any) ... | ErasureExpr | declarations.swift:38:7:38:7 | some top level statement | StringLiteralExpr |
| declarations.swift:38:7:38:7 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | declarations.swift:38:7:38:7 | some top level statement | StringLiteralExpr |
| declarations.swift:38:7:38:7 | [...] | ArrayExpr | declarations.swift:38:7:38:7 | (Any) ... | ErasureExpr |
| declarations.swift:38:7:38:7 | [...] | ArrayExpr | declarations.swift:38:7:38:7 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| declarations.swift:38:7:38:7 | [...] | VarargExpansionExpr | declarations.swift:38:7:38:7 | [...] | ArrayExpr |
| declarations.swift:41:3:41:14 | var ... = ... | PatternBindingDecl | declarations.swift:41:7:41:14 | ... as ... | TypedPattern |
| declarations.swift:41:7:41:7 | (unnamed function decl) | AccessorDecl | declarations.swift:41:7:41:7 | { ... } | BraceStmt |
@@ -120,7 +118,7 @@
| declarations.swift:41:7:41:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| declarations.swift:41:7:41:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:7:41:7 | field | NamedPattern |
| declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:14:41:14 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:14:41:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:42:3:44:3 | init | ConstructorDecl | declarations.swift:42:10:44:3 | { ... } | BraceStmt |
| declarations.swift:42:10:44:3 | { ... } | BraceStmt | declarations.swift:43:5:43:13 | ... = ... | AssignExpr |
| declarations.swift:42:10:44:3 | { ... } | BraceStmt | declarations.swift:44:3:44:3 | return | ReturnStmt |
@@ -141,7 +139,7 @@
| declarations.swift:69:3:73:3 | var ... = ... | PatternBindingDecl | declarations.swift:69:7:69:21 | ... as ... | TypedPattern |
| declarations.swift:69:7:69:7 | wrappedValue | ConcreteVarDecl | declarations.swift:70:5:72:5 | get | AccessorDecl |
| declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:7:69:7 | wrappedValue | NamedPattern |
| declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:21:69:21 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:21:69:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:70:5:72:5 | get | AccessorDecl | declarations.swift:70:9:72:5 | { ... } | BraceStmt |
| declarations.swift:70:9:72:5 | { ... } | BraceStmt | declarations.swift:71:7:71:14 | return ... | ReturnStmt |
| declarations.swift:71:7:71:14 | return ... | ReturnStmt | declarations.swift:71:14:71:14 | 0 | IntegerLiteralExpr |
@@ -149,7 +147,7 @@
| declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:77:16:77:23 | var ... = ... | PatternBindingDecl |
| declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:77:20:77:20 | x | ConcreteVarDecl |
| declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:78:3:78:10 | return ... | ReturnStmt |
| declarations.swift:77:4:77:4 | ZeroWrapper.Type | TypeExpr | declarations.swift:77:4:77:4 | TBD (FixedTypeRepr) | FixedTypeRepr |
| declarations.swift:77:4:77:4 | ZeroWrapper.Type | TypeExpr | declarations.swift:77:4:77:4 | FixedTypeRepr | FixedTypeRepr |
| declarations.swift:77:4:77:4 | call to ... | CallExpr | declarations.swift:77:4:77:4 | call to ... | ConstructorRefCallExpr |
| declarations.swift:77:4:77:4 | call to ... | ConstructorRefCallExpr | declarations.swift:77:4:77:4 | init | DeclRefExpr |
| declarations.swift:77:16:77:23 | var ... = ... | PatternBindingDecl | declarations.swift:77:20:77:23 | ... as ... | TypedPattern |
@@ -158,7 +156,7 @@
| declarations.swift:77:20:77:20 | x | ConcreteVarDecl | declarations.swift:77:20:77:20 | get | AccessorDecl |
| declarations.swift:77:20:77:20 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:20:77:20 | x | NamedPattern |
| declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:23:77:23 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:23:77:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:78:3:78:10 | return ... | ReturnStmt | declarations.swift:78:10:78:10 | x | DeclRefExpr |
| declarations.swift:81:8:81:8 | init | ConstructorDecl | declarations.swift:81:8:81:8 | hasBoth | ParamDecl |
| declarations.swift:81:8:81:8 | init | ConstructorDecl | declarations.swift:81:8:81:8 | hasDidSet1 | ParamDecl |
@@ -174,7 +172,7 @@
| declarations.swift:82:7:82:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr |
| declarations.swift:82:7:82:7 | { ... } | BraceStmt | declarations.swift:82:7:82:7 | yield ... | YieldStmt |
| declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:7:82:7 | settableField | NamedPattern |
| declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:22:82:22 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:22:82:22 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:83:5:83:11 | set | AccessorDecl | declarations.swift:83:5:83:5 | newValue | ParamDecl |
| declarations.swift:83:5:83:11 | set | AccessorDecl | declarations.swift:83:9:83:11 | { ... } | BraceStmt |
| declarations.swift:84:5:86:5 | get | AccessorDecl | declarations.swift:84:9:86:5 | { ... } | BraceStmt |
@@ -183,14 +181,14 @@
| declarations.swift:91:3:93:3 | var ... = ... | PatternBindingDecl | declarations.swift:91:7:91:23 | ... as ... | TypedPattern |
| declarations.swift:91:7:91:7 | readOnlyField1 | ConcreteVarDecl | declarations.swift:91:27:93:3 | get | AccessorDecl |
| declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:7:91:7 | readOnlyField1 | NamedPattern |
| declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:23:91:23 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:23:91:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:91:27:93:3 | get | AccessorDecl | declarations.swift:91:27:93:3 | { ... } | BraceStmt |
| declarations.swift:91:27:93:3 | { ... } | BraceStmt | declarations.swift:92:5:92:12 | return ... | ReturnStmt |
| declarations.swift:92:5:92:12 | return ... | ReturnStmt | declarations.swift:92:12:92:12 | 0 | IntegerLiteralExpr |
| declarations.swift:96:3:100:3 | var ... = ... | PatternBindingDecl | declarations.swift:96:7:96:23 | ... as ... | TypedPattern |
| declarations.swift:96:7:96:7 | readOnlyField2 | ConcreteVarDecl | declarations.swift:97:5:99:5 | get | AccessorDecl |
| declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:7:96:7 | readOnlyField2 | NamedPattern |
| declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:23:96:23 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:23:96:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:97:5:99:5 | get | AccessorDecl | declarations.swift:97:9:99:5 | { ... } | BraceStmt |
| declarations.swift:97:9:99:5 | { ... } | BraceStmt | declarations.swift:98:7:98:14 | return ... | ReturnStmt |
| declarations.swift:98:7:98:14 | return ... | ReturnStmt | declarations.swift:98:14:98:14 | 0 | IntegerLiteralExpr |
@@ -207,7 +205,7 @@
| declarations.swift:102:7:102:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| declarations.swift:102:7:102:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:7:102:7 | normalField | NamedPattern |
| declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:21:102:21 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:21:102:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:104:3:104:3 | (unnamed function decl) | AccessorDecl | declarations.swift:104:3:104:3 | { ... } | BraceStmt |
| declarations.swift:104:3:104:3 | (unnamed function decl) | AccessorDecl | file://:0:0:0:0 | x | ParamDecl |
| declarations.swift:104:3:104:3 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr |
@@ -246,7 +244,7 @@
| declarations.swift:115:7:115:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr |
| declarations.swift:115:7:115:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:7:115:7 | hasWillSet1 | NamedPattern |
| declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:21:115:21 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:21:115:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:116:5:116:25 | willSet | AccessorDecl | declarations.swift:116:13:116:13 | newValue | ParamDecl |
| declarations.swift:116:5:116:25 | willSet | AccessorDecl | declarations.swift:116:23:116:25 | { ... } | BraceStmt |
| declarations.swift:119:3:121:3 | var ... = ... | PatternBindingDecl | declarations.swift:119:7:119:21 | ... as ... | TypedPattern |
@@ -264,7 +262,7 @@
| declarations.swift:119:7:119:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr |
| declarations.swift:119:7:119:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:7:119:7 | hasWillSet2 | NamedPattern |
| declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:21:119:21 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:21:119:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:120:5:120:15 | willSet | AccessorDecl | declarations.swift:120:5:120:5 | newValue | ParamDecl |
| declarations.swift:120:5:120:15 | willSet | AccessorDecl | declarations.swift:120:13:120:15 | { ... } | BraceStmt |
| declarations.swift:123:3:125:3 | var ... = ... | PatternBindingDecl | declarations.swift:123:7:123:20 | ... as ... | TypedPattern |
@@ -284,7 +282,7 @@
| declarations.swift:123:7:123:7 | { ... } | BraceStmt | file://:0:0:0:0 | tmp | ConcreteVarDecl |
| declarations.swift:123:7:123:7 | { ... } | BraceStmt | file://:0:0:0:0 | var ... = ... | PatternBindingDecl |
| declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:7:123:7 | hasDidSet1 | NamedPattern |
| declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:20:123:20 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:20:123:20 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:124:5:124:24 | didSet | AccessorDecl | declarations.swift:124:12:124:12 | oldValue | ParamDecl |
| declarations.swift:124:5:124:24 | didSet | AccessorDecl | declarations.swift:124:22:124:24 | { ... } | BraceStmt |
| declarations.swift:127:3:129:3 | var ... = ... | PatternBindingDecl | declarations.swift:127:7:127:20 | ... as ... | TypedPattern |
@@ -303,7 +301,7 @@
| declarations.swift:127:7:127:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr |
| declarations.swift:127:7:127:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:7:127:7 | hasDidSet2 | NamedPattern |
| declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:20:127:20 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:20:127:20 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:128:5:128:14 | didSet | AccessorDecl | declarations.swift:128:12:128:14 | { ... } | BraceStmt |
| declarations.swift:131:3:135:3 | var ... = ... | PatternBindingDecl | declarations.swift:131:7:131:17 | ... as ... | TypedPattern |
| declarations.swift:131:7:131:7 | (unnamed function decl) | AccessorDecl | declarations.swift:131:7:131:7 | { ... } | BraceStmt |
@@ -322,10 +320,17 @@
| declarations.swift:131:7:131:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr |
| declarations.swift:131:7:131:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:7:131:7 | hasBoth | NamedPattern |
| declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:17:131:17 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:17:131:17 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| declarations.swift:132:5:132:15 | willSet | AccessorDecl | declarations.swift:132:5:132:5 | newValue | ParamDecl |
| declarations.swift:132:5:132:15 | willSet | AccessorDecl | declarations.swift:132:13:132:15 | { ... } | BraceStmt |
| declarations.swift:134:5:134:14 | didSet | AccessorDecl | declarations.swift:134:12:134:14 | { ... } | BraceStmt |
| declarations.swift:139:3:141:3 | id | ConcreteFuncDecl | declarations.swift:139:20:141:3 | { ... } | BraceStmt |
| declarations.swift:139:20:141:3 | { ... } | BraceStmt | declarations.swift:140:5:140:12 | return ... | ReturnStmt |
| declarations.swift:140:5:140:12 | return ... | ReturnStmt | declarations.swift:140:12:140:12 | self | DeclRefExpr |
| declarations.swift:144:1:144:4 | call to id | DotSyntaxCallExpr | declarations.swift:144:4:144:4 | id | DeclRefExpr |
| declarations.swift:144:1:144:7 | call to ... | CallExpr | declarations.swift:144:1:144:4 | call to id | DotSyntaxCallExpr |
| declarations.swift:144:1:144:7 | { ... } | BraceStmt | declarations.swift:144:1:144:7 | call to ... | CallExpr |
| declarations.swift:144:1:144:7 | { ... } | TopLevelCodeDecl | declarations.swift:144:1:144:7 | { ... } | BraceStmt |
| expressions.swift:1:1:1:9 | var ... = ... | PatternBindingDecl | expressions.swift:1:5:1:5 | a | NamedPattern |
| expressions.swift:1:1:1:9 | var ... = ... | PatternBindingDecl | expressions.swift:1:9:1:9 | 15 | IntegerLiteralExpr |
| expressions.swift:1:1:1:9 | { ... } | BraceStmt | expressions.swift:1:1:1:9 | var ... = ... | PatternBindingDecl |
@@ -378,7 +383,6 @@
| expressions.swift:8:1:8:15 | { ... } | TopLevelCodeDecl | expressions.swift:8:1:8:15 | { ... } | BraceStmt |
| expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:5:8:5 | n | NamedPattern |
| expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:8:8:11 | ...? | OptionalTypeRepr |
| expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:8:8:11 | TBD (OptionalTypeRepr) | OptionalTypeRepr |
| expressions.swift:11:3:11:8 | case ... | EnumCaseDecl | expressions.swift:11:8:11:8 | failed | EnumElementDecl |
| expressions.swift:14:1:18:1 | failure | ConcreteFuncDecl | expressions.swift:14:14:14:19 | x | ParamDecl |
| expressions.swift:14:1:18:1 | failure | ConcreteFuncDecl | expressions.swift:14:31:18:1 | { ... } | BraceStmt |
@@ -386,14 +390,12 @@
| expressions.swift:15:3:17:3 | guard ... else { ... } | GuardStmt | expressions.swift:15:9:15:14 | StmtCondition | StmtCondition |
| expressions.swift:15:3:17:3 | guard ... else { ... } | GuardStmt | expressions.swift:15:21:17:3 | { ... } | BraceStmt |
| expressions.swift:15:9:15:14 | ... call to != ... | BinaryExpr | expressions.swift:15:11:15:11 | call to != | DotSyntaxCallExpr |
| expressions.swift:15:11:15:11 | Int.Type | TypeExpr | expressions.swift:15:11:15:11 | TBD (FixedTypeRepr) | FixedTypeRepr |
| expressions.swift:15:11:15:11 | Int.Type | TypeExpr | expressions.swift:15:11:15:11 | FixedTypeRepr | FixedTypeRepr |
| expressions.swift:15:11:15:11 | call to != | DotSyntaxCallExpr | expressions.swift:15:11:15:11 | != | DeclRefExpr |
| expressions.swift:15:21:17:3 | { ... } | BraceStmt | expressions.swift:16:5:16:19 | throw ... | ThrowStmt |
| expressions.swift:16:5:16:19 | throw ... | ThrowStmt | expressions.swift:16:11:16:19 | (Error) ... | ErasureExpr |
| expressions.swift:16:5:16:19 | throw ... | ThrowStmt | expressions.swift:16:11:16:19 | (TBD (ExistentialType)) ... | ErasureExpr |
| expressions.swift:16:11:16:11 | AnError.Type | TypeExpr | expressions.swift:16:11:16:11 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:16:11:16:11 | AnError.Type | TypeExpr | expressions.swift:16:11:16:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:16:11:16:19 | (Error) ... | ErasureExpr | expressions.swift:16:11:16:19 | call to ... | DotSyntaxCallExpr |
| expressions.swift:16:11:16:19 | (TBD (ExistentialType)) ... | ErasureExpr | expressions.swift:16:11:16:19 | call to ... | DotSyntaxCallExpr |
| expressions.swift:16:11:16:19 | call to ... | DotSyntaxCallExpr | expressions.swift:16:19:16:19 | failed | DeclRefExpr |
| expressions.swift:20:1:20:16 | try! ... | ForceTryExpr | expressions.swift:20:6:20:16 | call to failure | CallExpr |
| expressions.swift:20:1:20:16 | { ... } | BraceStmt | expressions.swift:20:1:20:16 | try! ... | ForceTryExpr |
@@ -411,7 +413,7 @@
| expressions.swift:27:1:27:19 | var ... = ... | PatternBindingDecl | expressions.swift:27:13:27:19 | call to ... | CallExpr |
| expressions.swift:27:1:27:19 | { ... } | BraceStmt | expressions.swift:27:1:27:19 | var ... = ... | PatternBindingDecl |
| expressions.swift:27:1:27:19 | { ... } | TopLevelCodeDecl | expressions.swift:27:1:27:19 | { ... } | BraceStmt |
| expressions.swift:27:13:27:13 | Klass.Type | TypeExpr | expressions.swift:27:13:27:13 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:27:13:27:13 | Klass.Type | TypeExpr | expressions.swift:27:13:27:13 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:27:13:27:13 | call to ... | ConstructorRefCallExpr | expressions.swift:27:13:27:13 | init | DeclRefExpr |
| expressions.swift:27:13:27:19 | call to ... | CallExpr | expressions.swift:27:13:27:13 | call to ... | ConstructorRefCallExpr |
| expressions.swift:29:1:29:19 | var ... = ... | PatternBindingDecl | expressions.swift:29:5:29:5 | d | NamedPattern |
@@ -449,10 +451,8 @@
| expressions.swift:35:1:35:13 | { ... } | BraceStmt | expressions.swift:35:1:35:13 | call to print | CallExpr |
| expressions.swift:35:1:35:13 | { ... } | TopLevelCodeDecl | expressions.swift:35:1:35:13 | { ... } | BraceStmt |
| expressions.swift:35:7:35:12 | (Any) ... | ErasureExpr | expressions.swift:35:7:35:12 | ...[...] | SubscriptExpr |
| expressions.swift:35:7:35:12 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | expressions.swift:35:7:35:12 | ...[...] | SubscriptExpr |
| expressions.swift:35:7:35:12 | ...[...] | SubscriptExpr | expressions.swift:35:7:35:7 | d | DeclRefExpr |
| expressions.swift:35:7:35:12 | [...] | ArrayExpr | expressions.swift:35:7:35:12 | (Any) ... | ErasureExpr |
| expressions.swift:35:7:35:12 | [...] | ArrayExpr | expressions.swift:35:7:35:12 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| expressions.swift:35:7:35:12 | [...] | VarargExpansionExpr | expressions.swift:35:7:35:12 | [...] | ArrayExpr |
| expressions.swift:37:1:39:1 | closured | ConcreteFuncDecl | expressions.swift:37:15:37:38 | closure | ParamDecl |
| expressions.swift:37:1:39:1 | closured | ConcreteFuncDecl | expressions.swift:37:43:39:1 | { ... } | BraceStmt |
@@ -465,7 +465,7 @@
| expressions.swift:41:10:43:1 | { ... } | ClosureExpr | expressions.swift:41:10:43:1 | { ... } | BraceStmt |
| expressions.swift:42:5:42:16 | return ... | ReturnStmt | expressions.swift:42:12:42:16 | ... call to + ... | BinaryExpr |
| expressions.swift:42:12:42:16 | ... call to + ... | BinaryExpr | expressions.swift:42:14:42:14 | call to + | DotSyntaxCallExpr |
| expressions.swift:42:14:42:14 | Int.Type | TypeExpr | expressions.swift:42:14:42:14 | TBD (FixedTypeRepr) | FixedTypeRepr |
| expressions.swift:42:14:42:14 | Int.Type | TypeExpr | expressions.swift:42:14:42:14 | FixedTypeRepr | FixedTypeRepr |
| expressions.swift:42:14:42:14 | call to + | DotSyntaxCallExpr | expressions.swift:42:14:42:14 | + | DeclRefExpr |
| expressions.swift:44:1:46:1 | call to closured | CallExpr | expressions.swift:44:1:44:1 | closured | DeclRefExpr |
| expressions.swift:44:1:46:1 | { ... } | BraceStmt | expressions.swift:44:1:46:1 | call to closured | CallExpr |
@@ -474,7 +474,7 @@
| expressions.swift:44:10:46:1 | { ... } | ClosureExpr | expressions.swift:44:10:46:1 | { ... } | BraceStmt |
| expressions.swift:45:5:45:16 | return ... | ReturnStmt | expressions.swift:45:12:45:16 | ... call to + ... | BinaryExpr |
| expressions.swift:45:12:45:16 | ... call to + ... | BinaryExpr | expressions.swift:45:14:45:14 | call to + | DotSyntaxCallExpr |
| expressions.swift:45:14:45:14 | Int.Type | TypeExpr | expressions.swift:45:14:45:14 | TBD (FixedTypeRepr) | FixedTypeRepr |
| expressions.swift:45:14:45:14 | Int.Type | TypeExpr | expressions.swift:45:14:45:14 | FixedTypeRepr | FixedTypeRepr |
| expressions.swift:45:14:45:14 | call to + | DotSyntaxCallExpr | expressions.swift:45:14:45:14 | + | DeclRefExpr |
| expressions.swift:47:1:47:27 | call to closured | CallExpr | expressions.swift:47:1:47:1 | closured | DeclRefExpr |
| expressions.swift:47:1:47:27 | { ... } | BraceStmt | expressions.swift:47:1:47:27 | call to closured | CallExpr |
@@ -483,7 +483,7 @@
| expressions.swift:47:10:47:27 | { ... } | ClosureExpr | expressions.swift:47:10:47:27 | { ... } | BraceStmt |
| expressions.swift:47:12:47:24 | return ... | ReturnStmt | expressions.swift:47:19:47:24 | ... call to + ... | BinaryExpr |
| expressions.swift:47:19:47:24 | ... call to + ... | BinaryExpr | expressions.swift:47:22:47:22 | call to + | DotSyntaxCallExpr |
| expressions.swift:47:22:47:22 | Int.Type | TypeExpr | expressions.swift:47:22:47:22 | TBD (FixedTypeRepr) | FixedTypeRepr |
| expressions.swift:47:22:47:22 | Int.Type | TypeExpr | expressions.swift:47:22:47:22 | FixedTypeRepr | FixedTypeRepr |
| expressions.swift:47:22:47:22 | call to + | DotSyntaxCallExpr | expressions.swift:47:22:47:22 | + | DeclRefExpr |
| expressions.swift:48:1:48:20 | call to closured | CallExpr | expressions.swift:48:1:48:1 | closured | DeclRefExpr |
| expressions.swift:48:1:48:20 | { ... } | BraceStmt | expressions.swift:48:1:48:20 | call to closured | CallExpr |
@@ -492,7 +492,7 @@
| expressions.swift:48:10:48:20 | { ... } | ClosureExpr | expressions.swift:48:10:48:20 | { ... } | BraceStmt |
| expressions.swift:48:12:48:17 | ... call to + ... | BinaryExpr | expressions.swift:48:15:48:15 | call to + | DotSyntaxCallExpr |
| expressions.swift:48:12:48:17 | return ... | ReturnStmt | expressions.swift:48:12:48:17 | ... call to + ... | BinaryExpr |
| expressions.swift:48:15:48:15 | Int.Type | TypeExpr | expressions.swift:48:15:48:15 | TBD (FixedTypeRepr) | FixedTypeRepr |
| expressions.swift:48:15:48:15 | Int.Type | TypeExpr | expressions.swift:48:15:48:15 | FixedTypeRepr | FixedTypeRepr |
| expressions.swift:48:15:48:15 | call to + | DotSyntaxCallExpr | expressions.swift:48:15:48:15 | + | DeclRefExpr |
| expressions.swift:50:8:50:8 | init | ConstructorDecl | expressions.swift:50:8:50:8 | x | ParamDecl |
| expressions.swift:51:3:51:10 | var ... = ... | PatternBindingDecl | expressions.swift:51:7:51:10 | ... as ... | TypedPattern |
@@ -500,12 +500,12 @@
| expressions.swift:51:7:51:7 | x | ConcreteVarDecl | expressions.swift:51:7:51:7 | get | AccessorDecl |
| expressions.swift:51:7:51:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:7:51:7 | x | NamedPattern |
| expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:10:51:10 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:10:51:10 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:54:1:54:8 | ... = ... | AssignExpr | expressions.swift:54:1:54:1 | _ | DiscardAssignmentExpr |
| expressions.swift:54:1:54:8 | ... = ... | AssignExpr | expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr |
| expressions.swift:54:1:54:8 | { ... } | BraceStmt | expressions.swift:54:1:54:8 | ... = ... | AssignExpr |
| expressions.swift:54:1:54:8 | { ... } | TopLevelCodeDecl | expressions.swift:54:1:54:8 | { ... } | BraceStmt |
| expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | expressions.swift:54:6:54:8 | TBD (UnresolvedDotExpr) | UnresolvedDotExpr |
| expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | expressions.swift:54:6:54:8 | UnresolvedDotExpr | UnresolvedDotExpr |
| expressions.swift:56:1:57:1 | unsafeFunction | ConcreteFuncDecl | expressions.swift:56:21:56:47 | pointer | ParamDecl |
| expressions.swift:56:1:57:1 | unsafeFunction | ConcreteFuncDecl | expressions.swift:56:50:57:1 | { ... } | BraceStmt |
| expressions.swift:58:1:58:16 | var ... = ... | PatternBindingDecl | expressions.swift:58:5:58:5 | myNumber | NamedPattern |
@@ -534,9 +534,8 @@
| expressions.swift:64:5:66:5 | if ... then { ... } | IfStmt | expressions.swift:64:8:64:12 | StmtCondition | StmtCondition |
| expressions.swift:64:5:66:5 | if ... then { ... } | IfStmt | expressions.swift:64:14:66:5 | { ... } | BraceStmt |
| expressions.swift:64:8:64:12 | ... call to < ... | BinaryExpr | expressions.swift:64:10:64:10 | call to < | DotSyntaxCallExpr |
| expressions.swift:64:10:64:10 | Int.Type | TypeExpr | expressions.swift:64:10:64:10 | TBD (FixedTypeRepr) | FixedTypeRepr |
| expressions.swift:64:10:64:10 | Int.Type | TypeExpr | expressions.swift:64:10:64:10 | FixedTypeRepr | FixedTypeRepr |
| expressions.swift:64:10:64:10 | call to < | DotSyntaxCallExpr | expressions.swift:64:10:64:10 | < | DeclRefExpr |
| expressions.swift:64:14:66:5 | { ... } | BraceStmt | expressions.swift:65:7:65:14 | TBD (FailStmt) | FailStmt |
| expressions.swift:64:14:66:5 | { ... } | BraceStmt | expressions.swift:65:7:65:14 | fail | FailStmt |
| expressions.swift:70:7:70:7 | deinit | DestructorDecl | expressions.swift:70:7:70:7 | { ... } | BraceStmt |
| expressions.swift:71:3:71:11 | var ... = ... | PatternBindingDecl | expressions.swift:71:7:71:11 | ... as ... | TypedPattern |
@@ -544,7 +543,7 @@
| expressions.swift:71:7:71:7 | xx | ConcreteVarDecl | expressions.swift:71:7:71:7 | get | AccessorDecl |
| expressions.swift:71:7:71:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:7:71:7 | xx | NamedPattern |
| expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:11:71:11 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:11:71:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:72:3:74:3 | init | ConstructorDecl | expressions.swift:72:8:72:11 | x | ParamDecl |
| expressions.swift:72:3:74:3 | init | ConstructorDecl | expressions.swift:72:16:74:3 | { ... } | BraceStmt |
| expressions.swift:72:16:74:3 | { ... } | BraceStmt | expressions.swift:73:5:73:10 | ... = ... | AssignExpr |
@@ -559,7 +558,6 @@
| expressions.swift:78:3:80:3 | init | ConstructorDecl | expressions.swift:78:10:80:3 | { ... } | BraceStmt |
| expressions.swift:78:10:80:3 | { ... } | BraceStmt | expressions.swift:79:5:79:21 | self = ... | RebindSelfInConstructorExpr |
| expressions.swift:78:10:80:3 | { ... } | BraceStmt | expressions.swift:80:3:80:3 | return | ReturnStmt |
| expressions.swift:79:5:79:11 | call to ... | DotSyntaxCallExpr | expressions.swift:79:11:79:11 | TBD (OtherConstructorDeclRefExpr) | OtherConstructorDeclRefExpr |
| expressions.swift:79:5:79:11 | call to ... | DotSyntaxCallExpr | expressions.swift:79:11:79:11 | call to ... | OtherConstructorDeclRefExpr |
| expressions.swift:79:5:79:21 | call to ... | CallExpr | expressions.swift:79:5:79:11 | call to ... | DotSyntaxCallExpr |
| expressions.swift:79:5:79:21 | self = ... | RebindSelfInConstructorExpr | expressions.swift:78:3:78:3 | self | ParamDecl |
@@ -568,7 +566,7 @@
| expressions.swift:83:1:83:23 | var ... = ... | PatternBindingDecl | expressions.swift:83:15:83:23 | call to ... | CallExpr |
| expressions.swift:83:1:83:23 | { ... } | BraceStmt | expressions.swift:83:1:83:23 | var ... = ... | PatternBindingDecl |
| expressions.swift:83:1:83:23 | { ... } | TopLevelCodeDecl | expressions.swift:83:1:83:23 | { ... } | BraceStmt |
| expressions.swift:83:15:83:15 | Derived.Type | TypeExpr | expressions.swift:83:15:83:15 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:83:15:83:15 | Derived.Type | TypeExpr | expressions.swift:83:15:83:15 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:83:15:83:15 | call to ... | ConstructorRefCallExpr | expressions.swift:83:15:83:15 | init | DeclRefExpr |
| expressions.swift:83:15:83:23 | call to ... | CallExpr | expressions.swift:83:15:83:15 | call to ... | ConstructorRefCallExpr |
| expressions.swift:84:1:84:13 | ... = ... | AssignExpr | expressions.swift:84:1:84:1 | _ | DiscardAssignmentExpr |
@@ -583,7 +581,6 @@
| expressions.swift:86:1:86:13 | { ... } | TopLevelCodeDecl | expressions.swift:86:1:86:13 | { ... } | BraceStmt |
| expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:5:86:5 | opt | NamedPattern |
| expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:10:86:13 | ...? | OptionalTypeRepr |
| expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:10:86:13 | TBD (OptionalTypeRepr) | OptionalTypeRepr |
| expressions.swift:87:1:87:4 | ...! | ForceValueExpr | expressions.swift:87:1:87:1 | opt | DeclRefExpr |
| expressions.swift:87:1:87:4 | { ... } | BraceStmt | expressions.swift:87:1:87:4 | ...! | ForceValueExpr |
| expressions.swift:87:1:87:4 | { ... } | TopLevelCodeDecl | expressions.swift:87:1:87:4 | { ... } | BraceStmt |
@@ -598,16 +595,15 @@
| expressions.swift:92:1:92:55 | var ... = ... | PatternBindingDecl | expressions.swift:92:14:92:55 | call to ... | CallExpr |
| expressions.swift:92:1:92:55 | { ... } | BraceStmt | expressions.swift:92:1:92:55 | var ... = ... | PatternBindingDecl |
| expressions.swift:92:1:92:55 | { ... } | TopLevelCodeDecl | expressions.swift:92:1:92:55 | { ... } | BraceStmt |
| expressions.swift:92:14:92:14 | Unmanaged<ToPtr>.Type | TypeExpr | expressions.swift:92:14:92:14 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:92:14:92:14 | Unmanaged<ToPtr>.Type | TypeExpr | expressions.swift:92:14:92:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:92:14:92:24 | call to passRetained | DotSyntaxCallExpr | expressions.swift:92:24:92:24 | passRetained | DeclRefExpr |
| expressions.swift:92:14:92:44 | call to ... | CallExpr | expressions.swift:92:14:92:24 | call to passRetained | DotSyntaxCallExpr |
| expressions.swift:92:14:92:46 | call to toOpaque | DotSyntaxCallExpr | expressions.swift:92:46:92:46 | toOpaque | DeclRefExpr |
| expressions.swift:92:14:92:55 | call to ... | CallExpr | expressions.swift:92:14:92:46 | call to toOpaque | DotSyntaxCallExpr |
| expressions.swift:92:37:92:37 | ToPtr.Type | TypeExpr | expressions.swift:92:37:92:37 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:92:37:92:37 | ToPtr.Type | TypeExpr | expressions.swift:92:37:92:37 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:92:37:92:37 | call to ... | ConstructorRefCallExpr | expressions.swift:92:37:92:37 | init | DeclRefExpr |
| expressions.swift:92:37:92:43 | call to ... | CallExpr | expressions.swift:92:37:92:37 | call to ... | ConstructorRefCallExpr |
| expressions.swift:93:1:93:16 | Unmanaged<ToPtr>.Type | TypeExpr | expressions.swift:93:1:93:16 | ...<...> | GenericIdentTypeRepr |
| expressions.swift:93:1:93:16 | Unmanaged<ToPtr>.Type | TypeExpr | expressions.swift:93:1:93:16 | TBD (GenericIdentTypeRepr) | GenericIdentTypeRepr |
| expressions.swift:93:1:93:18 | call to fromOpaque | DotSyntaxCallExpr | expressions.swift:93:18:93:18 | fromOpaque | DeclRefExpr |
| expressions.swift:93:1:93:35 | call to ... | CallExpr | expressions.swift:93:1:93:18 | call to fromOpaque | DotSyntaxCallExpr |
| expressions.swift:93:1:93:35 | { ... } | BraceStmt | expressions.swift:93:1:93:35 | call to ... | CallExpr |
@@ -622,7 +618,7 @@
| expressions.swift:96:7:96:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr |
| expressions.swift:96:7:96:7 | { ... } | BraceStmt | expressions.swift:96:7:96:7 | yield ... | YieldStmt |
| expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:7:96:7 | settableField | NamedPattern |
| expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:22:96:22 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:22:96:22 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:97:5:97:11 | set | AccessorDecl | expressions.swift:97:5:97:5 | newValue | ParamDecl |
| expressions.swift:97:5:97:11 | set | AccessorDecl | expressions.swift:97:9:97:11 | { ... } | BraceStmt |
| expressions.swift:98:5:100:5 | get | AccessorDecl | expressions.swift:98:9:100:5 | { ... } | BraceStmt |
@@ -631,14 +627,14 @@
| expressions.swift:105:3:107:3 | var ... = ... | PatternBindingDecl | expressions.swift:105:7:105:23 | ... as ... | TypedPattern |
| expressions.swift:105:7:105:7 | readOnlyField1 | ConcreteVarDecl | expressions.swift:105:27:107:3 | get | AccessorDecl |
| expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:7:105:7 | readOnlyField1 | NamedPattern |
| expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:23:105:23 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:23:105:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:105:27:107:3 | get | AccessorDecl | expressions.swift:105:27:107:3 | { ... } | BraceStmt |
| expressions.swift:105:27:107:3 | { ... } | BraceStmt | expressions.swift:106:5:106:12 | return ... | ReturnStmt |
| expressions.swift:106:5:106:12 | return ... | ReturnStmt | expressions.swift:106:12:106:12 | 0 | IntegerLiteralExpr |
| expressions.swift:110:3:114:3 | var ... = ... | PatternBindingDecl | expressions.swift:110:7:110:23 | ... as ... | TypedPattern |
| expressions.swift:110:7:110:7 | readOnlyField2 | ConcreteVarDecl | expressions.swift:111:5:113:5 | get | AccessorDecl |
| expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:7:110:7 | readOnlyField2 | NamedPattern |
| expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:23:110:23 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:23:110:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:111:5:113:5 | get | AccessorDecl | expressions.swift:111:9:113:5 | { ... } | BraceStmt |
| expressions.swift:111:9:113:5 | { ... } | BraceStmt | expressions.swift:112:7:112:14 | return ... | ReturnStmt |
| expressions.swift:112:7:112:14 | return ... | ReturnStmt | expressions.swift:112:14:112:14 | 0 | IntegerLiteralExpr |
@@ -655,7 +651,7 @@
| expressions.swift:116:7:116:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| expressions.swift:116:7:116:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:7:116:7 | normalField | NamedPattern |
| expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:21:116:21 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:21:116:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:118:3:118:3 | (unnamed function decl) | AccessorDecl | expressions.swift:118:3:118:3 | { ... } | BraceStmt |
| expressions.swift:118:3:118:3 | (unnamed function decl) | AccessorDecl | file://:0:0:0:0 | x | ParamDecl |
| expressions.swift:118:3:118:3 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr |
@@ -736,7 +732,7 @@
| expressions.swift:142:7:142:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| expressions.swift:142:7:142:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:7:142:7 | x | NamedPattern |
| expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:11:142:11 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:11:142:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | b | ParamDecl |
| expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | bs | ParamDecl |
| expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | mayB | ParamDecl |
@@ -753,7 +749,7 @@
| expressions.swift:146:7:146:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| expressions.swift:146:7:146:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:7:146:7 | b | NamedPattern |
| expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:11:146:11 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:11:146:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| expressions.swift:147:3:147:14 | var ... = ... | PatternBindingDecl | expressions.swift:147:7:147:14 | ... as ... | TypedPattern |
| expressions.swift:147:7:147:7 | (unnamed function decl) | AccessorDecl | expressions.swift:147:7:147:7 | { ... } | BraceStmt |
| expressions.swift:147:7:147:7 | bs | ConcreteVarDecl | expressions.swift:147:7:147:7 | (unnamed function decl) | AccessorDecl |
@@ -767,7 +763,6 @@
| expressions.swift:147:7:147:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| expressions.swift:147:7:147:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:7:147:7 | bs | NamedPattern |
| expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:12:147:14 | TBD (ArrayTypeRepr) | ArrayTypeRepr |
| expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:12:147:14 | [...] | ArrayTypeRepr |
| expressions.swift:148:3:148:15 | var ... = ... | PatternBindingDecl | expressions.swift:148:7:148:15 | ... as ... | TypedPattern |
| expressions.swift:148:3:148:15 | var ... = ... | PatternBindingDecl | file://:0:0:0:0 | nil | NilLiteralExpr |
@@ -784,7 +779,6 @@
| expressions.swift:148:7:148:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:7:148:7 | mayB | NamedPattern |
| expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:14:148:15 | ...? | OptionalTypeRepr |
| expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:14:148:15 | TBD (OptionalTypeRepr) | OptionalTypeRepr |
| expressions.swift:151:1:155:1 | test | ConcreteFuncDecl | expressions.swift:151:11:151:15 | a | ParamDecl |
| expressions.swift:151:1:155:1 | test | ConcreteFuncDecl | expressions.swift:151:18:151:53 | keyPathInt | ParamDecl |
| expressions.swift:151:1:155:1 | test | ConcreteFuncDecl | expressions.swift:151:56:151:87 | keyPathB | ParamDecl |
@@ -809,7 +803,7 @@
| expressions.swift:154:22:154:41 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:33:154:33 | keyPathB | DeclRefExpr |
| expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:22:154:41 | \\...[...] | KeyPathApplicationExpr |
| expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr |
| expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | expressions.swift:154:53:154:55 | TBD (UnresolvedDotExpr) | UnresolvedDotExpr |
| expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | expressions.swift:154:53:154:55 | UnresolvedDotExpr | UnresolvedDotExpr |
| patterns.swift:1:1:7:1 | basic_patterns | ConcreteFuncDecl | patterns.swift:1:23:7:1 | { ... } | BraceStmt |
| patterns.swift:1:23:7:1 | { ... } | BraceStmt | patterns.swift:2:5:2:18 | var ... = ... | PatternBindingDecl |
| patterns.swift:1:23:7:1 | { ... } | BraceStmt | patterns.swift:2:9:2:9 | an_int | ConcreteVarDecl |
@@ -826,7 +820,7 @@
| patterns.swift:3:5:3:28 | var ... = ... | PatternBindingDecl | patterns.swift:3:9:3:19 | ... as ... | TypedPattern |
| patterns.swift:3:5:3:28 | var ... = ... | PatternBindingDecl | patterns.swift:3:28:3:28 | here | StringLiteralExpr |
| patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:9:3:9 | a_string | NamedPattern |
| patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:19:3:19 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:19:3:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| patterns.swift:4:5:4:29 | var ... = ... | PatternBindingDecl | patterns.swift:4:9:4:17 | (...) | TuplePattern |
| patterns.swift:4:5:4:29 | var ... = ... | PatternBindingDecl | patterns.swift:4:21:4:29 | (...) | TupleExpr |
| patterns.swift:4:9:4:17 | (...) | TuplePattern | patterns.swift:4:10:4:10 | x | NamedPattern |
@@ -874,10 +868,10 @@
| patterns.swift:15:5:18:5 | switch 3 { ... } | SwitchStmt | patterns.swift:15:12:15:12 | 3 | IntegerLiteralExpr |
| patterns.swift:15:5:18:5 | switch 3 { ... } | SwitchStmt | patterns.swift:16:5:16:17 | case ... | CaseStmt |
| patterns.swift:15:5:18:5 | switch 3 { ... } | SwitchStmt | patterns.swift:17:5:17:13 | case ... | CaseStmt |
| patterns.swift:16:5:16:17 | case ... | CaseStmt | patterns.swift:16:10:16:14 | TBD (SequenceExpr) | CaseLabelItem |
| patterns.swift:16:5:16:17 | case ... | CaseStmt | patterns.swift:16:10:16:14 | SequenceExpr | CaseLabelItem |
| patterns.swift:16:5:16:17 | case ... | CaseStmt | patterns.swift:16:17:16:17 | { ... } | BraceStmt |
| patterns.swift:16:10:16:14 | TBD (SequenceExpr) | CaseLabelItem | patterns.swift:16:10:16:14 | TBD (SequenceExpr) | ExprPattern |
| patterns.swift:16:10:16:14 | TBD (SequenceExpr) | ExprPattern | patterns.swift:16:10:16:14 | TBD (SequenceExpr) | SequenceExpr |
| patterns.swift:16:10:16:14 | SequenceExpr | CaseLabelItem | patterns.swift:16:10:16:14 | SequenceExpr | ExprPattern |
| patterns.swift:16:10:16:14 | SequenceExpr | ExprPattern | patterns.swift:16:10:16:14 | SequenceExpr | SequenceExpr |
| patterns.swift:16:17:16:17 | { ... } | BraceStmt | patterns.swift:16:17:16:17 | expr | StringLiteralExpr |
| patterns.swift:17:5:17:13 | case ... | CaseStmt | patterns.swift:17:10:17:10 | _ | CaseLabelItem |
| patterns.swift:17:5:17:13 | case ... | CaseStmt | patterns.swift:17:13:17:13 | { ... } | BraceStmt |
@@ -890,8 +884,8 @@
| patterns.swift:24:5:24:19 | var ... = ... | PatternBindingDecl | patterns.swift:24:9:24:12 | ... as ... | TypedPattern |
| patterns.swift:24:5:24:19 | var ... = ... | PatternBindingDecl | patterns.swift:24:18:24:19 | call to ... | DotSyntaxCallExpr |
| patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:9:24:9 | v | NamedPattern |
| patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:12:24:12 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| patterns.swift:24:18:24:18 | Foo.Type | TypeExpr | patterns.swift:24:18:24:18 | TBD (FixedTypeRepr) | FixedTypeRepr |
| patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:12:24:12 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| patterns.swift:24:18:24:18 | Foo.Type | TypeExpr | patterns.swift:24:18:24:18 | FixedTypeRepr | FixedTypeRepr |
| patterns.swift:24:18:24:19 | call to ... | DotSyntaxCallExpr | patterns.swift:24:19:24:19 | bar | DeclRefExpr |
| patterns.swift:26:5:29:5 | switch v { ... } | SwitchStmt | patterns.swift:26:12:26:12 | v | DeclRefExpr |
| patterns.swift:26:5:29:5 | switch v { ... } | SwitchStmt | patterns.swift:27:5:27:16 | case ... | CaseStmt |
@@ -912,7 +906,6 @@
| patterns.swift:31:5:31:19 | var ... = ... | PatternBindingDecl | patterns.swift:31:19:31:19 | nil | NilLiteralExpr |
| patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:9:31:9 | w | NamedPattern |
| patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:12:31:15 | ...? | OptionalTypeRepr |
| patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:12:31:15 | TBD (OptionalTypeRepr) | OptionalTypeRepr |
| patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:33:12:33:12 | w | DeclRefExpr |
| patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:34:5:34:18 | case ... | CaseStmt |
| patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:35:5:35:13 | case ... | CaseStmt |
@@ -928,11 +921,9 @@
| patterns.swift:35:13:35:13 | { ... } | BraceStmt | patterns.swift:35:13:35:13 | none | StringLiteralExpr |
| patterns.swift:38:5:38:18 | var ... = ... | PatternBindingDecl | patterns.swift:38:9:38:12 | ... as ... | TypedPattern |
| patterns.swift:38:5:38:18 | var ... = ... | PatternBindingDecl | patterns.swift:38:18:38:18 | (Any) ... | ErasureExpr |
| patterns.swift:38:5:38:18 | var ... = ... | PatternBindingDecl | patterns.swift:38:18:38:18 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:9:38:9 | a | NamedPattern |
| patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:12:38:12 | TBD (CompositionTypeRepr) | CompositionTypeRepr |
| patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:12:38:12 | CompositionTypeRepr | CompositionTypeRepr |
| patterns.swift:38:18:38:18 | (Any) ... | ErasureExpr | patterns.swift:38:18:38:18 | any | StringLiteralExpr |
| patterns.swift:38:18:38:18 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | patterns.swift:38:18:38:18 | any | StringLiteralExpr |
| patterns.swift:40:5:44:5 | switch a { ... } | SwitchStmt | patterns.swift:40:12:40:12 | a | DeclRefExpr |
| patterns.swift:40:5:44:5 | switch a { ... } | SwitchStmt | patterns.swift:41:5:41:18 | case ... | CaseStmt |
| patterns.swift:40:5:44:5 | switch a { ... } | SwitchStmt | patterns.swift:42:5:42:27 | case ... | CaseStmt |
@@ -940,14 +931,14 @@
| patterns.swift:41:5:41:18 | case ... | CaseStmt | patterns.swift:41:10:41:13 | ... is ... | CaseLabelItem |
| patterns.swift:41:5:41:18 | case ... | CaseStmt | patterns.swift:41:18:41:18 | { ... } | BraceStmt |
| patterns.swift:41:10:41:13 | ... is ... | CaseLabelItem | patterns.swift:41:10:41:13 | ... is ... | IsPattern |
| patterns.swift:41:10:41:13 | ... is ... | IsPattern | patterns.swift:41:13:41:13 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| patterns.swift:41:10:41:13 | ... is ... | IsPattern | patterns.swift:41:13:41:13 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| patterns.swift:41:18:41:18 | { ... } | BraceStmt | patterns.swift:41:18:41:18 | is pattern | StringLiteralExpr |
| patterns.swift:42:5:42:27 | case ... | CaseStmt | patterns.swift:42:10:42:19 | let ... | CaseLabelItem |
| patterns.swift:42:5:42:27 | case ... | CaseStmt | patterns.swift:42:27:42:27 | { ... } | BraceStmt |
| patterns.swift:42:10:42:19 | let ... | BindingPattern | patterns.swift:42:14:42:19 | ... is ... | IsPattern |
| patterns.swift:42:10:42:19 | let ... | CaseLabelItem | patterns.swift:42:10:42:19 | let ... | BindingPattern |
| patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:14:42:14 | x | NamedPattern |
| patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:19:42:19 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:19:42:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| patterns.swift:42:27:42:27 | { ... } | BraceStmt | patterns.swift:42:27:42:27 | as pattern | StringLiteralExpr |
| patterns.swift:43:5:43:13 | case ... | CaseStmt | patterns.swift:43:10:43:10 | _ | CaseLabelItem |
| patterns.swift:43:5:43:13 | case ... | CaseStmt | patterns.swift:43:13:43:13 | { ... } | BraceStmt |
@@ -979,14 +970,14 @@
| statements.swift:2:3:8:3 | for ... in ... { ... } | ForEachStmt | statements.swift:2:20:2:24 | ... call to ... ... | BinaryExpr |
| statements.swift:2:3:8:3 | for ... in ... { ... } | ForEachStmt | statements.swift:2:26:8:3 | { ... } | BraceStmt |
| statements.swift:2:20:2:24 | ... call to ... ... | BinaryExpr | statements.swift:2:21:2:21 | call to ... | DotSyntaxCallExpr |
| statements.swift:2:21:2:21 | Int.Type | TypeExpr | statements.swift:2:21:2:21 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:2:21:2:21 | Int.Type | TypeExpr | statements.swift:2:21:2:21 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:2:21:2:21 | call to ... | DotSyntaxCallExpr | statements.swift:2:21:2:21 | ... | DeclRefExpr |
| statements.swift:2:26:8:3 | { ... } | BraceStmt | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt |
| statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:3:8:3:13 | StmtCondition | StmtCondition |
| statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:3:15:5:5 | { ... } | BraceStmt |
| statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:5:12:7:5 | { ... } | BraceStmt |
| statements.swift:3:8:3:13 | ... call to == ... | BinaryExpr | statements.swift:3:10:3:10 | call to == | DotSyntaxCallExpr |
| statements.swift:3:10:3:10 | Int.Type | TypeExpr | statements.swift:3:10:3:10 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:3:10:3:10 | Int.Type | TypeExpr | statements.swift:3:10:3:10 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:3:10:3:10 | call to == | DotSyntaxCallExpr | statements.swift:3:10:3:10 | == | DeclRefExpr |
| statements.swift:3:15:5:5 | { ... } | BraceStmt | statements.swift:4:9:4:9 | break | BreakStmt |
| statements.swift:5:12:7:5 | { ... } | BraceStmt | statements.swift:6:9:6:9 | continue | ContinueStmt |
@@ -997,14 +988,14 @@
| statements.swift:10:17:10:24 | (...) | ParenExpr | statements.swift:10:18:10:22 | ... call to < ... | BinaryExpr |
| statements.swift:10:18:10:18 | (Int) ... | LoadExpr | statements.swift:10:18:10:18 | i | DeclRefExpr |
| statements.swift:10:18:10:22 | ... call to < ... | BinaryExpr | statements.swift:10:20:10:20 | call to < | DotSyntaxCallExpr |
| statements.swift:10:20:10:20 | Int.Type | TypeExpr | statements.swift:10:20:10:20 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:10:20:10:20 | Int.Type | TypeExpr | statements.swift:10:20:10:20 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:10:20:10:20 | call to < | DotSyntaxCallExpr | statements.swift:10:20:10:20 | < | DeclRefExpr |
| statements.swift:10:26:12:3 | { ... } | BraceStmt | statements.swift:11:5:11:13 | ... = ... | AssignExpr |
| statements.swift:11:5:11:13 | ... = ... | AssignExpr | statements.swift:11:5:11:5 | i | DeclRefExpr |
| statements.swift:11:5:11:13 | ... = ... | AssignExpr | statements.swift:11:9:11:13 | ... call to + ... | BinaryExpr |
| statements.swift:11:9:11:9 | (Int) ... | LoadExpr | statements.swift:11:9:11:9 | i | DeclRefExpr |
| statements.swift:11:9:11:13 | ... call to + ... | BinaryExpr | statements.swift:11:11:11:11 | call to + | DotSyntaxCallExpr |
| statements.swift:11:11:11:11 | Int.Type | TypeExpr | statements.swift:11:11:11:11 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:11:11:11:11 | Int.Type | TypeExpr | statements.swift:11:11:11:11 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:11:11:11:11 | call to + | DotSyntaxCallExpr | statements.swift:11:11:11:11 | + | DeclRefExpr |
| statements.swift:14:3:14:7 | ... = ... | AssignExpr | statements.swift:14:3:14:3 | i | DeclRefExpr |
| statements.swift:14:3:14:7 | ... = ... | AssignExpr | statements.swift:14:7:14:7 | 0 | IntegerLiteralExpr |
@@ -1015,12 +1006,12 @@
| statements.swift:16:5:16:13 | ... = ... | AssignExpr | statements.swift:16:9:16:13 | ... call to + ... | BinaryExpr |
| statements.swift:16:9:16:9 | (Int) ... | LoadExpr | statements.swift:16:9:16:9 | i | DeclRefExpr |
| statements.swift:16:9:16:13 | ... call to + ... | BinaryExpr | statements.swift:16:11:16:11 | call to + | DotSyntaxCallExpr |
| statements.swift:16:11:16:11 | Int.Type | TypeExpr | statements.swift:16:11:16:11 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:16:11:16:11 | Int.Type | TypeExpr | statements.swift:16:11:16:11 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:16:11:16:11 | call to + | DotSyntaxCallExpr | statements.swift:16:11:16:11 | + | DeclRefExpr |
| statements.swift:17:11:17:18 | (...) | ParenExpr | statements.swift:17:12:17:16 | ... call to < ... | BinaryExpr |
| statements.swift:17:12:17:12 | (Int) ... | LoadExpr | statements.swift:17:12:17:12 | i | DeclRefExpr |
| statements.swift:17:12:17:16 | ... call to < ... | BinaryExpr | statements.swift:17:14:17:14 | call to < | DotSyntaxCallExpr |
| statements.swift:17:14:17:14 | Int.Type | TypeExpr | statements.swift:17:14:17:14 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:17:14:17:14 | Int.Type | TypeExpr | statements.swift:17:14:17:14 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:17:14:17:14 | call to < | DotSyntaxCallExpr | statements.swift:17:14:17:14 | < | DeclRefExpr |
| statements.swift:19:3:23:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:19:6:21:3 | { ... } | BraceStmt |
| statements.swift:19:3:23:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:21:5:23:3 | case ... | CaseStmt |
@@ -1034,9 +1025,7 @@
| statements.swift:21:11:23:3 | { ... } | BraceStmt | statements.swift:22:5:22:18 | call to print | CallExpr |
| statements.swift:22:5:22:18 | call to print | CallExpr | statements.swift:22:5:22:5 | print | DeclRefExpr |
| statements.swift:22:11:22:11 | (Any) ... | ErasureExpr | statements.swift:22:11:22:11 | error | StringLiteralExpr |
| statements.swift:22:11:22:11 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:22:11:22:11 | error | StringLiteralExpr |
| statements.swift:22:11:22:11 | [...] | ArrayExpr | statements.swift:22:11:22:11 | (Any) ... | ErasureExpr |
| statements.swift:22:11:22:11 | [...] | ArrayExpr | statements.swift:22:11:22:11 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:22:11:22:11 | [...] | VarargExpansionExpr | statements.swift:22:11:22:11 | [...] | ArrayExpr |
| statements.swift:25:3:31:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:25:6:27:3 | { ... } | BraceStmt |
| statements.swift:25:3:31:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:27:5:29:3 | case ... | CaseStmt |
@@ -1051,9 +1040,7 @@
| statements.swift:27:26:29:3 | { ... } | BraceStmt | statements.swift:28:5:28:27 | call to print | CallExpr |
| statements.swift:28:5:28:27 | call to print | CallExpr | statements.swift:28:5:28:5 | print | DeclRefExpr |
| statements.swift:28:11:28:11 | (Any) ... | ErasureExpr | statements.swift:28:11:28:11 | AnError.failed | StringLiteralExpr |
| statements.swift:28:11:28:11 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:28:11:28:11 | AnError.failed | StringLiteralExpr |
| statements.swift:28:11:28:11 | [...] | ArrayExpr | statements.swift:28:11:28:11 | (Any) ... | ErasureExpr |
| statements.swift:28:11:28:11 | [...] | ArrayExpr | statements.swift:28:11:28:11 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:28:11:28:11 | [...] | VarargExpansionExpr | statements.swift:28:11:28:11 | [...] | ArrayExpr |
| statements.swift:29:5:31:3 | case ... | CaseStmt | statements.swift:29:11:29:11 | let ... | CaseLabelItem |
| statements.swift:29:5:31:3 | case ... | CaseStmt | statements.swift:29:11:31:3 | { ... } | BraceStmt |
@@ -1062,9 +1049,7 @@
| statements.swift:29:11:31:3 | { ... } | BraceStmt | statements.swift:30:5:30:18 | call to print | CallExpr |
| statements.swift:30:5:30:18 | call to print | CallExpr | statements.swift:30:5:30:5 | print | DeclRefExpr |
| statements.swift:30:11:30:11 | (Any) ... | ErasureExpr | statements.swift:30:11:30:11 | error | StringLiteralExpr |
| statements.swift:30:11:30:11 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:30:11:30:11 | error | StringLiteralExpr |
| statements.swift:30:11:30:11 | [...] | ArrayExpr | statements.swift:30:11:30:11 | (Any) ... | ErasureExpr |
| statements.swift:30:11:30:11 | [...] | ArrayExpr | statements.swift:30:11:30:11 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:30:11:30:11 | [...] | VarargExpansionExpr | statements.swift:30:11:30:11 | [...] | ArrayExpr |
| statements.swift:35:3:35:8 | case ... | EnumCaseDecl | statements.swift:35:8:35:8 | failed | EnumElementDecl |
| statements.swift:38:1:42:1 | failure | ConcreteFuncDecl | statements.swift:38:14:38:19 | x | ParamDecl |
@@ -1073,14 +1058,12 @@
| statements.swift:39:3:41:3 | guard ... else { ... } | GuardStmt | statements.swift:39:9:39:14 | StmtCondition | StmtCondition |
| statements.swift:39:3:41:3 | guard ... else { ... } | GuardStmt | statements.swift:39:21:41:3 | { ... } | BraceStmt |
| statements.swift:39:9:39:14 | ... call to != ... | BinaryExpr | statements.swift:39:11:39:11 | call to != | DotSyntaxCallExpr |
| statements.swift:39:11:39:11 | Int.Type | TypeExpr | statements.swift:39:11:39:11 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:39:11:39:11 | Int.Type | TypeExpr | statements.swift:39:11:39:11 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:39:11:39:11 | call to != | DotSyntaxCallExpr | statements.swift:39:11:39:11 | != | DeclRefExpr |
| statements.swift:39:21:41:3 | { ... } | BraceStmt | statements.swift:40:5:40:19 | throw ... | ThrowStmt |
| statements.swift:40:5:40:19 | throw ... | ThrowStmt | statements.swift:40:11:40:19 | (Error) ... | ErasureExpr |
| statements.swift:40:5:40:19 | throw ... | ThrowStmt | statements.swift:40:11:40:19 | (TBD (ExistentialType)) ... | ErasureExpr |
| statements.swift:40:11:40:11 | AnError.Type | TypeExpr | statements.swift:40:11:40:11 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| statements.swift:40:11:40:11 | AnError.Type | TypeExpr | statements.swift:40:11:40:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| statements.swift:40:11:40:19 | (Error) ... | ErasureExpr | statements.swift:40:11:40:19 | call to ... | DotSyntaxCallExpr |
| statements.swift:40:11:40:19 | (TBD (ExistentialType)) ... | ErasureExpr | statements.swift:40:11:40:19 | call to ... | DotSyntaxCallExpr |
| statements.swift:40:11:40:19 | call to ... | DotSyntaxCallExpr | statements.swift:40:19:40:19 | failed | DeclRefExpr |
| statements.swift:44:1:46:1 | defer { ... } | DeferStmt | statements.swift:44:7:46:1 | { ... } | BraceStmt |
| statements.swift:44:1:46:1 | { ... } | BraceStmt | statements.swift:44:1:46:1 | defer { ... } | DeferStmt |
@@ -1088,9 +1071,7 @@
| statements.swift:44:7:46:1 | { ... } | BraceStmt | statements.swift:45:3:45:15 | call to print | CallExpr |
| statements.swift:45:3:45:15 | call to print | CallExpr | statements.swift:45:3:45:3 | print | DeclRefExpr |
| statements.swift:45:9:45:9 | (Any) ... | ErasureExpr | statements.swift:45:9:45:9 | done | StringLiteralExpr |
| statements.swift:45:9:45:9 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:45:9:45:9 | done | StringLiteralExpr |
| statements.swift:45:9:45:9 | [...] | ArrayExpr | statements.swift:45:9:45:9 | (Any) ... | ErasureExpr |
| statements.swift:45:9:45:9 | [...] | ArrayExpr | statements.swift:45:9:45:9 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:45:9:45:9 | [...] | VarargExpansionExpr | statements.swift:45:9:45:9 | [...] | ArrayExpr |
| statements.swift:48:1:50:1 | do { ... } | DoStmt | statements.swift:48:4:50:1 | { ... } | BraceStmt |
| statements.swift:48:1:50:1 | { ... } | BraceStmt | statements.swift:48:1:50:1 | do { ... } | DoStmt |
@@ -1098,9 +1079,7 @@
| statements.swift:48:4:50:1 | { ... } | BraceStmt | statements.swift:49:3:49:16 | call to print | CallExpr |
| statements.swift:49:3:49:16 | call to print | CallExpr | statements.swift:49:3:49:3 | print | DeclRefExpr |
| statements.swift:49:9:49:9 | (Any) ... | ErasureExpr | statements.swift:49:9:49:9 | doing | StringLiteralExpr |
| statements.swift:49:9:49:9 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:49:9:49:9 | doing | StringLiteralExpr |
| statements.swift:49:9:49:9 | [...] | ArrayExpr | statements.swift:49:9:49:9 | (Any) ... | ErasureExpr |
| statements.swift:49:9:49:9 | [...] | ArrayExpr | statements.swift:49:9:49:9 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:49:9:49:9 | [...] | VarargExpansionExpr | statements.swift:49:9:49:9 | [...] | ArrayExpr |
| statements.swift:52:1:52:13 | var ... = ... | PatternBindingDecl | statements.swift:52:5:52:5 | index | NamedPattern |
| statements.swift:52:1:52:13 | var ... = ... | PatternBindingDecl | statements.swift:52:13:52:13 | 42 | IntegerLiteralExpr |
@@ -1120,9 +1099,7 @@
| statements.swift:55:7:56:7 | { ... } | BraceStmt | statements.swift:55:7:55:16 | call to print | CallExpr |
| statements.swift:55:7:56:7 | { ... } | BraceStmt | statements.swift:56:7:56:7 | fallthrough | FallthroughStmt |
| statements.swift:55:13:55:13 | (Any) ... | ErasureExpr | statements.swift:55:13:55:13 | 1 | StringLiteralExpr |
| statements.swift:55:13:55:13 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:55:13:55:13 | 1 | StringLiteralExpr |
| statements.swift:55:13:55:13 | [...] | ArrayExpr | statements.swift:55:13:55:13 | (Any) ... | ErasureExpr |
| statements.swift:55:13:55:13 | [...] | ArrayExpr | statements.swift:55:13:55:13 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:55:13:55:13 | [...] | VarargExpansionExpr | statements.swift:55:13:55:13 | [...] | ArrayExpr |
| statements.swift:57:4:59:7 | case ... | CaseStmt | statements.swift:57:9:57:9 | 5 | CaseLabelItem |
| statements.swift:57:4:59:7 | case ... | CaseStmt | statements.swift:57:12:57:12 | 10 | CaseLabelItem |
@@ -1135,9 +1112,7 @@
| statements.swift:58:7:59:7 | { ... } | BraceStmt | statements.swift:58:7:58:20 | call to print | CallExpr |
| statements.swift:58:7:59:7 | { ... } | BraceStmt | statements.swift:59:7:59:7 | break | BreakStmt |
| statements.swift:58:13:58:13 | (Any) ... | ErasureExpr | statements.swift:58:13:58:13 | 5, 10 | StringLiteralExpr |
| statements.swift:58:13:58:13 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:58:13:58:13 | 5, 10 | StringLiteralExpr |
| statements.swift:58:13:58:13 | [...] | ArrayExpr | statements.swift:58:13:58:13 | (Any) ... | ErasureExpr |
| statements.swift:58:13:58:13 | [...] | ArrayExpr | statements.swift:58:13:58:13 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:58:13:58:13 | [...] | VarargExpansionExpr | statements.swift:58:13:58:13 | [...] | ArrayExpr |
| statements.swift:60:4:60:4 | _ | CaseLabelItem | statements.swift:60:4:60:4 | _ | AnyPattern |
| statements.swift:60:4:61:22 | case ... | CaseStmt | statements.swift:60:4:60:4 | _ | CaseLabelItem |
@@ -1145,9 +1120,7 @@
| statements.swift:61:7:61:22 | call to print | CallExpr | statements.swift:61:7:61:7 | print | DeclRefExpr |
| statements.swift:61:7:61:22 | { ... } | BraceStmt | statements.swift:61:7:61:22 | call to print | CallExpr |
| statements.swift:61:13:61:13 | (Any) ... | ErasureExpr | statements.swift:61:13:61:13 | default | StringLiteralExpr |
| statements.swift:61:13:61:13 | (TBD (ProtocolCompositionType)) ... | ErasureExpr | statements.swift:61:13:61:13 | default | StringLiteralExpr |
| statements.swift:61:13:61:13 | [...] | ArrayExpr | statements.swift:61:13:61:13 | (Any) ... | ErasureExpr |
| statements.swift:61:13:61:13 | [...] | ArrayExpr | statements.swift:61:13:61:13 | (TBD (ProtocolCompositionType)) ... | ErasureExpr |
| statements.swift:61:13:61:13 | [...] | VarargExpansionExpr | statements.swift:61:13:61:13 | [...] | ArrayExpr |
| statements.swift:64:1:64:15 | var ... = ... | PatternBindingDecl | statements.swift:64:5:64:11 | ... as ... | TypedPattern |
| statements.swift:64:1:64:15 | var ... = ... | PatternBindingDecl | statements.swift:64:15:64:15 | (Int?) ... | InjectIntoOptionalExpr |
@@ -1155,7 +1128,6 @@
| statements.swift:64:1:64:15 | { ... } | TopLevelCodeDecl | statements.swift:64:1:64:15 | { ... } | BraceStmt |
| statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:5:64:5 | x | NamedPattern |
| statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:8:64:11 | ...? | OptionalTypeRepr |
| statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:8:64:11 | TBD (OptionalTypeRepr) | OptionalTypeRepr |
| statements.swift:64:15:64:15 | (Int?) ... | InjectIntoOptionalExpr | statements.swift:64:15:64:15 | 4 | IntegerLiteralExpr |
| statements.swift:65:1:66:1 | if ... then { ... } | IfStmt | statements.swift:65:4:65:19 | StmtCondition | StmtCondition |
| statements.swift:65:1:66:1 | if ... then { ... } | IfStmt | statements.swift:65:21:66:1 | { ... } | BraceStmt |
@@ -1184,9 +1156,9 @@
| statements.swift:71:1:72:1 | { ... } | TopLevelCodeDecl | statements.swift:71:1:72:1 | { ... } | BraceStmt |
| statements.swift:71:29:71:38 | ... call to % ... | BinaryExpr | statements.swift:71:36:71:36 | call to % | DotSyntaxCallExpr |
| statements.swift:71:29:71:43 | ... call to == ... | BinaryExpr | statements.swift:71:40:71:40 | call to == | DotSyntaxCallExpr |
| statements.swift:71:36:71:36 | Int.Type | TypeExpr | statements.swift:71:36:71:36 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:71:36:71:36 | Int.Type | TypeExpr | statements.swift:71:36:71:36 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:71:36:71:36 | call to % | DotSyntaxCallExpr | statements.swift:71:36:71:36 | % | DeclRefExpr |
| statements.swift:71:40:71:40 | Int.Type | TypeExpr | statements.swift:71:40:71:40 | TBD (FixedTypeRepr) | FixedTypeRepr |
| statements.swift:71:40:71:40 | Int.Type | TypeExpr | statements.swift:71:40:71:40 | FixedTypeRepr | FixedTypeRepr |
| statements.swift:71:40:71:40 | call to == | DotSyntaxCallExpr | statements.swift:71:40:71:40 | == | DeclRefExpr |
| statements.swift:74:8:74:8 | init | ConstructorDecl | statements.swift:74:8:74:8 | x | ParamDecl |
| statements.swift:75:3:75:11 | var ... = ... | PatternBindingDecl | statements.swift:75:7:75:11 | ... as ... | TypedPattern |
@@ -1202,7 +1174,7 @@
| statements.swift:75:7:75:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt |
| statements.swift:75:7:75:7 | { ... } | BraceStmt | statements.swift:75:7:75:7 | yield ... | YieldStmt |
| statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:7:75:7 | x | NamedPattern |
| statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:11:75:11 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:11:75:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| statements.swift:76:3:84:3 | var ... = ... | PatternBindingDecl | statements.swift:76:7:76:19 | ... as ... | TypedPattern |
| statements.swift:76:7:76:7 | hasModify | ConcreteVarDecl | statements.swift:76:7:76:7 | set | AccessorDecl |
| statements.swift:76:7:76:7 | hasModify | ConcreteVarDecl | statements.swift:77:5:79:5 | (unnamed function decl) | AccessorDecl |
@@ -1211,7 +1183,7 @@
| statements.swift:76:7:76:7 | set | AccessorDecl | statements.swift:76:7:76:7 | { ... } | BraceStmt |
| statements.swift:76:7:76:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr |
| statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:7:76:7 | hasModify | NamedPattern |
| statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:19:76:19 | TBD (SimpleIdentTypeRepr) | SimpleIdentTypeRepr |
| statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:19:76:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr |
| statements.swift:77:5:79:5 | (unnamed function decl) | AccessorDecl | statements.swift:77:13:79:5 | { ... } | BraceStmt |
| statements.swift:77:13:79:5 | { ... } | BraceStmt | statements.swift:78:7:78:14 | yield ... | YieldStmt |
| statements.swift:78:7:78:14 | yield ... | YieldStmt | statements.swift:78:13:78:14 | &... | InOutExpr |