Skip to content

Commit 9c4f85f

Browse files
committed
JS: Split getSourceNode into getDirectSourceNode and getReExportedSourceNode
1 parent 94566e5 commit 9c4f85f

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

javascript/ql/lib/semmle/javascript/ES2015Modules.qll

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,17 @@ abstract class ExportDeclaration extends Stmt, @export_declaration {
379379
* to module `a` or possibly to some other module from which `a` re-exports.
380380
*/
381381
overlay[global]
382-
abstract DataFlow::Node getSourceNode(string name);
382+
final DataFlow::Node getSourceNode(string name) {
383+
result = this.getDirectSourceNode(name)
384+
or
385+
result = this.(ReExportDeclaration).getReExportedSourceNode(name)
386+
}
387+
388+
/**
389+
* Gets the data flow node corresponding to the value this declaration exports
390+
* under the name `name`, not including sources that come from a re-export.
391+
*/
392+
DataFlow::Node getDirectSourceNode(string name) { none() }
383393

384394
/** Holds if is declared with the `type` keyword, so only types are exported. */
385395
predicate isTypeOnly() { has_type_keyword(this) }
@@ -437,7 +447,7 @@ class BulkReExportDeclaration extends ReExportDeclaration, @export_all_declarati
437447
}
438448

439449
overlay[global]
440-
override DataFlow::Node getSourceNode(string name) {
450+
override DataFlow::Node getReExportedSourceNode(string name) {
441451
result = this.getReExportedES2015Module().getAnExport().getSourceNode(name)
442452
}
443453
}
@@ -490,8 +500,7 @@ class ExportDefaultDeclaration extends ExportDeclaration, @export_default_declar
490500
)
491501
}
492502

493-
overlay[global]
494-
override DataFlow::Node getSourceNode(string name) {
503+
override DataFlow::Node getDirectSourceNode(string name) {
495504
name = "default" and result = DataFlow::valueNode(this.getOperand())
496505
}
497506
}
@@ -543,8 +552,7 @@ class ExportNamedDeclaration extends ExportDeclaration, @export_named_declaratio
543552
)
544553
}
545554

546-
overlay[global]
547-
override DataFlow::Node getSourceNode(string name) {
555+
override DataFlow::Node getDirectSourceNode(string name) {
548556
exists(VarDef d | d.getTarget() = this.getADecl() |
549557
name = d.getTarget().(VarDecl).getName() and
550558
result = DataFlow::valueNode(d.getSource())
@@ -560,12 +568,11 @@ class ExportNamedDeclaration extends ExportDeclaration, @export_named_declaratio
560568
exists(ExportSpecifier spec | spec = this.getASpecifier() and name = spec.getExportedName() |
561569
not exists(this.getImportedPath()) and result = DataFlow::valueNode(spec.getLocal())
562570
or
563-
exists(ReExportDeclaration red | red = this |
564-
result = red.getReExportedES2015Module().getAnExport().getSourceNode(spec.getLocalName())
565-
or
566-
spec instanceof ExportNamespaceSpecifier and
567-
result = DataFlow::valueNode(spec)
568-
)
571+
// For `export * as B from ".."`, we use the ExportNamespaceSpecifier as a representative for the
572+
// object that gets exposed as `B`.
573+
this instanceof ReExportDeclaration and
574+
spec instanceof ExportNamespaceSpecifier and
575+
result = DataFlow::valueNode(spec)
569576
)
570577
}
571578

@@ -789,6 +796,13 @@ abstract class ReExportDeclaration extends ExportDeclaration {
789796
*/
790797
overlay[global]
791798
abstract predicate reExportsAs(LexicalName v, string name);
799+
800+
/**
801+
* Gets the data flow node (from another module) corresponding to the value that is re-exported
802+
* under the name `name`.
803+
*/
804+
overlay[global]
805+
abstract DataFlow::Node getReExportedSourceNode(string name);
792806
}
793807

794808
/** A literal path expression appearing in a re-export declaration. */
@@ -822,6 +836,13 @@ class SelectiveReExportDeclaration extends ReExportDeclaration, ExportNamedDecla
822836
this.getReExportedES2015Module().exportsAs(v, spec.getLocalName())
823837
)
824838
}
839+
840+
overlay[global]
841+
override DataFlow::Node getReExportedSourceNode(string name) {
842+
exists(ExportSpecifier spec | spec = this.getASpecifier() and name = spec.getExportedName() |
843+
result = this.getReExportedES2015Module().getAnExport().getSourceNode(spec.getLocalName())
844+
)
845+
}
825846
}
826847

827848
/**

0 commit comments

Comments
 (0)