mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
Merge pull request #4609 from asgerf/js/destructuring-export
Approved by erik-krogh
This commit is contained in:
@@ -40,6 +40,40 @@ class ES2015Module extends Module {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `mod` contains one or more named export declarations other than `default`.
|
||||
*/
|
||||
private predicate hasNamedExports(ES2015Module mod) {
|
||||
mod.getAnExport().(ExportNamedDeclaration).getASpecifier().getExportedName() != "default"
|
||||
or
|
||||
exists(mod.getAnExport().(ExportNamedDeclaration).getAnExportedDecl())
|
||||
or
|
||||
// Bulk re-exports only export named bindings (not "default")
|
||||
mod.getAnExport() instanceof BulkReExportDeclaration
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this module contains a `default` export.
|
||||
*/
|
||||
private predicate hasDefaultExport(ES2015Module mod) {
|
||||
// export default foo;
|
||||
mod.getAnExport() instanceof ExportDefaultDeclaration
|
||||
or
|
||||
// export { foo as default };
|
||||
mod.getAnExport().(ExportNamedDeclaration).getASpecifier().getExportedName() = "default"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `mod` contains both named and `default` exports.
|
||||
*
|
||||
* This is used to determine whether a default-import of the module should be reinterpreted
|
||||
* as a namespace-import, to accomodate the non-standard behavior implemented by some compilers.
|
||||
*/
|
||||
private predicate hasBothNamedAndDefaultExports(ES2015Module mod) {
|
||||
hasNamedExports(mod) and
|
||||
hasDefaultExport(mod)
|
||||
}
|
||||
|
||||
/**
|
||||
* An import declaration.
|
||||
*
|
||||
@@ -70,6 +104,10 @@ class ImportDeclaration extends Stmt, Import, @import_declaration {
|
||||
is instanceof ImportNamespaceSpecifier and
|
||||
count(getASpecifier()) = 1
|
||||
or
|
||||
// For compatibility with the non-standard implementation of default imports,
|
||||
// treat default imports as namespace imports in cases where it can't cause ambiguity
|
||||
// between named exports and the properties of a default-exported object.
|
||||
not hasBothNamedAndDefaultExports(getImportedModule()) and
|
||||
is.getImportedName() = "default"
|
||||
)
|
||||
or
|
||||
|
||||
@@ -205,15 +205,16 @@ private predicate isRequire(DataFlow::Node nd) {
|
||||
or
|
||||
isRequire(nd.getAPredecessor())
|
||||
or
|
||||
// `import { createRequire } from 'module';` support.
|
||||
// specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate.
|
||||
exists(ImportDeclaration imp | imp.getImportedPath().getValue() = "module" |
|
||||
nd =
|
||||
imp
|
||||
.getImportedModuleNode()
|
||||
.(DataFlow::SourceNode)
|
||||
.getAPropertyRead("createRequire")
|
||||
.getACall()
|
||||
// `import { createRequire } from 'module';`.
|
||||
// specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate and to avoid
|
||||
// negative recursion between `Import.getImportedModuleNode()` and `Import.getImportedModule()`.
|
||||
exists(ImportDeclaration imp, DataFlow::SourceNode baseObj |
|
||||
imp.getImportedPath().getValue() = "module"
|
||||
|
|
||||
baseObj =
|
||||
[DataFlow::destructuredModuleImportNode(imp),
|
||||
DataFlow::valueNode(imp.getASpecifier().(ImportNamespaceSpecifier))] and
|
||||
nd = baseObj.getAPropertyRead("createRequire").getACall()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +318,12 @@ private class AnalyzedVariableExport extends AnalyzedPropertyWrite, DataFlow::Va
|
||||
override predicate writes(AbstractValue baseVal, string propName, DataFlow::AnalyzedNode source) {
|
||||
baseVal = TAbstractExportsObject(export.getEnclosingModule()) and
|
||||
propName = name and
|
||||
source = varDef.getSource().analyze()
|
||||
(
|
||||
source = varDef.getSource().analyze()
|
||||
or
|
||||
varDef.getTarget() instanceof DestructuringPattern and
|
||||
source = export.getSourceNode(propName)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate writesValue(AbstractValue baseVal, string propName, AbstractValue val) {
|
||||
|
||||
Reference in New Issue
Block a user