JavaScript: Add QL library support for E4X.

This commit is contained in:
Max Schaefer
2018-10-12 11:41:44 +01:00
parent 5a89024507
commit be67d5129a
3 changed files with 110 additions and 2 deletions

View File

@@ -14,6 +14,7 @@ import semmle.javascript.Concepts
import semmle.javascript.Constants
import semmle.javascript.DefUse
import semmle.javascript.DOM
import semmle.javascript.E4X
import semmle.javascript.EmailClients
import semmle.javascript.Errors
import semmle.javascript.ES2015Modules

View File

@@ -0,0 +1,101 @@
/**
* Provides classes for working with E4X.
*/
import javascript
module E4X {
/**
* An E4X wildcard pseudo-identifier.
*/
class XMLAnyName extends Expr, @e4x_xml_anyname {
}
/**
* An E4X qualified identifier of the form `q::n` or `q::[expr]`.
*/
class XMLQualifiedIdentifier extends Expr, @e4x_xml_qualident {
/**
* Gets the left operand of this qualified identifier, which is either
* an identifier or a wildcard.
*/
Expr getLeft() { result = getChildExpr(0) }
/**
* Gets the right operand of this qualified identifer, which is either
* an identifier, or an arbitrary expression for computed qualified
* identifiers.
*/
Expr getRight() { result = getChildExpr(1) }
/**
* Holds if this is a qualified identifier with a computed name, as in
* `q::[expr]`.
*/
predicate isComputed() { this instanceof @e4x_xml_dynamic_qualident }
override ControlFlowNode getFirstControlFlowNode() {
result = getLeft().getFirstControlFlowNode()
}
}
/**
* An E4X attribute selector of the form `@name` or `@[expr]`.
*/
class XMLAttributeSelector extends Expr, @e4x_xml_attribute_selector {
/**
* Gets the selected attribute, which is either a static name (that is, a
* wildcard identifier or a possibly qualified name), or an arbitrary
* expression for computed attribute selectors.
*/
Expr getAttribute() { result = getChildExpr(0) }
/**
* Holds if this is an attribute selector with a computed name, as in
* `@[expr]`.
*/
predicate isComputed() { this instanceof @e4x_xml_dynamic_attribute_selector }
override ControlFlowNode getFirstControlFlowNode() {
result = getAttribute().getFirstControlFlowNode()
}
}
/**
* An E4X filter expression of the form `left.(right)`.
*/
class XMLFilterExpression extends Expr, @e4x_xml_filter_expression {
/**
* Gets the left operand of this filter expression.
*/
Expr getLeft() { result = getChildExpr(0) }
/**
* Gets the right operand of this filter expression.
*/
Expr getRight() { result = getChildExpr(1) }
override ControlFlowNode getFirstControlFlowNode() {
result = getLeft().getFirstControlFlowNode()
}
}
/**
* An E4X "dot-dot" expression of the form `e..id`.
*/
class XMLDotDotExpression extends Expr, @e4x_xml_dotdotexpr {
/**
* Gets the base expression of this dot-dot expression.
*/
Expr getBase() { result = getChildExpr(0) }
/**
* Gets the index expression of this dot-dot expression.
*/
Expr getIndex() { result = getChildExpr(1) }
override ControlFlowNode getFirstControlFlowNode() {
result = getBase().getFirstControlFlowNode()
}
}
}

View File

@@ -1078,8 +1078,14 @@ module DataFlow {
nd.asExpr() instanceof ExternalModuleReference and
cause = "import"
or
nd.asExpr() instanceof PropAccess and
cause = "heap"
exists (Expr e | e = nd.asExpr() and cause = "heap" |
e instanceof PropAccess or
e instanceof E4X::XMLAnyName or
e instanceof E4X::XMLAttributeSelector or
e instanceof E4X::XMLDotDotExpression or
e instanceof E4X::XMLFilterExpression or
e instanceof E4X::XMLQualifiedIdentifier
)
or
exists(Expr e | e = nd.asExpr() |
(e instanceof YieldExpr or e instanceof FunctionSentExpr) and