mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
JS: add query js/vue/arrow-method-on-vue-instance
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
| **Query** | **Tags** | **Purpose** |
|
| **Query** | **Tags** | **Purpose** |
|
||||||
|-----------------------------------------------|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------------------------------------------|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| Arrow method on Vue instance (`js/vue/arrow-method-on-vue-instance`) | reliability, frameworks/vue | Highlights arrow functions that are used as methods on Vue instances. Results are shown on LGTM by default.|
|
||||||
| Double escaping or unescaping (`js/double-escaping`) | correctness, security, external/cwe/cwe-116 | Highlights potential double escaping or unescaping of special characters, indicating a possible violation of [CWE-116](https://cwe.mitre.org/data/definitions/116.html). Results are shown on LGTM by default. |
|
| Double escaping or unescaping (`js/double-escaping`) | correctness, security, external/cwe/cwe-116 | Highlights potential double escaping or unescaping of special characters, indicating a possible violation of [CWE-116](https://cwe.mitre.org/data/definitions/116.html). Results are shown on LGTM by default. |
|
||||||
| Incomplete regular expression for hostnames (`js/incomplete-hostname-regexp`) | correctness, security, external/cwe/cwe-020 | Highlights hostname sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default.|
|
| Incomplete regular expression for hostnames (`js/incomplete-hostname-regexp`) | correctness, security, external/cwe/cwe-020 | Highlights hostname sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default.|
|
||||||
| Incomplete URL substring sanitization | correctness, security, external/cwe/cwe-020 | Highlights URL sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results shown on LGTM by default. |
|
| Incomplete URL substring sanitization | correctness, security, external/cwe/cwe-020 | Highlights URL sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results shown on LGTM by default. |
|
||||||
|
|||||||
@@ -23,3 +23,4 @@
|
|||||||
+ semmlecode-javascript-queries/React/UnusedOrUndefinedStateProperty.ql: /Frameworks/React
|
+ semmlecode-javascript-queries/React/UnusedOrUndefinedStateProperty.ql: /Frameworks/React
|
||||||
+ semmlecode-javascript-queries/Electron/DisablingWebSecurity.ql: /Frameworks/Electron
|
+ semmlecode-javascript-queries/Electron/DisablingWebSecurity.ql: /Frameworks/Electron
|
||||||
+ semmlecode-javascript-queries/Electron/AllowRunningInsecureContent.ql: /Frameworks/Electron
|
+ semmlecode-javascript-queries/Electron/AllowRunningInsecureContent.ql: /Frameworks/Electron
|
||||||
|
+ semmlecode-javascript-queries/Vue/ArrowMethodOnVueInstance.ql: /Frameworks/Vue
|
||||||
|
|||||||
49
javascript/ql/src/Vue/ArrowMethodOnVueInstance.qhelp
Normal file
49
javascript/ql/src/Vue/ArrowMethodOnVueInstance.qhelp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE qhelp PUBLIC
|
||||||
|
"-//Semmle//qhelp//EN"
|
||||||
|
"qhelp.dtd">
|
||||||
|
<qhelp>
|
||||||
|
|
||||||
|
<overview>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
The Vue framework invokes the methods of a Vue instance with
|
||||||
|
the instance as the receiver. It is however impossible to perform
|
||||||
|
this binding of instance and receiver for arrow functions, so the
|
||||||
|
<code>this</code> variable in an arrow function on a Vue instance may
|
||||||
|
not have the value that the programmer expects.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</overview>
|
||||||
|
|
||||||
|
<recommendation>
|
||||||
|
<p>
|
||||||
|
Ensure that the methods on a Vue instance can have their receiver bound to the instance.
|
||||||
|
</p>
|
||||||
|
</recommendation>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
The following example shows two similar Vue instances, the only
|
||||||
|
difference is how the <code>created</code> life cycle hook
|
||||||
|
callback is defined.
|
||||||
|
|
||||||
|
The first Vue instance uses an arrow function as the callback.
|
||||||
|
This means that the <code>this</code> variable will have the global
|
||||||
|
object as its value, causing <code>this.myProperty</code> to evaluate
|
||||||
|
to <code>undefined</code>, which may not be intended.
|
||||||
|
|
||||||
|
Instead, the second Vue instance uses an ordinary function as the callback,
|
||||||
|
causing <code>this.myProperty</code> to evaluate to <code>42</code>.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<sample src="examples/ArrowMethodOnVueInstance.js"/>
|
||||||
|
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<references>
|
||||||
|
<li>Vue documentation: <a href="https://vuejs.org/v2/guide/instance.html">The Vue Instance</a></li>
|
||||||
|
</references>
|
||||||
|
</qhelp>
|
||||||
19
javascript/ql/src/Vue/ArrowMethodOnVueInstance.ql
Normal file
19
javascript/ql/src/Vue/ArrowMethodOnVueInstance.ql
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* @name Arrow method on Vue instance
|
||||||
|
* @description An arrow method on a Vue instance doesn't have its `this` variable bound to the Vue instance.
|
||||||
|
* @kind problem
|
||||||
|
* @problem.severity warning
|
||||||
|
* @id js/vue/arrow-method-on-vue-instance
|
||||||
|
* @tags reliability
|
||||||
|
* frameworks/vue
|
||||||
|
* @precision high
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javascript
|
||||||
|
|
||||||
|
from Vue::Instance instance, DataFlow::Node def, DataFlow::FunctionNode arrow, ThisExpr dis
|
||||||
|
where instance.getABoundFunction() = def and
|
||||||
|
arrow.flowsTo(def) and
|
||||||
|
arrow.asExpr() instanceof ArrowFunctionExpr and
|
||||||
|
arrow.asExpr() = dis.getEnclosingFunction()
|
||||||
|
select def, "The $@ of this $@ it will not be bound to the Vue instance.", dis, "`this` variable", arrow, "arrow function"
|
||||||
19
javascript/ql/src/Vue/examples/ArrowMethodOnVueInstance.js
Normal file
19
javascript/ql/src/Vue/examples/ArrowMethodOnVueInstance.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
new Vue({
|
||||||
|
data: {
|
||||||
|
myProperty: 42
|
||||||
|
},
|
||||||
|
created: () => {
|
||||||
|
// BAD: prints: "myProperty is: undefined"
|
||||||
|
console.log('myProperty is: ' + this.myProperty);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
data: {
|
||||||
|
myProperty: 42
|
||||||
|
},
|
||||||
|
created: function () {
|
||||||
|
// GOOD: prints: "myProperty is: 1"
|
||||||
|
console.log('myProperty is: ' + this.myProperty);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
| tst.js:4:11:4:20 | () => this | The $@ of this $@ it will not be bound to the Vue instance. | tst.js:4:17:4:20 | this | `this` variable | tst.js:4:11:4:20 | () => this | arrow function |
|
||||||
|
| tst.js:6:6:6:15 | () => this | The $@ of this $@ it will not be bound to the Vue instance. | tst.js:6:12:6:15 | this | `this` variable | tst.js:6:6:6:15 | () => this | arrow function |
|
||||||
|
| tst.js:7:13:7:22 | () => this | The $@ of this $@ it will not be bound to the Vue instance. | tst.js:7:19:7:22 | this | `this` variable | tst.js:7:13:7:22 | () => this | arrow function |
|
||||||
|
| tst.js:8:13:8:22 | () => this | The $@ of this $@ it will not be bound to the Vue instance. | tst.js:8:19:8:22 | this | `this` variable | tst.js:8:13:8:22 | () => this | arrow function |
|
||||||
|
| tst.js:11:10:11:19 | () => this | The $@ of this $@ it will not be bound to the Vue instance. | tst.js:11:16:11:19 | this | `this` variable | tst.js:11:10:11:19 | () => this | arrow function |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Vue/ArrowMethodOnVueInstance.ql
|
||||||
16
javascript/ql/test/query-tests/Vue/tst.js
Normal file
16
javascript/ql/test/query-tests/Vue/tst.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
let Vue = require('vue');
|
||||||
|
|
||||||
|
new Vue( {
|
||||||
|
created: () => this, // NOT OK
|
||||||
|
computed: {
|
||||||
|
x: () => this, // NOT OK
|
||||||
|
y: { get: () => this }, // NOT OK
|
||||||
|
z: { set: () => this } // NOT OK
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
arrow: () => this, // NOT OK
|
||||||
|
nonArrow: function() { this; }, // OK
|
||||||
|
arrowWithoutThis: () => 42, // OK
|
||||||
|
arrowWithNestedThis: () => (() => this) // OK
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user