Merge branch 'main' into express-rate-limit

This commit is contained in:
Mark Vogelgesang
2023-01-18 14:44:29 -05:00
committed by GitHub
5 changed files with 91 additions and 25 deletions

View File

@@ -91,20 +91,21 @@ class CfgNode extends ControlFlowNode, TElementNode {
/** Gets a split for this control flow node, if any. */
final Split getASplit() { result = splits.getASplit() }
}
private Expr getAst(ControlFlowElement n) {
result = n.asAstNode()
or
result = n.(PropertyGetterElement).getRef()
or
result = n.(PropertySetterElement).getAssignExpr()
or
result = n.(PropertyObserverElement).getAssignExpr()
or
result = n.(ClosureElement).getAst()
or
result = n.(KeyPathElement).getAst()
/** Gets the AST representation of this control flow node, if any. */
Expr getAst() {
result = n.asAstNode()
or
result = n.(PropertyGetterElement).getRef()
or
result = n.(PropertySetterElement).getAssignExpr()
or
result = n.(PropertyObserverElement).getAssignExpr()
or
result = n.(ClosureElement).getAst()
or
result = n.(KeyPathElement).getAst()
}
}
/** A control-flow node that wraps an AST expression. */
@@ -123,7 +124,7 @@ class PropertyGetterCfgNode extends CfgNode {
Expr getRef() { result = n.getRef() }
CfgNode getBase() { getAst(result.getNode()) = n.getBase() }
CfgNode getBase() { result.getAst() = n.getBase() }
AccessorDecl getAccessorDecl() { result = n.getAccessorDecl() }
}
@@ -134,9 +135,9 @@ class PropertySetterCfgNode extends CfgNode {
AssignExpr getAssignExpr() { result = n.getAssignExpr() }
CfgNode getBase() { getAst(result.getNode()) = n.getBase() }
CfgNode getBase() { result.getAst() = n.getBase() }
CfgNode getSource() { getAst(result.getNode()) = n.getAssignExpr().getSource() }
CfgNode getSource() { result.getAst() = n.getAssignExpr().getSource() }
AccessorDecl getAccessorDecl() { result = n.getAccessorDecl() }
}
@@ -146,9 +147,9 @@ class PropertyObserverCfgNode extends CfgNode {
AssignExpr getAssignExpr() { result = n.getAssignExpr() }
CfgNode getBase() { getAst(result.getNode()) = n.getBase() }
CfgNode getBase() { result.getAst() = n.getBase() }
CfgNode getSource() { getAst(result.getNode()) = n.getAssignExpr().getSource() }
CfgNode getSource() { result.getAst() = n.getAssignExpr().getSource() }
AccessorDecl getAccessorDecl() { result = n.getObserver() }
}
@@ -156,9 +157,9 @@ class PropertyObserverCfgNode extends CfgNode {
class ApplyExprCfgNode extends ExprCfgNode {
override ApplyExpr e;
CfgNode getArgument(int index) { getAst(result.getNode()) = e.getArgument(index).getExpr() }
CfgNode getArgument(int index) { result.getAst() = e.getArgument(index).getExpr() }
CfgNode getQualifier() { getAst(result.getNode()) = e.getQualifier() }
CfgNode getQualifier() { result.getAst() = e.getQualifier() }
AbstractFunctionDecl getStaticTarget() { result = e.getStaticTarget() }

View File

@@ -160,10 +160,7 @@ module Ssa {
pbd.getAPattern() = bb.getNode(blockIndex).getNode().asAstNode() and
init = var.getParentInitializer()
|
value.getNode().asAstNode() = init
or
// TODO: We should probably enumerate more cfg nodes here.
value.(PropertyGetterCfgNode).getRef() = init
value.getAst() = init
)
or
exists(SsaInput::BasicBlock bb, int blockIndex, ConditionElement ce, Expr init |
@@ -172,7 +169,7 @@ module Ssa {
init = ce.getInitializer() and
strictcount(Ssa::WriteDefinition alt | alt.definesAt(_, bb, blockIndex)) = 1 // exclude cases where there are multiple writes from the same pattern, this is at best taint flow.
|
value.getNode().asAstNode() = init
value.getAst() = init
)
}
}

View File

@@ -2,6 +2,8 @@ edges
| file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : |
| file://:0:0:0:0 | self [a, x] : | file://:0:0:0:0 | .a [x] : |
| file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : |
| file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : |
| file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [x] : |
| file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [x] : |
| 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 |
@@ -101,6 +103,7 @@ edges
| test.swift:225:14:225:21 | call to source() : | test.swift:238:13:238:15 | .source_value |
| test.swift:259:12:259:19 | call to source() : | test.swift:263:13:263:28 | call to optionalSource() : |
| test.swift:259:12:259:19 | call to source() : | test.swift:439:13:439:28 | call to optionalSource() : |
| test.swift:259:12:259:19 | call to source() : | test.swift:466:13:466:28 | call to optionalSource() : |
| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:265:15:265:15 | x |
| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:267:15:267:16 | ...! |
| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:271:15:271:16 | ...? : |
@@ -142,14 +145,27 @@ edges
| test.swift:360:15:360:15 | t2 [Tuple element at index 0] : | test.swift:360:15:360:18 | .0 |
| test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | test.swift:361:15:361:18 | .1 |
| test.swift:439:13:439:28 | call to optionalSource() : | test.swift:442:19:442:19 | a |
| test.swift:462:9:462:9 | self [x] : | file://:0:0:0:0 | self [x] : |
| test.swift:462:9:462:9 | value : | file://:0:0:0:0 | value : |
| test.swift:466:13:466:28 | call to optionalSource() : | test.swift:468:12:468:12 | x : |
| test.swift:468:5:468:5 | [post] cx [x] : | test.swift:472:20:472:20 | cx [x] : |
| test.swift:468:12:468:12 | x : | test.swift:462:9:462:9 | value : |
| test.swift:468:12:468:12 | x : | test.swift:468:5:468:5 | [post] cx [x] : |
| test.swift:472:20:472:20 | cx [x] : | test.swift:462:9:462:9 | self [x] : |
| test.swift:472:20:472:20 | cx [x] : | test.swift:472:20:472:23 | .x : |
| test.swift:472:20:472:23 | .x : | test.swift:473:15:473:15 | z1 |
nodes
| file://:0:0:0:0 | .a [x] : | semmle.label | .a [x] : |
| file://:0:0:0:0 | .x : | semmle.label | .x : |
| file://:0:0:0:0 | .x : | semmle.label | .x : |
| file://:0:0:0:0 | [post] self [x] : | semmle.label | [post] self [x] : |
| file://:0:0:0:0 | [post] self [x] : | semmle.label | [post] self [x] : |
| file://:0:0:0:0 | [summary param] this in signum() : | semmle.label | [summary param] this in signum() : |
| file://:0:0:0:0 | [summary] to write: return (return) in signum() : | semmle.label | [summary] to write: return (return) in signum() : |
| file://:0:0:0:0 | self [a, x] : | semmle.label | self [a, x] : |
| file://:0:0:0:0 | self [x] : | semmle.label | self [x] : |
| file://:0:0:0:0 | self [x] : | semmle.label | self [x] : |
| file://:0:0:0:0 | value : | semmle.label | value : |
| file://:0:0:0:0 | value : | semmle.label | value : |
| test.swift:6:19:6:26 | call to source() : | semmle.label | call to source() : |
| test.swift:7:15:7:15 | t1 | semmle.label | t1 |
@@ -300,6 +316,14 @@ nodes
| test.swift:361:15:361:18 | .1 | semmle.label | .1 |
| test.swift:439:13:439:28 | call to optionalSource() : | semmle.label | call to optionalSource() : |
| test.swift:442:19:442:19 | a | semmle.label | a |
| test.swift:462:9:462:9 | self [x] : | semmle.label | self [x] : |
| test.swift:462:9:462:9 | value : | semmle.label | value : |
| test.swift:466:13:466:28 | call to optionalSource() : | semmle.label | call to optionalSource() : |
| test.swift:468:5:468:5 | [post] cx [x] : | semmle.label | [post] cx [x] : |
| test.swift:468:12:468:12 | x : | semmle.label | x : |
| test.swift:472:20:472:20 | cx [x] : | semmle.label | cx [x] : |
| test.swift:472:20:472:23 | .x : | semmle.label | .x : |
| test.swift:473:15:473:15 | z1 | semmle.label | z1 |
subpaths
| test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | arg1 : | test.swift:65:1:70:1 | arg2[return] : | test.swift:75:31:75:32 | [post] &... : |
| test.swift:114:19:114:19 | arg : | test.swift:109:9:109:14 | arg : | test.swift:110:12:110:12 | arg : | test.swift:114:12:114:22 | call to ... : |
@@ -330,6 +354,8 @@ subpaths
| test.swift:271:15:271:16 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:271:15:271:25 | call to signum() : |
| test.swift:291:16:291:17 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:291:16:291:26 | call to signum() : |
| test.swift:303:15:303:16 | ...! : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:303:15:303:25 | call to signum() |
| test.swift:468:12:468:12 | x : | test.swift:462:9:462:9 | value : | file://:0:0:0:0 | [post] self [x] : | test.swift:468:5:468:5 | [post] cx [x] : |
| test.swift:472:20:472:20 | cx [x] : | test.swift:462:9:462:9 | self [x] : | file://:0:0:0:0 | .x : | test.swift:472:20:472:23 | .x : |
#select
| 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 |
@@ -381,3 +407,4 @@ subpaths
| test.swift:360:15:360:18 | .0 | test.swift:351:18:351:25 | call to source() : | test.swift:360:15:360:18 | .0 | result |
| test.swift:361:15:361:18 | .1 | test.swift:351:31:351:38 | call to source() : | test.swift:361:15:361:18 | .1 | result |
| test.swift:442:19:442:19 | a | test.swift:259:12:259:19 | call to source() : | test.swift:442:19:442:19 | a | result |
| test.swift:473:15:473:15 | z1 | test.swift:259:12:259:19 | call to source() : | test.swift:473:15:473:15 | z1 | result |

View File

@@ -366,3 +366,27 @@
| test.swift:448:10:448:37 | SSA def(b) | test.swift:450:19:450:19 | b |
| test.swift:455:8:455:17 | SSA def(x) | test.swift:456:19:456:19 | x |
| test.swift:455:8:455:17 | SSA def(y) | test.swift:457:19:457:19 | y |
| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] |
| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] |
| test.swift:461:7:461:7 | self | test.swift:461:7:461:7 | SSA def(self) |
| test.swift:461:7:461:7 | self | test.swift:461:7:461:7 | SSA def(self) |
| test.swift:462:9:462:9 | self | test.swift:462:9:462:9 | SSA def(self) |
| test.swift:462:9:462:9 | self | test.swift:462:9:462:9 | SSA def(self) |
| test.swift:462:9:462:9 | self | test.swift:462:9:462:9 | SSA def(self) |
| test.swift:462:9:462:9 | value | test.swift:462:9:462:9 | SSA def(value) |
| test.swift:465:33:465:39 | SSA def(y) | test.swift:470:12:470:12 | y |
| test.swift:465:33:465:39 | y | test.swift:465:33:465:39 | SSA def(y) |
| test.swift:466:9:466:9 | SSA def(x) | test.swift:468:12:468:12 | x |
| test.swift:466:13:466:28 | call to optionalSource() | test.swift:466:9:466:9 | SSA def(x) |
| test.swift:467:9:467:9 | SSA def(cx) | test.swift:468:5:468:5 | cx |
| test.swift:467:14:467:16 | call to C.init() | test.swift:467:9:467:9 | SSA def(cx) |
| test.swift:468:5:468:5 | [post] cx | test.swift:472:20:472:20 | cx |
| test.swift:468:5:468:5 | cx | test.swift:472:20:472:20 | cx |
| test.swift:469:9:469:9 | SSA def(cy) | test.swift:470:5:470:5 | cy |
| test.swift:469:14:469:16 | call to C.init() | test.swift:469:9:469:9 | SSA def(cy) |
| test.swift:470:5:470:5 | [post] cy | test.swift:474:20:474:20 | cy |
| test.swift:470:5:470:5 | cy | test.swift:474:20:474:20 | cy |
| test.swift:472:11:472:15 | SSA def(z1) | test.swift:473:15:473:15 | z1 |
| test.swift:472:20:472:23 | .x | test.swift:472:11:472:15 | SSA def(z1) |
| test.swift:474:11:474:15 | SSA def(z2) | test.swift:475:15:475:15 | z2 |
| test.swift:474:20:474:23 | .x | test.swift:474:11:474:15 | SSA def(z2) |

View File

@@ -457,3 +457,20 @@ func testOptionals2(y: Int?) {
sink(arg: y) // (taint but not data flow)
}
}
class C {
var x: Int?
}
func testOptionalPropertyAccess(y: Int?) {
let x = optionalSource()
let cx = C()
cx.x = x
let cy = C()
cy.x = y
guard let z1 = cx.x else { return }
sink(arg: z1) // $ flow=259
guard let z2 = cy.x else { return }
sink(arg: z2)
}