From 87c0b6195fc80480378a295955851592a1be7ba4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 20 Feb 2023 15:28:02 +0000 Subject: [PATCH 1/2] Swift: Add taint tests for various arithmetic operators. --- .../dataflow/taint/LocalTaint.expected | 59 ++++++++++++++++ .../library-tests/dataflow/taint/simple.swift | 70 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 swift/ql/test/library-tests/dataflow/taint/simple.swift diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 951def0fd910..9ceb0b4aa328 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -557,6 +557,65 @@ | nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | | nsmutabledata.swift:48:33:48:40 | call to source() | nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | +| simple.swift:36:7:36:7 | SSA def(a) | simple.swift:37:13:37:13 | a | +| simple.swift:36:11:36:11 | 0 | simple.swift:36:7:36:7 | SSA def(a) | +| simple.swift:37:13:37:13 | [post] a | simple.swift:38:3:38:3 | a | +| simple.swift:37:13:37:13 | a | simple.swift:38:3:38:3 | a | +| simple.swift:38:3:38:3 | &... | simple.swift:39:13:39:13 | a | +| simple.swift:38:3:38:3 | [post] &... | simple.swift:39:13:39:13 | a | +| simple.swift:38:3:38:3 | a | simple.swift:38:3:38:3 | &... | +| simple.swift:39:13:39:13 | [post] a | simple.swift:40:3:40:3 | a | +| simple.swift:39:13:39:13 | a | simple.swift:40:3:40:3 | a | +| simple.swift:40:3:40:3 | &... | simple.swift:41:13:41:13 | a | +| simple.swift:40:3:40:3 | [post] &... | simple.swift:41:13:41:13 | a | +| simple.swift:40:3:40:3 | a | simple.swift:40:3:40:3 | &... | +| simple.swift:41:13:41:13 | [post] a | simple.swift:42:3:42:3 | a | +| simple.swift:41:13:41:13 | a | simple.swift:42:3:42:3 | a | +| simple.swift:42:3:42:3 | &... | simple.swift:43:13:43:13 | a | +| simple.swift:42:3:42:3 | [post] &... | simple.swift:43:13:43:13 | a | +| simple.swift:42:3:42:3 | a | simple.swift:42:3:42:3 | &... | +| simple.swift:44:3:44:7 | SSA def(a) | simple.swift:45:13:45:13 | a | +| simple.swift:44:7:44:7 | 0 | simple.swift:44:3:44:7 | SSA def(a) | +| simple.swift:47:7:47:7 | SSA def(b) | simple.swift:48:3:48:3 | b | +| simple.swift:47:11:47:11 | 128 | simple.swift:47:7:47:7 | SSA def(b) | +| simple.swift:48:3:48:3 | &... | simple.swift:49:13:49:13 | b | +| simple.swift:48:3:48:3 | [post] &... | simple.swift:49:13:49:13 | b | +| simple.swift:48:3:48:3 | b | simple.swift:48:3:48:3 | &... | +| simple.swift:49:13:49:13 | [post] b | simple.swift:50:3:50:3 | b | +| simple.swift:49:13:49:13 | b | simple.swift:50:3:50:3 | b | +| simple.swift:50:3:50:3 | &... | simple.swift:51:13:51:13 | b | +| simple.swift:50:3:50:3 | [post] &... | simple.swift:51:13:51:13 | b | +| simple.swift:50:3:50:3 | b | simple.swift:50:3:50:3 | &... | +| simple.swift:53:7:53:7 | SSA def(c) | simple.swift:54:3:54:3 | c | +| simple.swift:53:11:53:11 | 10 | simple.swift:53:7:53:7 | SSA def(c) | +| simple.swift:54:3:54:3 | &... | simple.swift:55:13:55:13 | c | +| simple.swift:54:3:54:3 | [post] &... | simple.swift:55:13:55:13 | c | +| simple.swift:54:3:54:3 | c | simple.swift:54:3:54:3 | &... | +| simple.swift:55:13:55:13 | [post] c | simple.swift:56:3:56:3 | c | +| simple.swift:55:13:55:13 | c | simple.swift:56:3:56:3 | c | +| simple.swift:56:3:56:3 | &... | simple.swift:57:13:57:13 | c | +| simple.swift:56:3:56:3 | [post] &... | simple.swift:57:13:57:13 | c | +| simple.swift:56:3:56:3 | c | simple.swift:56:3:56:3 | &... | +| simple.swift:59:7:59:7 | SSA def(d) | simple.swift:60:3:60:3 | d | +| simple.swift:59:11:59:11 | 100 | simple.swift:59:7:59:7 | SSA def(d) | +| simple.swift:60:3:60:3 | &... | simple.swift:61:13:61:13 | d | +| simple.swift:60:3:60:3 | [post] &... | simple.swift:61:13:61:13 | d | +| simple.swift:60:3:60:3 | d | simple.swift:60:3:60:3 | &... | +| simple.swift:61:13:61:13 | [post] d | simple.swift:62:3:62:3 | d | +| simple.swift:61:13:61:13 | d | simple.swift:62:3:62:3 | d | +| simple.swift:62:3:62:3 | &... | simple.swift:63:13:63:13 | d | +| simple.swift:62:3:62:3 | [post] &... | simple.swift:63:13:63:13 | d | +| simple.swift:62:3:62:3 | d | simple.swift:62:3:62:3 | &... | +| simple.swift:65:7:65:7 | SSA def(e) | simple.swift:66:3:66:3 | e | +| simple.swift:65:11:65:11 | 1000 | simple.swift:65:7:65:7 | SSA def(e) | +| simple.swift:66:3:66:3 | &... | simple.swift:67:13:67:13 | e | +| simple.swift:66:3:66:3 | [post] &... | simple.swift:67:13:67:13 | e | +| simple.swift:66:3:66:3 | e | simple.swift:66:3:66:3 | &... | +| simple.swift:67:13:67:13 | [post] e | simple.swift:68:3:68:3 | e | +| simple.swift:67:13:67:13 | e | simple.swift:68:3:68:3 | e | +| simple.swift:68:3:68:3 | &... | simple.swift:69:13:69:13 | e | +| simple.swift:68:3:68:3 | [post] &... | simple.swift:69:13:69:13 | e | +| simple.swift:68:3:68:3 | e | simple.swift:68:3:68:3 | &... | | string.swift:6:8:6:8 | SSA def(self) | string.swift:6:8:6:8 | self[return] | | string.swift:6:8:6:8 | self | string.swift:6:8:6:8 | SSA def(self) | | string.swift:10:3:10:3 | SSA def(self) | string.swift:10:3:10:27 | self[return] | diff --git a/swift/ql/test/library-tests/dataflow/taint/simple.swift b/swift/ql/test/library-tests/dataflow/taint/simple.swift new file mode 100644 index 000000000000..979415683713 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/simple.swift @@ -0,0 +1,70 @@ + +// --- stubs --- + +// --- tests --- + +func source() -> Int { return 0; } +func sink(arg: Any) {} + +func taintThroughArithmetic() { + // arithmetic + + sink(arg: 1 + source()) // $ MISSING: tainted= + sink(arg: source() + 1) // $ MISSING: tainted= + sink(arg: 1 - source()) // $ MISSING: tainted= + sink(arg: source() - 1) // $ MISSING: tainted= + sink(arg: 2 * source()) // $ MISSING: tainted= + sink(arg: source() * 2) // $ MISSING: tainted= + sink(arg: 100 / source()) // $ MISSING: tainted= + sink(arg: source() / 100) // $ MISSING: tainted= + sink(arg: 100 % source()) // $ MISSING: tainted= + sink(arg: source() % 100) // $ MISSING: tainted= + + sink(arg: -source()) // $ MISSING: tainted= + + // overflow operators + + sink(arg: 1 &+ source()) // $ MISSING: tainted= + sink(arg: source() &+ 1) // $ MISSING: tainted= + sink(arg: 1 &- source()) // $ MISSING: tainted= + sink(arg: source() &- 1) // $ MISSING: tainted= + sink(arg: 2 &* source()) // $ MISSING: tainted= + sink(arg: source() &* 2) // $ MISSING: tainted= +} + +func taintThroughAssignmentArithmetic() { + var a = 0 + sink(arg: a) + a += 1 + sink(arg: a) + a += source() + sink(arg: a) // $ MISSING: tainted= + a += 1 + sink(arg: a) // $ MISSING: tainted= + a = 0 + sink(arg: a) + + var b = 128 + b -= source() + sink(arg: b) // $ MISSING: tainted= + b -= 1 + sink(arg: b) // $ MISSING: tainted= + + var c = 10 + c *= source() + sink(arg: c) // $ MISSING: tainted= + c *= 2 + sink(arg: c) // $ MISSING: tainted= + + var d = 100 + d /= source() + sink(arg: d) // $ MISSING: tainted= + d /= 2 + sink(arg: d) // $ MISSING: tainted= + + var e = 1000 + e %= source() + sink(arg: e) // $ MISSING: tainted= + e %= 100 + sink(arg: e) // $ MISSING: tainted= +} From 9b117fefd7ef2eb64aecffb6417b2effae31b70d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 20 Feb 2023 16:23:39 +0000 Subject: [PATCH 2/2] Swift: Generalize the arithmetic we allow taint through. --- .../internal/TaintTrackingPrivate.qll | 8 +--- .../dataflow/taint/LocalTaint.expected | 21 +++++++++ .../dataflow/taint/Taint.expected | 44 +++++++++++++++++++ .../library-tests/dataflow/taint/simple.swift | 22 +++++----- 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index 6fdcca98c36b..911f44627a66 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -43,12 +43,8 @@ private module Cached { nodeFrom.asExpr() = interpolated.getAppendingExpr() ) or - // allow flow through string concatenation. - exists(AddExpr ae | - ae.getAnOperand() = nodeFrom.asExpr() and - ae = nodeTo.asExpr() and - ae.getType().getName() = "String" - ) + // allow flow through arithmetic (this case includes string concatenation) + nodeTo.asExpr().(ArithmeticOperation).getAnOperand() = nodeFrom.asExpr() or // flow through a subscript access exists(SubscriptExpr se | diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 9ceb0b4aa328..f6dd70752fae 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -557,6 +557,27 @@ | nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | | nsmutabledata.swift:48:33:48:40 | call to source() | nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes | +| simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... | +| simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | +| simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | +| simple.swift:13:24:13:24 | 1 | simple.swift:13:13:13:24 | ... .+(_:_:) ... | +| simple.swift:14:13:14:13 | 1 | simple.swift:14:13:14:24 | ... .-(_:_:) ... | +| simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... | +| simple.swift:15:13:15:20 | call to source() | simple.swift:15:13:15:24 | ... .-(_:_:) ... | +| simple.swift:15:24:15:24 | 1 | simple.swift:15:13:15:24 | ... .-(_:_:) ... | +| simple.swift:16:13:16:13 | 2 | simple.swift:16:13:16:24 | ... .*(_:_:) ... | +| simple.swift:16:17:16:24 | call to source() | simple.swift:16:13:16:24 | ... .*(_:_:) ... | +| simple.swift:17:13:17:20 | call to source() | simple.swift:17:13:17:24 | ... .*(_:_:) ... | +| simple.swift:17:24:17:24 | 2 | simple.swift:17:13:17:24 | ... .*(_:_:) ... | +| simple.swift:18:13:18:13 | 100 | simple.swift:18:13:18:26 | ... ./(_:_:) ... | +| simple.swift:18:19:18:26 | call to source() | simple.swift:18:13:18:26 | ... ./(_:_:) ... | +| simple.swift:19:13:19:20 | call to source() | simple.swift:19:13:19:24 | ... ./(_:_:) ... | +| simple.swift:19:24:19:24 | 100 | simple.swift:19:13:19:24 | ... ./(_:_:) ... | +| simple.swift:20:13:20:13 | 100 | simple.swift:20:13:20:26 | ... .%(_:_:) ... | +| simple.swift:20:19:20:26 | call to source() | simple.swift:20:13:20:26 | ... .%(_:_:) ... | +| simple.swift:21:13:21:20 | call to source() | simple.swift:21:13:21:24 | ... .%(_:_:) ... | +| simple.swift:21:24:21:24 | 100 | simple.swift:21:13:21:24 | ... .%(_:_:) ... | +| simple.swift:23:14:23:21 | call to source() | simple.swift:23:13:23:21 | call to -(_:) | | simple.swift:36:7:36:7 | SSA def(a) | simple.swift:37:13:37:13 | a | | simple.swift:36:11:36:11 | 0 | simple.swift:36:7:36:7 | SSA def(a) | | simple.swift:37:13:37:13 | [post] a | simple.swift:38:3:38:3 | a | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index fef44d98a5a3..1ea47a03460b 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -331,6 +331,17 @@ edges | nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:13:9:13:9 | self : | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | +| simple.swift:12:17:12:24 | call to source() : | simple.swift:12:13:12:24 | ... .+(_:_:) ... | +| simple.swift:13:13:13:20 | call to source() : | simple.swift:13:13:13:24 | ... .+(_:_:) ... | +| simple.swift:14:17:14:24 | call to source() : | simple.swift:14:13:14:24 | ... .-(_:_:) ... | +| simple.swift:15:13:15:20 | call to source() : | simple.swift:15:13:15:24 | ... .-(_:_:) ... | +| simple.swift:16:17:16:24 | call to source() : | simple.swift:16:13:16:24 | ... .*(_:_:) ... | +| simple.swift:17:13:17:20 | call to source() : | simple.swift:17:13:17:24 | ... .*(_:_:) ... | +| simple.swift:18:19:18:26 | call to source() : | simple.swift:18:13:18:26 | ... ./(_:_:) ... | +| simple.swift:19:13:19:20 | call to source() : | simple.swift:19:13:19:24 | ... ./(_:_:) ... | +| simple.swift:20:19:20:26 | call to source() : | simple.swift:20:13:20:26 | ... .%(_:_:) ... | +| simple.swift:21:13:21:20 | call to source() : | simple.swift:21:13:21:24 | ... .%(_:_:) ... | +| simple.swift:23:14:23:21 | call to source() : | simple.swift:23:13:23:21 | call to -(_:) | | string.swift:60:2:60:54 | [summary param] 0 in String.init(data:encoding:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(data:encoding:) : | | string.swift:64:3:64:63 | [summary param] 0 in String.init(format:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(format:_:) : | | string.swift:65:3:65:60 | [summary param] 0 in String.init(format:arguments:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(format:arguments:) : | @@ -1370,6 +1381,28 @@ nodes | nsmutabledata.swift:48:33:48:40 | call to source() : | semmle.label | call to source() : | | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | semmle.label | nsMutableDataTainted6 : | | nsmutabledata.swift:49:15:49:37 | .mutableBytes | semmle.label | .mutableBytes | +| simple.swift:12:13:12:24 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| simple.swift:12:17:12:24 | call to source() : | semmle.label | call to source() : | +| simple.swift:13:13:13:20 | call to source() : | semmle.label | call to source() : | +| simple.swift:13:13:13:24 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| simple.swift:14:13:14:24 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| simple.swift:14:17:14:24 | call to source() : | semmle.label | call to source() : | +| simple.swift:15:13:15:20 | call to source() : | semmle.label | call to source() : | +| simple.swift:15:13:15:24 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| simple.swift:16:13:16:24 | ... .*(_:_:) ... | semmle.label | ... .*(_:_:) ... | +| simple.swift:16:17:16:24 | call to source() : | semmle.label | call to source() : | +| simple.swift:17:13:17:20 | call to source() : | semmle.label | call to source() : | +| simple.swift:17:13:17:24 | ... .*(_:_:) ... | semmle.label | ... .*(_:_:) ... | +| simple.swift:18:13:18:26 | ... ./(_:_:) ... | semmle.label | ... ./(_:_:) ... | +| simple.swift:18:19:18:26 | call to source() : | semmle.label | call to source() : | +| simple.swift:19:13:19:20 | call to source() : | semmle.label | call to source() : | +| simple.swift:19:13:19:24 | ... ./(_:_:) ... | semmle.label | ... ./(_:_:) ... | +| simple.swift:20:13:20:26 | ... .%(_:_:) ... | semmle.label | ... .%(_:_:) ... | +| simple.swift:20:19:20:26 | call to source() : | semmle.label | call to source() : | +| simple.swift:21:13:21:20 | call to source() : | semmle.label | call to source() : | +| simple.swift:21:13:21:24 | ... .%(_:_:) ... | semmle.label | ... .%(_:_:) ... | +| simple.swift:23:13:23:21 | call to -(_:) | semmle.label | call to -(_:) | +| simple.swift:23:14:23:21 | call to source() : | semmle.label | call to source() : | | string.swift:60:2:60:54 | [summary param] 0 in String.init(data:encoding:) : | semmle.label | [summary param] 0 in String.init(data:encoding:) : | | string.swift:64:3:64:63 | [summary param] 0 in String.init(format:_:) : | semmle.label | [summary param] 0 in String.init(format:_:) : | | string.swift:65:3:65:60 | [summary param] 0 in String.init(format:arguments:) : | semmle.label | [summary param] 0 in String.init(format:arguments:) : | @@ -2084,6 +2117,17 @@ subpaths | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | result | | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | result | | nsmutabledata.swift:49:15:49:37 | .mutableBytes | nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | result | +| simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() : | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result | +| simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() : | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result | +| simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() : | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result | +| simple.swift:15:13:15:24 | ... .-(_:_:) ... | simple.swift:15:13:15:20 | call to source() : | simple.swift:15:13:15:24 | ... .-(_:_:) ... | result | +| simple.swift:16:13:16:24 | ... .*(_:_:) ... | simple.swift:16:17:16:24 | call to source() : | simple.swift:16:13:16:24 | ... .*(_:_:) ... | result | +| simple.swift:17:13:17:24 | ... .*(_:_:) ... | simple.swift:17:13:17:20 | call to source() : | simple.swift:17:13:17:24 | ... .*(_:_:) ... | result | +| simple.swift:18:13:18:26 | ... ./(_:_:) ... | simple.swift:18:19:18:26 | call to source() : | simple.swift:18:13:18:26 | ... ./(_:_:) ... | result | +| simple.swift:19:13:19:24 | ... ./(_:_:) ... | simple.swift:19:13:19:20 | call to source() : | simple.swift:19:13:19:24 | ... ./(_:_:) ... | result | +| simple.swift:20:13:20:26 | ... .%(_:_:) ... | simple.swift:20:19:20:26 | call to source() : | simple.swift:20:13:20:26 | ... .%(_:_:) ... | result | +| simple.swift:21:13:21:24 | ... .%(_:_:) ... | simple.swift:21:13:21:20 | call to source() : | simple.swift:21:13:21:24 | ... .%(_:_:) ... | result | +| simple.swift:23:13:23:21 | call to -(_:) | simple.swift:23:14:23:21 | call to source() : | simple.swift:23:13:23:21 | call to -(_:) | result | | string.swift:139:13:139:13 | "..." | string.swift:137:11:137:18 | call to source() : | string.swift:139:13:139:13 | "..." | result | | string.swift:141:13:141:13 | "..." | string.swift:137:11:137:18 | call to source() : | string.swift:141:13:141:13 | "..." | result | | string.swift:143:13:143:13 | "..." | string.swift:137:11:137:18 | call to source() : | string.swift:143:13:143:13 | "..." | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/simple.swift b/swift/ql/test/library-tests/dataflow/taint/simple.swift index 979415683713..8ede1e6eb0c1 100644 --- a/swift/ql/test/library-tests/dataflow/taint/simple.swift +++ b/swift/ql/test/library-tests/dataflow/taint/simple.swift @@ -9,18 +9,18 @@ func sink(arg: Any) {} func taintThroughArithmetic() { // arithmetic - sink(arg: 1 + source()) // $ MISSING: tainted= - sink(arg: source() + 1) // $ MISSING: tainted= - sink(arg: 1 - source()) // $ MISSING: tainted= - sink(arg: source() - 1) // $ MISSING: tainted= - sink(arg: 2 * source()) // $ MISSING: tainted= - sink(arg: source() * 2) // $ MISSING: tainted= - sink(arg: 100 / source()) // $ MISSING: tainted= - sink(arg: source() / 100) // $ MISSING: tainted= - sink(arg: 100 % source()) // $ MISSING: tainted= - sink(arg: source() % 100) // $ MISSING: tainted= + sink(arg: 1 + source()) // $ tainted=12 + sink(arg: source() + 1) // $ tainted=13 + sink(arg: 1 - source()) // $ tainted=14 + sink(arg: source() - 1) // $ tainted=15 + sink(arg: 2 * source()) // $ tainted=16 + sink(arg: source() * 2) // $ tainted=17 + sink(arg: 100 / source()) // $ tainted=18 + sink(arg: source() / 100) // $ tainted=19 + sink(arg: 100 % source()) // $ tainted=20 + sink(arg: source() % 100) // $ tainted=21 - sink(arg: -source()) // $ MISSING: tainted= + sink(arg: -source()) // $ tainted=23 // overflow operators