Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f60a748

Browse files
committed
ignore parents that doesn't have all constant roots when deciding which roots to compute getStringValue for
1 parent bbdeca3 commit f60a748

4 files changed

Lines changed: 95 additions & 5 deletions

File tree

javascript/ql/src/semmle/javascript/Expr.qll

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,17 +1545,24 @@ private string getConstantString(Expr e) {
15451545
result = e.(TemplateElement).getValue()
15461546
}
15471547

1548+
/**
1549+
* Holds if `add` is a string-concatenation where all the transitive leafs have a constant string value.
1550+
*/
1551+
private predicate hasAllConstantLeafs(AddExpr add) {
1552+
forex(Expr leaf | leaf = getAnAddOperand*(add) and not exists(getAnAddOperand(leaf)) |
1553+
exists(getConstantString(leaf))
1554+
)
1555+
}
1556+
15481557
/**
15491558
* Gets the concatenated string for a string-concatenation `add`.
1550-
* Only has a result if `add` is not itself an operand in another string-concatenation.
1559+
* Only has a result if `add` is not itself an operand in another string-concatenation with all constant leafs.
15511560
*/
15521561
private string getConcatenatedString(Expr add) {
15531562
result = getConcatenatedString(add.getUnderlyingValue())
15541563
or
1555-
not add = getAnAddOperand(_) and
1556-
forex(Expr leaf | leaf = getAnAddOperand*(add) and not exists(getAnAddOperand(leaf)) |
1557-
exists(getConstantString(leaf))
1558-
) and
1564+
not add = getAnAddOperand(any(AddExpr parent | hasAllConstantLeafs(parent))) and
1565+
hasAllConstantLeafs(add) and
15591566
result =
15601567
strictconcat(Expr leaf |
15611568
leaf = getAnAddOperand*(add)

javascript/ql/test/library-tests/StringConcatenation/StringOps.expected

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ concatenation
4646
| tst.js:89:3:89:14 | x |
4747
| tst.js:89:3:89:14 | x += 'three' |
4848
| tst.js:95:7:95:30 | x.conca ... three') |
49+
| tst.js:104:11:104:23 | "foo" + "bar" |
50+
| tst.js:104:11:104:31 | "foo" + ... + value |
51+
| tst.js:105:11:105:23 | value + "foo" |
52+
| tst.js:105:11:105:31 | value + ... + "bar" |
53+
| tst.js:106:11:106:33 | "foo" + ... "baz") |
54+
| tst.js:106:20:106:32 | "bar" + "baz" |
4955
concatenationOperand
5056
| closure.js:5:1:5:37 | build(' ... 'four') |
5157
| closure.js:5:7:5:11 | 'one' |
@@ -127,6 +133,18 @@ concatenationOperand
127133
| tst.js:95:7:95:7 | x |
128134
| tst.js:95:16:95:20 | 'two' |
129135
| tst.js:95:23:95:29 | 'three' |
136+
| tst.js:104:11:104:15 | "foo" |
137+
| tst.js:104:11:104:23 | "foo" + "bar" |
138+
| tst.js:104:19:104:23 | "bar" |
139+
| tst.js:104:27:104:31 | value |
140+
| tst.js:105:11:105:15 | value |
141+
| tst.js:105:11:105:23 | value + "foo" |
142+
| tst.js:105:19:105:23 | "foo" |
143+
| tst.js:105:27:105:31 | "bar" |
144+
| tst.js:106:11:106:15 | "foo" |
145+
| tst.js:106:19:106:33 | ("bar" + "baz") |
146+
| tst.js:106:20:106:24 | "bar" |
147+
| tst.js:106:28:106:32 | "baz" |
130148
concatenationLeaf
131149
| closure.js:5:7:5:11 | 'one' |
132150
| closure.js:5:14:5:18 | 'two' |
@@ -199,6 +217,16 @@ concatenationLeaf
199217
| tst.js:95:7:95:7 | x |
200218
| tst.js:95:16:95:20 | 'two' |
201219
| tst.js:95:23:95:29 | 'three' |
220+
| tst.js:104:11:104:15 | "foo" |
221+
| tst.js:104:19:104:23 | "bar" |
222+
| tst.js:104:27:104:31 | value |
223+
| tst.js:105:11:105:15 | value |
224+
| tst.js:105:19:105:23 | "foo" |
225+
| tst.js:105:27:105:31 | "bar" |
226+
| tst.js:106:11:106:15 | "foo" |
227+
| tst.js:106:19:106:33 | ("bar" + "baz") |
228+
| tst.js:106:20:106:24 | "bar" |
229+
| tst.js:106:28:106:32 | "baz" |
202230
concatenationNode
203231
| closure.js:5:1:5:37 | build(' ... 'four') |
204232
| closure.js:5:1:5:46 | build(' ... 'five' |
@@ -318,6 +346,22 @@ concatenationNode
318346
| tst.js:95:7:95:30 | x.conca ... three') |
319347
| tst.js:95:16:95:20 | 'two' |
320348
| tst.js:95:23:95:29 | 'three' |
349+
| tst.js:104:11:104:15 | "foo" |
350+
| tst.js:104:11:104:23 | "foo" + "bar" |
351+
| tst.js:104:11:104:31 | "foo" + ... + value |
352+
| tst.js:104:19:104:23 | "bar" |
353+
| tst.js:104:27:104:31 | value |
354+
| tst.js:105:11:105:15 | value |
355+
| tst.js:105:11:105:23 | value + "foo" |
356+
| tst.js:105:11:105:31 | value + ... + "bar" |
357+
| tst.js:105:19:105:23 | "foo" |
358+
| tst.js:105:27:105:31 | "bar" |
359+
| tst.js:106:11:106:15 | "foo" |
360+
| tst.js:106:11:106:33 | "foo" + ... "baz") |
361+
| tst.js:106:19:106:33 | ("bar" + "baz") |
362+
| tst.js:106:20:106:24 | "bar" |
363+
| tst.js:106:20:106:32 | "bar" + "baz" |
364+
| tst.js:106:28:106:32 | "baz" |
321365
operand
322366
| closure.js:5:1:5:37 | build(' ... 'four') | 0 | closure.js:5:7:5:11 | 'one' |
323367
| closure.js:5:1:5:37 | build(' ... 'four') | 1 | closure.js:5:14:5:28 | 'two' + 'three' |
@@ -421,6 +465,18 @@ operand
421465
| tst.js:95:7:95:30 | x.conca ... three') | 0 | tst.js:95:7:95:7 | x |
422466
| tst.js:95:7:95:30 | x.conca ... three') | 1 | tst.js:95:16:95:20 | 'two' |
423467
| tst.js:95:7:95:30 | x.conca ... three') | 2 | tst.js:95:23:95:29 | 'three' |
468+
| tst.js:104:11:104:23 | "foo" + "bar" | 0 | tst.js:104:11:104:15 | "foo" |
469+
| tst.js:104:11:104:23 | "foo" + "bar" | 1 | tst.js:104:19:104:23 | "bar" |
470+
| tst.js:104:11:104:31 | "foo" + ... + value | 0 | tst.js:104:11:104:23 | "foo" + "bar" |
471+
| tst.js:104:11:104:31 | "foo" + ... + value | 1 | tst.js:104:27:104:31 | value |
472+
| tst.js:105:11:105:23 | value + "foo" | 0 | tst.js:105:11:105:15 | value |
473+
| tst.js:105:11:105:23 | value + "foo" | 1 | tst.js:105:19:105:23 | "foo" |
474+
| tst.js:105:11:105:31 | value + ... + "bar" | 0 | tst.js:105:11:105:23 | value + "foo" |
475+
| tst.js:105:11:105:31 | value + ... + "bar" | 1 | tst.js:105:27:105:31 | "bar" |
476+
| tst.js:106:11:106:33 | "foo" + ... "baz") | 0 | tst.js:106:11:106:15 | "foo" |
477+
| tst.js:106:11:106:33 | "foo" + ... "baz") | 1 | tst.js:106:19:106:33 | ("bar" + "baz") |
478+
| tst.js:106:20:106:32 | "bar" + "baz" | 0 | tst.js:106:20:106:24 | "bar" |
479+
| tst.js:106:20:106:32 | "bar" + "baz" | 1 | tst.js:106:28:106:32 | "baz" |
424480
nextLeaf
425481
| closure.js:5:7:5:11 | 'one' | closure.js:5:14:5:18 | 'two' |
426482
| closure.js:5:14:5:18 | 'two' | closure.js:5:22:5:28 | 'three' |
@@ -466,6 +522,12 @@ nextLeaf
466522
| tst.js:89:3:89:3 | x | tst.js:89:8:89:14 | 'three' |
467523
| tst.js:95:7:95:7 | x | tst.js:95:16:95:20 | 'two' |
468524
| tst.js:95:16:95:20 | 'two' | tst.js:95:23:95:29 | 'three' |
525+
| tst.js:104:11:104:15 | "foo" | tst.js:104:19:104:23 | "bar" |
526+
| tst.js:104:19:104:23 | "bar" | tst.js:104:27:104:31 | value |
527+
| tst.js:105:11:105:15 | value | tst.js:105:19:105:23 | "foo" |
528+
| tst.js:105:19:105:23 | "foo" | tst.js:105:27:105:31 | "bar" |
529+
| tst.js:106:11:106:15 | "foo" | tst.js:106:19:106:33 | ("bar" + "baz") |
530+
| tst.js:106:20:106:24 | "bar" | tst.js:106:28:106:32 | "baz" |
469531
htmlRoot
470532
| html-concat.js:2:14:2:26 | `<b>${x}</b>` |
471533
| html-concat.js:3:14:3:26 | `<B>${x}</B>` |
@@ -488,3 +550,13 @@ htmlLeaf
488550
| html-concat.js:8:15:10:23 | .\\n \\n ... um!</i> |
489551
| html-concat.js:13:3:13:8 | buffer |
490552
| html-concat.js:13:13:13:18 | '<li>' |
553+
getStringValue
554+
| tst.js:104:11:104:15 | "foo" | foo |
555+
| tst.js:104:11:104:23 | "foo" + "bar" | foobar |
556+
| tst.js:104:19:104:23 | "bar" | bar |
557+
| tst.js:105:19:105:23 | "foo" | foo |
558+
| tst.js:105:27:105:31 | "bar" | bar |
559+
| tst.js:106:11:106:15 | "foo" | foo |
560+
| tst.js:106:11:106:33 | "foo" + ... "baz") | foobarbaz |
561+
| tst.js:106:20:106:24 | "bar" | bar |
562+
| tst.js:106:28:106:32 | "baz" | baz |

javascript/ql/test/library-tests/StringConcatenation/StringOps.ql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ query predicate nextLeaf(StringOps::ConcatenationNode node, DataFlow::Node next)
1919
query StringOps::HtmlConcatenationRoot htmlRoot() { any() }
2020

2121
query StringOps::HtmlConcatenationLeaf htmlLeaf() { any() }
22+
23+
query string getStringValue(Expr e) {
24+
result = e.getStringValue() and
25+
e.getEnclosingFunction().getName() = "stringValue"
26+
}

javascript/ql/test/library-tests/StringConcatenation/tst.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,9 @@ function concatCall() {
9999
function arrayConcat(a, b) {
100100
return [].concat(a, b);
101101
}
102+
103+
function stringValue() {
104+
var a = "foo" + "bar" + value;
105+
var b = value + "foo" + "bar";
106+
var c = "foo" + ("bar" + "baz")
107+
}

0 commit comments

Comments
 (0)