Skip to content

Commit ceed0c3

Browse files
authored
Merge pull request #3 from adrienpessu/adrienpessu-vue-toref-computed-tests
Add Vue toRef value-flow and computed object-overload tests
2 parents f329988 + 0f8f884 commit ceed0c3

4 files changed

Lines changed: 23 additions & 13 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: summaryModel
5+
data:
6+
# `computed(() => ...)` — function overload: the getter's return value flows to `.value`.
7+
- ["vue", "Member[computed]", "Argument[0].ReturnValue", "ReturnValue.Member[value]", "value"]
8+
# `computed({ get() { ... } })` — object overload: the `get` getter's return value flows to `.value`.
9+
- ["vue", "Member[computed]", "Argument[0].Member[get].ReturnValue", "ReturnValue.Member[value]", "value"]

javascript/ql/lib/semmle/javascript/frameworks/Vue.qll

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,36 +35,33 @@ module Vue {
3535
result = any(GlobalVueEntryPoint e).getANode()
3636
}
3737

38-
/** Models data flow through Vue Composition API helpers. */
38+
/**
39+
* Models data flow through Vue Composition API helpers.
40+
*
41+
* Note that `computed` is not modeled here but in the `vue.model.yml` data
42+
* extension, because its object overload (`computed({ get() { ... } })`)
43+
* requires callback flow synthesis that data extensions support but a
44+
* hand-written `SummarizedCallable` does not.
45+
*/
3946
overlay[local?]
4047
private class VueCompositionApiSummary extends DataFlow::SummarizedCallable::Range {
4148
string name;
4249

4350
VueCompositionApiSummary() {
44-
name = ["ref", "shallowRef", "toRef", "reactive", "computed"] and
51+
name = ["ref", "shallowRef", "toRef", "reactive"] and
4552
this = "vue." + name
4653
}
4754

4855
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
49-
name = ["ref", "shallowRef"] and
56+
name = ["ref", "shallowRef", "toRef"] and
5057
input = "Argument[0]" and
5158
output = "ReturnValue.Member[value]" and
5259
preservesValue = true
5360
or
54-
name = "toRef" and
55-
input = "Argument[0]" and
56-
output = "ReturnValue.Member[value]" and
57-
preservesValue = false
58-
or
5961
name = "reactive" and
6062
input = "Argument[0]" and
6163
output = "ReturnValue" and
6264
preservesValue = false
63-
or
64-
name = "computed" and
65-
input = "Argument[0].ReturnValue" and
66-
output = "ReturnValue.Member[value]" and
67-
preservesValue = true
6865
}
6966

7067
override DataFlow::InvokeNode getACall() {

javascript/ql/test/library-tests/frameworks/Vue/tests.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,13 @@ threatModelSource
251251
compositionApiDataFlow
252252
| tst.js:119:14:119:26 | source("ref") | tst.js:119:6:119:33 | Vue.ref ... ).value |
253253
| tst.js:120:21:120:40 | source("shallowRef") | tst.js:120:6:120:47 | Vue.sha ... ).value |
254+
| tst.js:121:16:121:30 | source("toRef") | tst.js:121:6:121:37 | Vue.toR ... ).value |
254255
| tst.js:123:25:123:42 | source("computed") | tst.js:123:6:123:49 | Vue.com ... ).value |
256+
| tst.js:124:36:124:59 | source( ... bject") | tst.js:124:6:124:82 | Vue.com ... ).value |
255257
compositionApiTaintFlow
256258
| tst.js:119:14:119:26 | source("ref") | tst.js:119:6:119:33 | Vue.ref ... ).value |
257259
| tst.js:120:21:120:40 | source("shallowRef") | tst.js:120:6:120:47 | Vue.sha ... ).value |
258260
| tst.js:121:16:121:30 | source("toRef") | tst.js:121:6:121:37 | Vue.toR ... ).value |
259261
| tst.js:122:19:122:36 | source("reactive") | tst.js:122:6:122:37 | Vue.rea ... tive")) |
260262
| tst.js:123:25:123:42 | source("computed") | tst.js:123:6:123:49 | Vue.com ... ).value |
263+
| tst.js:124:36:124:59 | source( ... bject") | tst.js:124:6:124:82 | Vue.com ... ).value |

javascript/ql/test/library-tests/frameworks/Vue/tst.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,4 @@ sink(Vue.shallowRef(source("shallowRef")).value);
121121
sink(Vue.toRef(source("toRef")).value);
122122
sink(Vue.reactive(source("reactive")));
123123
sink(Vue.computed(() => source("computed")).value);
124+
sink(Vue.computed({ get() { return source("computedObject"); }, set(v) {} }).value);

0 commit comments

Comments
 (0)