mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
JavaScript: Fix exported name of default re-exports.
A default re-export (not part of the standard yet) looks like this: ``` export f from 'mod'; ``` What this means is that the default export of `mod` is re-exported under the name `f`. Default re-export specifiers (like `f` in this example) are modelled as a kind of default export specifier in our library, but unlike normal default export specifiers they do not export the name `default`. This was previously not modelled correctly, leading to surprising errors down the line, for example in type inference where we suddenly would no longer be able to resolve an import that otherwise looked resolvable.
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
|
||||
* Modelling of global variables has been improved. This may give more true-positive results and fewer false-positive results for a variety of queries.
|
||||
|
||||
* Modelling of re-export declarations has been improved. This may result in fewer false-positive results for a variety of queries.
|
||||
|
||||
* Modelling of taint flow through the array operations `map` and `join` has been improved. This may give additional results for the security queries.
|
||||
|
||||
* Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following libraries:
|
||||
|
||||
@@ -428,22 +428,39 @@ class ExportSpecifier extends Expr, @exportspecifier {
|
||||
string getExportedName() { result = getExported().getName() }
|
||||
}
|
||||
|
||||
/** A named export specifier. */
|
||||
/**
|
||||
* A named export specifier, for example `v` in `export { v }`.
|
||||
*/
|
||||
class NamedExportSpecifier extends ExportSpecifier, @namedexportspecifier {
|
||||
}
|
||||
|
||||
/** A default export specifier. */
|
||||
/**
|
||||
* A default export specifier, for example `default` in `export default 42`,
|
||||
* or `v` in `export v from "mod"`.
|
||||
*/
|
||||
class ExportDefaultSpecifier extends ExportSpecifier, @exportdefaultspecifier {
|
||||
override string getLocalName() {
|
||||
getExportDeclaration() instanceof ReExportDeclaration and result = "default"
|
||||
}
|
||||
|
||||
override string getExportedName() {
|
||||
result = "default"
|
||||
}
|
||||
}
|
||||
|
||||
/** A namespace export specifier. */
|
||||
/**
|
||||
* A default export specifier in a re-export declaration, for example `v` in
|
||||
* `export v from "mod"`.
|
||||
*/
|
||||
class ReExportDefaultSpecifier extends ExportDefaultSpecifier {
|
||||
ReExportDefaultSpecifier() {
|
||||
getExportDeclaration() instanceof ReExportDeclaration
|
||||
}
|
||||
|
||||
override string getLocalName() { result = "default" }
|
||||
|
||||
override string getExportedName() { result = getExported().getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A namespace export specifier, for example `*` in `export * from "mod"`.
|
||||
*/
|
||||
class ExportNamespaceSpecifier extends ExportSpecifier, @exportnamespacespecifier {
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,12 @@
|
||||
| reexport-mixins.js:1:1:4:0 | module object of module reexport-mixins |
|
||||
| reexport-unknown.js:1:1:2:0 | exports object of module reexport-unknown |
|
||||
| reexport-unknown.js:1:1:2:0 | module object of module reexport-unknown |
|
||||
| reexport/client/src/index.js:1:1:3:0 | exports object of module index |
|
||||
| reexport/client/src/index.js:1:1:3:0 | module object of module index |
|
||||
| reexport/lib/index.js:1:1:4:0 | exports object of module index |
|
||||
| reexport/lib/index.js:1:1:4:0 | module object of module index |
|
||||
| reexport/lib/src/utils/util.js:1:1:3:0 | exports object of module util |
|
||||
| reexport/lib/src/utils/util.js:1:1:3:0 | module object of module util |
|
||||
| refinements.js:1:1:8:1 | function f1 |
|
||||
| refinements.js:1:1:8:1 | instance of function f1 |
|
||||
| refinements.js:10:1:24:1 | function f2 |
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
| objlit.js:38:11:38:12 | x6 | objlit.js:38:16:38:21 | this.h | file://:0:0:0:0 | indefinite value (heap) |
|
||||
| objlit.js:38:11:38:12 | x6 | objlit.js:38:16:38:21 | this.h | objlit.js:41:10:41:22 | anonymous function |
|
||||
| objlit.js:43:7:43:8 | o3 | objlit.js:43:12:45:3 | {\\n _ ... o2\\n } | objlit.js:43:12:45:3 | object literal |
|
||||
| reexport/client/src/index.js:2:5:2:8 | test | reexport/client/src/index.js:2:12:2:15 | data | file://:0:0:0:0 | non-empty, non-numeric string |
|
||||
| refinements.js:3:7:3:8 | x1 | refinements.js:3:12:3:12 | g | file://:0:0:0:0 | undefined |
|
||||
| refinements.js:7:7:7:8 | x3 | refinements.js:7:12:7:12 | g | file://:0:0:0:0 | undefined |
|
||||
| refinements.js:11:7:11:7 | a | refinements.js:11:11:11:72 | Math.ra ... ' : 42) | file://:0:0:0:0 | non-empty, non-numeric string |
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
import { data } from '../../lib';
|
||||
var test = data;
|
||||
@@ -0,0 +1,3 @@
|
||||
export data from './src/utils/util'
|
||||
|
||||
// semmle-extractor-options: --experimental
|
||||
@@ -0,0 +1,2 @@
|
||||
export default "data";
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
| objlit.js:37:11:37:12 | x5 | objlit.js:37:16:37:21 | this.f | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
| objlit.js:38:11:38:12 | x6 | objlit.js:38:16:38:21 | this.h | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
| objlit.js:43:7:43:8 | o3 | objlit.js:43:12:45:3 | {\\n _ ... o2\\n } | object |
|
||||
| reexport/client/src/index.js:2:5:2:8 | test | reexport/client/src/index.js:2:12:2:15 | data | string |
|
||||
| refinements.js:3:7:3:8 | x1 | refinements.js:3:12:3:12 | g | undefined |
|
||||
| refinements.js:5:9:5:10 | x2 | refinements.js:5:14:5:14 | g | |
|
||||
| refinements.js:7:7:7:8 | x3 | refinements.js:7:12:7:12 | g | undefined |
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
| a.js:1:1:3:1 | export ... n 23;\\n} |
|
||||
| a.js:5:1:5:32 | export ... } = o; |
|
||||
| b.js:5:1:5:18 | export { f as g }; |
|
||||
| b.js:7:1:7:21 | export ... './a'; |
|
||||
| d.js:4:1:4:20 | export * from 'm/c'; |
|
||||
| e.js:2:1:2:16 | export { x, y }; |
|
||||
| e.js:3:1:3:35 | export ... './a'; |
|
||||
| es2015_require.js:3:1:3:25 | export ... ss C {} |
|
||||
| export-in-mjs.mjs:1:1:1:34 | export ... s = 42; |
|
||||
| f.ts:5:1:5:24 | export ... oo() {} |
|
||||
| m/c.js:5:1:5:30 | export ... '../b'; |
|
||||
| tst.html:7:3:7:22 | export const y = 42; |
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
| e.js:2:10:2:10 | x | e.js:2:10:2:10 | x | e.js:2:10:2:10 | x |
|
||||
| e.js:2:13:2:13 | y | e.js:2:13:2:13 | y | e.js:2:13:2:13 | y |
|
||||
| e.js:3:10:3:21 | default as g | e.js:3:10:3:16 | default | e.js:3:21:3:21 | g |
|
||||
| m/c.js:5:10:5:15 | g as h | m/c.js:5:10:5:10 | g | m/c.js:5:15:5:15 | h |
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
| a.js:1:1:5:32 | <toplevel> | default | a.js:1:1:3:1 | export ... n 23;\\n} |
|
||||
| a.js:1:1:5:32 | <toplevel> | x | a.js:5:1:5:32 | export ... } = o; |
|
||||
| a.js:1:1:5:32 | <toplevel> | y | a.js:5:1:5:32 | export ... } = o; |
|
||||
| b.js:1:1:6:0 | <toplevel> | g | b.js:5:1:5:18 | export { f as g }; |
|
||||
| b.js:1:1:10:0 | <toplevel> | f2 | b.js:7:1:7:21 | export ... './a'; |
|
||||
| b.js:1:1:10:0 | <toplevel> | g | b.js:5:1:5:18 | export { f as g }; |
|
||||
| e.js:1:1:4:0 | <toplevel> | g | e.js:3:1:3:35 | export ... './a'; |
|
||||
| e.js:1:1:4:0 | <toplevel> | x | e.js:2:1:2:16 | export { x, y }; |
|
||||
| e.js:1:1:4:0 | <toplevel> | y | e.js:2:1:2:16 | export { x, y }; |
|
||||
| es2015_require.js:1:1:3:25 | <toplevel> | default | es2015_require.js:3:1:3:25 | export ... ss C {} |
|
||||
| export-in-mjs.mjs:1:1:1:34 | <toplevel> | exported_from_mjs | export-in-mjs.mjs:1:1:1:34 | export ... s = 42; |
|
||||
| f.ts:1:1:6:0 | <toplevel> | foo | f.ts:5:1:5:24 | export ... oo() {} |
|
||||
| m/c.js:1:1:8:0 | <toplevel> | h | m/c.js:5:1:5:30 | export ... '../b'; |
|
||||
| tst.html:4:23:8:0 | <toplevel> | y | tst.html:7:3:7:22 | export const y = 42; |
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
| b.js:7:1:7:21 | export ... './a'; | b.js:7:16:7:20 | './a' |
|
||||
| d.js:4:1:4:20 | export * from 'm/c'; | d.js:4:15:4:19 | 'm/c' |
|
||||
| e.js:3:1:3:35 | export ... './a'; | e.js:3:30:3:34 | './a' |
|
||||
| m/c.js:5:1:5:30 | export ... '../b'; | m/c.js:5:24:5:29 | '../b' |
|
||||
|
||||
@@ -3,3 +3,7 @@ import f from './a';
|
||||
f();
|
||||
|
||||
export { f as g };
|
||||
|
||||
export f2 from './a';
|
||||
|
||||
// semmle-extractor-options: --experimental
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
| b.js:5:10:5:15 | f as g | f |
|
||||
| b.js:7:8:7:9 | f2 | default |
|
||||
| e.js:2:10:2:10 | x | x |
|
||||
| e.js:2:13:2:13 | y | y |
|
||||
| e.js:3:10:3:21 | default as g | default |
|
||||
| m/c.js:5:10:5:15 | g as h | g |
|
||||
@@ -0,0 +1,4 @@
|
||||
import javascript
|
||||
|
||||
from ExportSpecifier es
|
||||
select es, es.getLocalName()
|
||||
@@ -0,0 +1,6 @@
|
||||
| b.js:5:10:5:15 | f as g | f |
|
||||
| b.js:7:8:7:9 | f2 | default |
|
||||
| e.js:2:10:2:10 | x | x |
|
||||
| e.js:2:13:2:13 | y | y |
|
||||
| e.js:3:10:3:21 | default as g | default |
|
||||
| m/c.js:5:10:5:15 | g as h | g |
|
||||
4
javascript/ql/test/library-tests/Modules/getLocalName.ql
Normal file
4
javascript/ql/test/library-tests/Modules/getLocalName.ql
Normal file
@@ -0,0 +1,4 @@
|
||||
import javascript
|
||||
|
||||
from ExportSpecifier es
|
||||
select es, es.getLocalName()
|
||||
@@ -1,10 +1,12 @@
|
||||
| a.js:1:1:3:1 | export ... n 23;\\n} | default | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
| a.js:5:1:5:32 | export ... } = o; | x | a.js:5:18:5:20 | f() |
|
||||
| b.js:5:1:5:18 | export { f as g }; | g | b.js:5:10:5:10 | f |
|
||||
| b.js:7:1:7:21 | export ... './a'; | f2 | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
| e.js:2:1:2:16 | export { x, y }; | x | e.js:2:10:2:10 | x |
|
||||
| e.js:2:1:2:16 | export { x, y }; | y | e.js:2:13:2:13 | y |
|
||||
| e.js:3:1:3:35 | export ... './a'; | g | a.js:1:16:3:1 | functio ... n 23;\\n} |
|
||||
| es2015_require.js:3:1:3:25 | export ... ss C {} | default | es2015_require.js:3:16:3:25 | class C {} |
|
||||
| export-in-mjs.mjs:1:1:1:34 | export ... s = 42; | exported_from_mjs | export-in-mjs.mjs:1:32:1:33 | 42 |
|
||||
| f.ts:5:1:5:24 | export ... oo() {} | foo | f.ts:5:8:5:24 | function foo() {} |
|
||||
| m/c.js:5:1:5:30 | export ... '../b'; | h | b.js:5:10:5:10 | f |
|
||||
| tst.html:7:3:7:22 | export const y = 42; | y | tst.html:7:20:7:21 | 42 |
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import * as b from '../b';
|
||||
|
||||
b.g();
|
||||
|
||||
export { g as h } from '../b';
|
||||
|
||||
// semmle-extractor-options: --experimental
|
||||
|
||||
Reference in New Issue
Block a user