mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge pull request #1694 from asger-semmle/concatenation-operand
Approved by xiemaisi
This commit is contained in:
@@ -13,6 +13,7 @@ module StringConcatenation {
|
||||
}
|
||||
|
||||
/** Gets the `n`th operand to the string concatenation defining `node`. */
|
||||
pragma[nomagic]
|
||||
DataFlow::Node getOperand(DataFlow::Node node, int n) {
|
||||
exists(AddExpr add | node = add.flow() |
|
||||
n = 0 and result = add.getLeftOperand().flow()
|
||||
|
||||
@@ -438,30 +438,72 @@ module StringOps {
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that concatenates strings and returns the result.
|
||||
* Holds if `first` and `second` are adjacent leaves in a concatenation tree.
|
||||
*/
|
||||
class Concatenation extends DataFlow::Node {
|
||||
Concatenation() {
|
||||
pragma[nomagic]
|
||||
private predicate adjacentLeaves(ConcatenationLeaf first, ConcatenationLeaf second) {
|
||||
exists(Concatenation parent, int i |
|
||||
first = parent.getOperand(i).getLastLeaf() and
|
||||
second = parent.getOperand(i + 1).getFirstLeaf()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that performs a string concatenation or occurs as an operand
|
||||
* in a string concatenation.
|
||||
*
|
||||
* For example, the expression `x + y + z` contains the following concatenation
|
||||
* nodes:
|
||||
* - The leaf nodes `x`, `y`, and `z`
|
||||
* - The intermediate node `x + y`, which is both a concatenation and an operand
|
||||
* - The root node `x + y + z`
|
||||
*
|
||||
*
|
||||
* Note that the following are not recognized a string concatenations:
|
||||
* - Array `join()` calls with a non-empty separator
|
||||
* - Tagged template literals
|
||||
*
|
||||
*
|
||||
* Also note that all `+` operators are seen as string concatenations,
|
||||
* even in cases where it is used for arithmetic.
|
||||
*
|
||||
* Examples of string concatenations:
|
||||
* ```
|
||||
* x + y
|
||||
* x += y
|
||||
* [x, y].join('')
|
||||
* Array(x, y).join('')
|
||||
* `Hello, ${message}`
|
||||
* ```
|
||||
*/
|
||||
class ConcatenationNode extends DataFlow::Node {
|
||||
pragma[inline]
|
||||
ConcatenationNode() {
|
||||
exists(StringConcatenation::getAnOperand(this))
|
||||
or
|
||||
this = StringConcatenation::getAnOperand(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `n`th operand of this string concatenation.
|
||||
*/
|
||||
DataFlow::Node getOperand(int n) {
|
||||
pragma[inline]
|
||||
ConcatenationOperand getOperand(int n) {
|
||||
result = StringConcatenation::getOperand(this, n)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an operand of this string concatenation.
|
||||
*/
|
||||
DataFlow::Node getAnOperand() {
|
||||
pragma[inline]
|
||||
ConcatenationOperand getAnOperand() {
|
||||
result = StringConcatenation::getAnOperand(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of operands of this string concatenation.
|
||||
*/
|
||||
pragma[inline]
|
||||
int getNumOperand() {
|
||||
result = StringConcatenation::getNumOperand(this)
|
||||
}
|
||||
@@ -469,20 +511,23 @@ module StringOps {
|
||||
/**
|
||||
* Gets the first operand of this string concatenation.
|
||||
*/
|
||||
DataFlow::Node getFirstOperand() {
|
||||
pragma[inline]
|
||||
ConcatenationOperand getFirstOperand() {
|
||||
result = StringConcatenation::getFirstOperand(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last operand of this string concatenation
|
||||
*/
|
||||
DataFlow::Node getLastOperand() {
|
||||
pragma[inline]
|
||||
ConcatenationOperand getLastOperand() {
|
||||
result = StringConcatenation::getLastOperand(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this only acts as a string coercion, such as `"" + x`.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate isCoercion() {
|
||||
StringConcatenation::isCoercion(this)
|
||||
}
|
||||
@@ -492,15 +537,220 @@ module StringOps {
|
||||
* it is a concatenation operator that is not itself the immediate operand to
|
||||
* another concatenation operator.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate isRoot() {
|
||||
StringConcatenation::isRoot(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is a leaf in the concatenation tree, that is, it is not
|
||||
* itself a concatenation.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate isLeaf() {
|
||||
not exists(StringConcatenation::getAnOperand(this))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the root of the concatenation tree in which this is an operator.
|
||||
*/
|
||||
Concatenation getRoot() {
|
||||
pragma[inline]
|
||||
ConcatenationRoot getRoot() {
|
||||
result = StringConcatenation::getRoot(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enclosing concatenation in which this is an operand, if any.
|
||||
*/
|
||||
pragma[inline]
|
||||
Concatenation getParentConcatenation() {
|
||||
this = StringConcatenation::getAnOperand(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last leaf in this concatenation tree.
|
||||
*
|
||||
* For example, `z` is the last leaf in `x + y + z`.
|
||||
*/
|
||||
pragma[inline]
|
||||
ConcatenationLeaf getLastLeaf() {
|
||||
result = StringConcatenation::getLastOperand*(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first leaf in this concatenation tree.
|
||||
*
|
||||
* For example, `x` is the first leaf in `x + y + z`.
|
||||
*/
|
||||
pragma[inline]
|
||||
ConcatenationLeaf getFirstLeaf() {
|
||||
result = StringConcatenation::getFirstOperand*(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the leaf that is occurs immediately before this leaf in the
|
||||
* concatenation tree, if any.
|
||||
*
|
||||
* For example, `y` is the previous leaf from `z` in `x + y + z`.
|
||||
*/
|
||||
pragma[inline]
|
||||
ConcatenationLeaf getPreviousLeaf() {
|
||||
adjacentLeaves(result, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the leaf that is occurs immediately after this leaf in the
|
||||
* concatenation tree, if any.
|
||||
*
|
||||
* For example, `y` is the next leaf from `x` in `x + y + z`.
|
||||
*/
|
||||
pragma[inline]
|
||||
ConcatenationLeaf getNextLeaf() {
|
||||
adjacentLeaves(this, result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that performs a string concatenation and returns the result.
|
||||
*
|
||||
* Examples:
|
||||
* ```
|
||||
* x + y
|
||||
* x += y
|
||||
* [x, y].join('')
|
||||
* Array(x, y).join('')
|
||||
* `Hello ${message}`
|
||||
* ```
|
||||
*
|
||||
* See `ConcatenationNode` for more information.
|
||||
*/
|
||||
class Concatenation extends ConcatenationNode {
|
||||
pragma[inline]
|
||||
Concatenation() {
|
||||
exists(StringConcatenation::getAnOperand(this))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* One of the operands in a string concatenation.
|
||||
*
|
||||
* Examples:
|
||||
* ```
|
||||
* x + y // x and y are operands
|
||||
* [x, y].join('') // x and y are operands
|
||||
* `Hello ${message}` // `Hello ` and message are operands
|
||||
* ```
|
||||
*
|
||||
* See `ConcatenationNode` for more information.
|
||||
*/
|
||||
class ConcatenationOperand extends ConcatenationNode {
|
||||
pragma[inline]
|
||||
ConcatenationOperand() {
|
||||
this = StringConcatenation::getAnOperand(_)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that performs a string concatenation, and is not an
|
||||
* immediate operand in a larger string concatenation.
|
||||
*
|
||||
* Examples:
|
||||
* ```
|
||||
* // x + y + z is a root, but the inner x + y is not
|
||||
* return x + y + z;
|
||||
* ```
|
||||
*
|
||||
* See `ConcatenationNode` for more information.
|
||||
*/
|
||||
class ConcatenationRoot extends Concatenation {
|
||||
pragma[inline]
|
||||
ConcatenationRoot() {
|
||||
isRoot()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a leaf in this concatenation tree that this node is the root of.
|
||||
*/
|
||||
pragma[inline]
|
||||
ConcatenationLeaf getALeaf() {
|
||||
this = StringConcatenation::getRoot(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the concatenation of all constant operands in this concatenation,
|
||||
* ignoring the non-constant parts entirely.
|
||||
*
|
||||
* For example, for the following concatenation
|
||||
* ```
|
||||
* `Hello ${person}, how are you?`
|
||||
* ```
|
||||
* the result is `"Hello , how are you?"`
|
||||
*/
|
||||
string getConstantStringParts() {
|
||||
result = getStringValue()
|
||||
or
|
||||
not exists(getStringValue()) and
|
||||
result = strictconcat(StringLiteralLike leaf |
|
||||
leaf = getALeaf().asExpr()
|
||||
|
|
||||
leaf.getStringValue()
|
||||
order by leaf.getFirstToken().getIndex() asc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A string literal or template literal without any substitutions. */
|
||||
private class StringLiteralLike extends Expr {
|
||||
StringLiteralLike() {
|
||||
this instanceof StringLiteral or
|
||||
this instanceof TemplateElement
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand to a concatenation that is not itself a concatenation.
|
||||
*
|
||||
* Example:
|
||||
* ```
|
||||
* x + y + z // x, y, and z are leaves
|
||||
* [x, y + z].join('') // x, y, and z are leaves
|
||||
* ```
|
||||
*
|
||||
* See `ConcatenationNode` for more information.
|
||||
*/
|
||||
class ConcatenationLeaf extends ConcatenationOperand {
|
||||
pragma[inline]
|
||||
ConcatenationLeaf() {
|
||||
isLeaf()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The root node in a concatenation of one or more strings containing HTML fragments.
|
||||
*/
|
||||
class HtmlConcatenationRoot extends ConcatenationRoot {
|
||||
pragma[noinline]
|
||||
HtmlConcatenationRoot() {
|
||||
getConstantStringParts().regexpMatch("(?s).*</?[a-zA-Z][^\\r\\n<>/]*/?>.*")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that is part of an HTML string concatenation.
|
||||
*/
|
||||
class HtmlConcatenationNode extends ConcatenationNode {
|
||||
HtmlConcatenationNode() {
|
||||
getRoot() instanceof HtmlConcatenationRoot
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that is part of an HTML string concatenation,
|
||||
* and is not itself a concatenation operator.
|
||||
*/
|
||||
class HtmlConcatenationLeaf extends ConcatenationLeaf {
|
||||
HtmlConcatenationLeaf() {
|
||||
getRoot() instanceof HtmlConcatenationRoot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ class TemplateLiteral extends Expr, @templateliteral {
|
||||
*/
|
||||
Expr getAnElement() { result = getElement(_) }
|
||||
|
||||
/**
|
||||
* Gets the number of elements of this template literal.
|
||||
*/
|
||||
int getNumElement() { result = count(getAnElement()) }
|
||||
|
||||
override predicate isImpure() { getAnElement().isImpure() }
|
||||
|
||||
override string getStringValue() {
|
||||
|
||||
@@ -34,11 +34,11 @@ private class HeuristicCodeInjectionSink extends HeuristicSink, CodeInjection::S
|
||||
srcPattern = "(?s).*function\\s*\\(.*\\).*" or
|
||||
srcPattern = "(?s).*(\\(.*\\)|[A-Za-z_]+)\\s?=>.*"
|
||||
|
|
||||
isContatenatedWithString(this, srcPattern)
|
||||
isConcatenatedWithString(this, srcPattern)
|
||||
)
|
||||
or
|
||||
// dynamic property name
|
||||
isContatenatedWithStrings("(?is)[a-z]+\\[", this, "(?s)\\].*")
|
||||
isConcatenatedWithStrings("(?is)[a-z]+\\[", this, "(?s)\\].*")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ private class HeuristicDomBasedXssSink extends HeuristicSink, DomBasedXss::DomBa
|
||||
HeuristicDomBasedXssSink() {
|
||||
isAssignedToOrConcatenatedWith(this, "(?i)(html|innerhtml)") or
|
||||
isArgTo(this, "(?i)(html|render)") or
|
||||
isContatenatedWithString(this, "(?is).*<.*>.*") or
|
||||
isContatenatedWithStrings("(?is).*<[a-z ]+.*", this, "(?s).*>.*")
|
||||
this instanceof StringOps::HtmlConcatenationLeaf or
|
||||
isConcatenatedWithStrings("(?is).*<[a-z ]+.*", this, "(?s).*>.*")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ private class HeuristicReflectedXssSink extends HeuristicSink, ReflectedXss::Ref
|
||||
HeuristicReflectedXssSink() {
|
||||
isAssignedToOrConcatenatedWith(this, "(?i)(html|innerhtml)") or
|
||||
isArgTo(this, "(?i)(html|render)") or
|
||||
isContatenatedWithString(this, "(?is).*<.*>.*") or
|
||||
isContatenatedWithStrings("(?is).*<[a-z ]+.*", this, "(?s).*>.*")
|
||||
this instanceof StringOps::HtmlConcatenationLeaf or
|
||||
isConcatenatedWithStrings("(?is).*<[a-z ]+.*", this, "(?s).*>.*")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ private class HeuristicSqlInjectionSink extends HeuristicSink, SqlInjection::Sin
|
||||
HeuristicSqlInjectionSink() {
|
||||
isAssignedToOrConcatenatedWith(this, "(?i)(sql|query)") or
|
||||
isArgTo(this, "(?i)(query)") or
|
||||
isContatenatedWithString(this,
|
||||
isConcatenatedWithString(this,
|
||||
"(?s).*(ALTER|COUNT|CREATE|DATABASE|DELETE|DISTINCT|DROP|FROM|GROUP|INSERT|INTO|LIMIT|ORDER|SELECT|TABLE|UPDATE|WHERE).*")
|
||||
}
|
||||
}
|
||||
@@ -94,10 +94,10 @@ private class HeuristicTaintedPathSink extends HeuristicSink, TaintedPath::Sink
|
||||
pathPattern = "(?i)([a-z0-9_.-]+/){2,}" or
|
||||
pathPattern = "(?i)(/[a-z0-9_.-]+){2,}"
|
||||
|
|
||||
isContatenatedWithString(this, pathPattern)
|
||||
isConcatenatedWithString(this, pathPattern)
|
||||
)
|
||||
or
|
||||
isContatenatedWithStrings(".*/", this, "/.*")
|
||||
isConcatenatedWithStrings(".*/", this, "/.*")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,42 +66,28 @@ predicate isArgTo(DataFlow::Node arg, string regexp) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` is concatenated with something with a name that matches `regexp`.
|
||||
* Holds if `n` is a concatenation containing something with a name that matches `regexp`.
|
||||
*/
|
||||
bindingset[regexp]
|
||||
predicate isConcatenatedWith(DataFlow::Node n, string regexp) {
|
||||
exists(Expr other |
|
||||
other = n.asExpr().(AddExpr).getAnOperand() or
|
||||
other = n.asExpr().(AssignAddExpr).getRhs()
|
||||
|
|
||||
isReadFrom(DataFlow::valueNode(other), regexp)
|
||||
)
|
||||
predicate isConcatenatedWith(StringOps::Concatenation n, string regexp) {
|
||||
isReadFrom(n.getAnOperand(), regexp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` is concatenated with a string constant that matches `regexp`.
|
||||
* Holds if `n` is a concatenation containing something with a name that matches `regexp`.
|
||||
*/
|
||||
bindingset[regexp]
|
||||
predicate isContatenatedWithString(DataFlow::Node n, string regexp) {
|
||||
exists(Expr other |
|
||||
other = n.asExpr().(AddExpr).getAnOperand() or
|
||||
other = n.asExpr().(AssignAddExpr).getRhs()
|
||||
|
|
||||
other.getStringValue().regexpMatch(regexp)
|
||||
)
|
||||
predicate isConcatenatedWithString(StringOps::Concatenation n, string regexp) {
|
||||
n.getAnOperand().getStringValue().regexpMatch(regexp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` is concatenated between two string constants that match `lRegexp` and `rRegexp` respectively.
|
||||
*/
|
||||
bindingset[lRegexp, rRegexp]
|
||||
predicate isContatenatedWithStrings(string lRegexp, DataFlow::Node n, string rRegexp) {
|
||||
exists(AddExpr concat1, AddExpr concat2 |
|
||||
concat1.getLeftOperand().getStringValue().regexpMatch(lRegexp) and
|
||||
concat1.getRightOperand() = n.asExpr() and
|
||||
concat2.getLeftOperand() = concat1 and
|
||||
concat2.getRightOperand().getStringValue().regexpMatch(rRegexp)
|
||||
)
|
||||
predicate isConcatenatedWithStrings(string lRegexp, StringOps::ConcatenationLeaf n, string rRegexp) {
|
||||
n.getPreviousLeaf().getStringValue().regexpMatch(lRegexp) and
|
||||
n.getNextLeaf().getStringValue().regexpMatch(rRegexp)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
| sinks.js:4:9:4:12 | sink |
|
||||
| sinks.js:6:16:6:19 | sink |
|
||||
| sinks.js:7:5:7:22 | getScript() + sink |
|
||||
| sinks.js:8:5:8:18 | script += sink |
|
||||
| sinks.js:8:15:8:18 | sink |
|
||||
| sinks.js:9:5:9:18 | sink += script |
|
||||
| sinks.js:10:11:10:14 | sink |
|
||||
@@ -25,8 +26,11 @@
|
||||
| sinks.js:41:5:41:26 | sink + ... ion(){" |
|
||||
| sinks.js:42:5:42:18 | "x => " + sink |
|
||||
| sinks.js:43:14:43:17 | sink |
|
||||
| sinks.js:45:5:45:18 | "<div>" + sink |
|
||||
| sinks.js:45:5:45:11 | "<div>" |
|
||||
| sinks.js:45:15:45:18 | sink |
|
||||
| sinks.js:46:5:46:20 | '<div foo="foo"' |
|
||||
| sinks.js:46:24:46:27 | sink |
|
||||
| sinks.js:46:31:46:42 | 'bar="bar">' |
|
||||
| sinks.js:48:5:48:20 | "SELECT " + sink |
|
||||
| sinks.js:50:5:50:21 | "/foo/bar" + sink |
|
||||
| sinks.js:51:5:51:21 | "foo/bar/" + sink |
|
||||
|
||||
@@ -0,0 +1,474 @@
|
||||
concatenation
|
||||
| closure.js:5:1:5:37 | build(' ... 'four') |
|
||||
| closure.js:5:1:5:46 | build(' ... 'five' |
|
||||
| closure.js:5:14:5:28 | 'two' + 'three' |
|
||||
| html-concat.js:2:14:2:26 | `<b>${x}</b>` |
|
||||
| html-concat.js:3:14:3:26 | `<B>${x}</B>` |
|
||||
| html-concat.js:5:21:5:47 | `Hey <s ... trong>` |
|
||||
| html-concat.js:7:18:10:24 | `\\n H ... m!</i>` |
|
||||
| html-concat.js:13:3:13:18 | buffer |
|
||||
| html-concat.js:13:3:13:18 | buffer += '<li>' |
|
||||
| html-concat.js:14:3:14:13 | buffer |
|
||||
| html-concat.js:14:3:14:13 | buffer += x |
|
||||
| html-concat.js:15:3:15:15 | buffer |
|
||||
| html-concat.js:15:3:15:15 | buffer += '!' |
|
||||
| tst.js:3:3:3:12 | x |
|
||||
| tst.js:3:3:3:12 | x += "two" |
|
||||
| tst.js:4:3:4:14 | x |
|
||||
| tst.js:4:3:4:14 | x += "three" |
|
||||
| tst.js:5:3:5:13 | x |
|
||||
| tst.js:5:3:5:13 | x += "four" |
|
||||
| tst.js:12:5:12:26 | x |
|
||||
| tst.js:12:5:12:26 | x += "o ... + "two" |
|
||||
| tst.js:12:10:12:18 | "one" + y |
|
||||
| tst.js:12:10:12:26 | "one" + y + "two" |
|
||||
| tst.js:14:3:14:13 | x |
|
||||
| tst.js:14:3:14:13 | x += "last" |
|
||||
| tst.js:19:11:19:23 | "one" + "two" |
|
||||
| tst.js:20:3:20:25 | x |
|
||||
| tst.js:20:3:20:25 | x += (" ... "four") |
|
||||
| tst.js:20:9:20:24 | "three" + "four" |
|
||||
| tst.js:21:10:21:19 | x + "five" |
|
||||
| tst.js:25:10:25:32 | ["one", ... three"] |
|
||||
| tst.js:25:10:25:41 | ["one", ... oin("") |
|
||||
| tst.js:29:10:29:37 | Array(" ... three") |
|
||||
| tst.js:29:10:29:46 | Array(" ... oin("") |
|
||||
| tst.js:33:10:33:41 | new Arr ... three") |
|
||||
| tst.js:33:10:33:50 | new Arr ... oin("") |
|
||||
| tst.js:37:12:37:18 | ["one"] |
|
||||
| tst.js:40:10:40:20 | xs.join("") |
|
||||
| tst.js:44:12:44:20 | ["first"] |
|
||||
| tst.js:49:10:49:20 | xs.join("") |
|
||||
| tst.js:53:10:53:34 | `one ${ ... three` |
|
||||
| tst.js:61:10:61:34 | `first ... } last` |
|
||||
| tst.js:87:5:87:14 | x |
|
||||
| tst.js:87:5:87:14 | x += 'two' |
|
||||
| tst.js:89:3:89:14 | x |
|
||||
| tst.js:89:3:89:14 | x += 'three' |
|
||||
concatenationOperand
|
||||
| closure.js:5:1:5:37 | build(' ... 'four') |
|
||||
| closure.js:5:7:5:11 | 'one' |
|
||||
| closure.js:5:14:5:18 | 'two' |
|
||||
| closure.js:5:14:5:28 | 'two' + 'three' |
|
||||
| closure.js:5:22:5:28 | 'three' |
|
||||
| closure.js:5:31:5:36 | 'four' |
|
||||
| closure.js:5:41:5:46 | 'five' |
|
||||
| html-concat.js:2:15:2:17 | <b> |
|
||||
| html-concat.js:2:20:2:20 | x |
|
||||
| html-concat.js:2:22:2:25 | </b> |
|
||||
| html-concat.js:3:15:3:17 | <B> |
|
||||
| html-concat.js:3:20:3:20 | x |
|
||||
| html-concat.js:3:22:3:25 | </B> |
|
||||
| html-concat.js:5:22:5:33 | Hey <strong> |
|
||||
| html-concat.js:5:36:5:36 | x |
|
||||
| html-concat.js:5:38:5:46 | </strong> |
|
||||
| html-concat.js:7:19:8:10 | \\n Hello |
|
||||
| html-concat.js:8:13:8:13 | x |
|
||||
| html-concat.js:8:15:10:23 | .\\n \\n ... um!</i> |
|
||||
| html-concat.js:13:3:13:8 | buffer |
|
||||
| html-concat.js:13:13:13:18 | '<li>' |
|
||||
| html-concat.js:14:3:14:8 | buffer |
|
||||
| html-concat.js:14:13:14:13 | x |
|
||||
| html-concat.js:15:3:15:8 | buffer |
|
||||
| html-concat.js:15:13:15:15 | '!' |
|
||||
| tst.js:3:3:3:3 | x |
|
||||
| tst.js:3:8:3:12 | "two" |
|
||||
| tst.js:4:3:4:3 | x |
|
||||
| tst.js:4:8:4:14 | "three" |
|
||||
| tst.js:5:3:5:3 | x |
|
||||
| tst.js:5:8:5:13 | "four" |
|
||||
| tst.js:12:5:12:5 | x |
|
||||
| tst.js:12:10:12:14 | "one" |
|
||||
| tst.js:12:10:12:18 | "one" + y |
|
||||
| tst.js:12:10:12:26 | "one" + y + "two" |
|
||||
| tst.js:12:18:12:18 | y |
|
||||
| tst.js:12:22:12:26 | "two" |
|
||||
| tst.js:14:3:14:3 | x |
|
||||
| tst.js:14:8:14:13 | "last" |
|
||||
| tst.js:19:11:19:15 | "one" |
|
||||
| tst.js:19:19:19:23 | "two" |
|
||||
| tst.js:20:3:20:3 | x |
|
||||
| tst.js:20:8:20:25 | ("three" + "four") |
|
||||
| tst.js:20:9:20:15 | "three" |
|
||||
| tst.js:20:19:20:24 | "four" |
|
||||
| tst.js:21:10:21:10 | x |
|
||||
| tst.js:21:14:21:19 | "five" |
|
||||
| tst.js:25:10:25:32 | ["one", ... three"] |
|
||||
| tst.js:25:11:25:15 | "one" |
|
||||
| tst.js:25:18:25:22 | "two" |
|
||||
| tst.js:25:25:25:31 | "three" |
|
||||
| tst.js:29:10:29:37 | Array(" ... three") |
|
||||
| tst.js:29:16:29:20 | "one" |
|
||||
| tst.js:29:23:29:27 | "two" |
|
||||
| tst.js:29:30:29:36 | "three" |
|
||||
| tst.js:33:10:33:41 | new Arr ... three") |
|
||||
| tst.js:33:20:33:24 | "one" |
|
||||
| tst.js:33:27:33:31 | "two" |
|
||||
| tst.js:33:34:33:40 | "three" |
|
||||
| tst.js:37:12:37:18 | ["one"] |
|
||||
| tst.js:37:13:37:17 | "one" |
|
||||
| tst.js:44:12:44:20 | ["first"] |
|
||||
| tst.js:44:13:44:19 | "first" |
|
||||
| tst.js:53:11:53:14 | one |
|
||||
| tst.js:53:17:53:17 | x |
|
||||
| tst.js:53:19:53:23 | two |
|
||||
| tst.js:53:26:53:26 | x |
|
||||
| tst.js:53:28:53:33 | three |
|
||||
| tst.js:61:11:61:16 | first |
|
||||
| tst.js:61:19:61:19 | x |
|
||||
| tst.js:61:23:61:23 | x |
|
||||
| tst.js:61:27:61:27 | x |
|
||||
| tst.js:61:29:61:33 | last |
|
||||
| tst.js:87:5:87:5 | x |
|
||||
| tst.js:87:10:87:14 | 'two' |
|
||||
| tst.js:89:3:89:3 | x |
|
||||
| tst.js:89:8:89:14 | 'three' |
|
||||
concatenationLeaf
|
||||
| closure.js:5:7:5:11 | 'one' |
|
||||
| closure.js:5:14:5:18 | 'two' |
|
||||
| closure.js:5:22:5:28 | 'three' |
|
||||
| closure.js:5:31:5:36 | 'four' |
|
||||
| closure.js:5:41:5:46 | 'five' |
|
||||
| html-concat.js:2:15:2:17 | <b> |
|
||||
| html-concat.js:2:20:2:20 | x |
|
||||
| html-concat.js:2:22:2:25 | </b> |
|
||||
| html-concat.js:3:15:3:17 | <B> |
|
||||
| html-concat.js:3:20:3:20 | x |
|
||||
| html-concat.js:3:22:3:25 | </B> |
|
||||
| html-concat.js:5:22:5:33 | Hey <strong> |
|
||||
| html-concat.js:5:36:5:36 | x |
|
||||
| html-concat.js:5:38:5:46 | </strong> |
|
||||
| html-concat.js:7:19:8:10 | \\n Hello |
|
||||
| html-concat.js:8:13:8:13 | x |
|
||||
| html-concat.js:8:15:10:23 | .\\n \\n ... um!</i> |
|
||||
| html-concat.js:13:3:13:8 | buffer |
|
||||
| html-concat.js:13:13:13:18 | '<li>' |
|
||||
| html-concat.js:14:3:14:8 | buffer |
|
||||
| html-concat.js:14:13:14:13 | x |
|
||||
| html-concat.js:15:3:15:8 | buffer |
|
||||
| html-concat.js:15:13:15:15 | '!' |
|
||||
| tst.js:3:3:3:3 | x |
|
||||
| tst.js:3:8:3:12 | "two" |
|
||||
| tst.js:4:3:4:3 | x |
|
||||
| tst.js:4:8:4:14 | "three" |
|
||||
| tst.js:5:3:5:3 | x |
|
||||
| tst.js:5:8:5:13 | "four" |
|
||||
| tst.js:12:5:12:5 | x |
|
||||
| tst.js:12:10:12:14 | "one" |
|
||||
| tst.js:12:18:12:18 | y |
|
||||
| tst.js:12:22:12:26 | "two" |
|
||||
| tst.js:14:3:14:3 | x |
|
||||
| tst.js:14:8:14:13 | "last" |
|
||||
| tst.js:19:11:19:15 | "one" |
|
||||
| tst.js:19:19:19:23 | "two" |
|
||||
| tst.js:20:3:20:3 | x |
|
||||
| tst.js:20:8:20:25 | ("three" + "four") |
|
||||
| tst.js:20:9:20:15 | "three" |
|
||||
| tst.js:20:19:20:24 | "four" |
|
||||
| tst.js:21:10:21:10 | x |
|
||||
| tst.js:21:14:21:19 | "five" |
|
||||
| tst.js:25:11:25:15 | "one" |
|
||||
| tst.js:25:18:25:22 | "two" |
|
||||
| tst.js:25:25:25:31 | "three" |
|
||||
| tst.js:29:16:29:20 | "one" |
|
||||
| tst.js:29:23:29:27 | "two" |
|
||||
| tst.js:29:30:29:36 | "three" |
|
||||
| tst.js:33:20:33:24 | "one" |
|
||||
| tst.js:33:27:33:31 | "two" |
|
||||
| tst.js:33:34:33:40 | "three" |
|
||||
| tst.js:37:13:37:17 | "one" |
|
||||
| tst.js:44:13:44:19 | "first" |
|
||||
| tst.js:53:11:53:14 | one |
|
||||
| tst.js:53:17:53:17 | x |
|
||||
| tst.js:53:19:53:23 | two |
|
||||
| tst.js:53:26:53:26 | x |
|
||||
| tst.js:53:28:53:33 | three |
|
||||
| tst.js:61:11:61:16 | first |
|
||||
| tst.js:61:19:61:19 | x |
|
||||
| tst.js:61:23:61:23 | x |
|
||||
| tst.js:61:27:61:27 | x |
|
||||
| tst.js:61:29:61:33 | last |
|
||||
| tst.js:87:5:87:5 | x |
|
||||
| tst.js:87:10:87:14 | 'two' |
|
||||
| tst.js:89:3:89:3 | x |
|
||||
| tst.js:89:8:89:14 | 'three' |
|
||||
concatenationNode
|
||||
| closure.js:5:1:5:37 | build(' ... 'four') |
|
||||
| closure.js:5:1:5:46 | build(' ... 'five' |
|
||||
| closure.js:5:7:5:11 | 'one' |
|
||||
| closure.js:5:14:5:18 | 'two' |
|
||||
| closure.js:5:14:5:28 | 'two' + 'three' |
|
||||
| closure.js:5:22:5:28 | 'three' |
|
||||
| closure.js:5:31:5:36 | 'four' |
|
||||
| closure.js:5:41:5:46 | 'five' |
|
||||
| html-concat.js:2:14:2:26 | `<b>${x}</b>` |
|
||||
| html-concat.js:2:15:2:17 | <b> |
|
||||
| html-concat.js:2:20:2:20 | x |
|
||||
| html-concat.js:2:22:2:25 | </b> |
|
||||
| html-concat.js:3:14:3:26 | `<B>${x}</B>` |
|
||||
| html-concat.js:3:15:3:17 | <B> |
|
||||
| html-concat.js:3:20:3:20 | x |
|
||||
| html-concat.js:3:22:3:25 | </B> |
|
||||
| html-concat.js:5:21:5:47 | `Hey <s ... trong>` |
|
||||
| html-concat.js:5:22:5:33 | Hey <strong> |
|
||||
| html-concat.js:5:36:5:36 | x |
|
||||
| html-concat.js:5:38:5:46 | </strong> |
|
||||
| html-concat.js:7:18:10:24 | `\\n H ... m!</i>` |
|
||||
| html-concat.js:7:19:8:10 | \\n Hello |
|
||||
| html-concat.js:8:13:8:13 | x |
|
||||
| html-concat.js:8:15:10:23 | .\\n \\n ... um!</i> |
|
||||
| html-concat.js:13:3:13:8 | buffer |
|
||||
| html-concat.js:13:3:13:18 | buffer |
|
||||
| html-concat.js:13:3:13:18 | buffer += '<li>' |
|
||||
| html-concat.js:13:13:13:18 | '<li>' |
|
||||
| html-concat.js:14:3:14:8 | buffer |
|
||||
| html-concat.js:14:3:14:13 | buffer |
|
||||
| html-concat.js:14:3:14:13 | buffer += x |
|
||||
| html-concat.js:14:13:14:13 | x |
|
||||
| html-concat.js:15:3:15:8 | buffer |
|
||||
| html-concat.js:15:3:15:15 | buffer |
|
||||
| html-concat.js:15:3:15:15 | buffer += '!' |
|
||||
| html-concat.js:15:13:15:15 | '!' |
|
||||
| tst.js:3:3:3:3 | x |
|
||||
| tst.js:3:3:3:12 | x |
|
||||
| tst.js:3:3:3:12 | x += "two" |
|
||||
| tst.js:3:8:3:12 | "two" |
|
||||
| tst.js:4:3:4:3 | x |
|
||||
| tst.js:4:3:4:14 | x |
|
||||
| tst.js:4:3:4:14 | x += "three" |
|
||||
| tst.js:4:8:4:14 | "three" |
|
||||
| tst.js:5:3:5:3 | x |
|
||||
| tst.js:5:3:5:13 | x |
|
||||
| tst.js:5:3:5:13 | x += "four" |
|
||||
| tst.js:5:8:5:13 | "four" |
|
||||
| tst.js:12:5:12:5 | x |
|
||||
| tst.js:12:5:12:26 | x |
|
||||
| tst.js:12:5:12:26 | x += "o ... + "two" |
|
||||
| tst.js:12:10:12:14 | "one" |
|
||||
| tst.js:12:10:12:18 | "one" + y |
|
||||
| tst.js:12:10:12:26 | "one" + y + "two" |
|
||||
| tst.js:12:18:12:18 | y |
|
||||
| tst.js:12:22:12:26 | "two" |
|
||||
| tst.js:14:3:14:3 | x |
|
||||
| tst.js:14:3:14:13 | x |
|
||||
| tst.js:14:3:14:13 | x += "last" |
|
||||
| tst.js:14:8:14:13 | "last" |
|
||||
| tst.js:19:11:19:15 | "one" |
|
||||
| tst.js:19:11:19:23 | "one" + "two" |
|
||||
| tst.js:19:19:19:23 | "two" |
|
||||
| tst.js:20:3:20:3 | x |
|
||||
| tst.js:20:3:20:25 | x |
|
||||
| tst.js:20:3:20:25 | x += (" ... "four") |
|
||||
| tst.js:20:8:20:25 | ("three" + "four") |
|
||||
| tst.js:20:9:20:15 | "three" |
|
||||
| tst.js:20:9:20:24 | "three" + "four" |
|
||||
| tst.js:20:19:20:24 | "four" |
|
||||
| tst.js:21:10:21:10 | x |
|
||||
| tst.js:21:10:21:19 | x + "five" |
|
||||
| tst.js:21:14:21:19 | "five" |
|
||||
| tst.js:25:10:25:32 | ["one", ... three"] |
|
||||
| tst.js:25:10:25:41 | ["one", ... oin("") |
|
||||
| tst.js:25:11:25:15 | "one" |
|
||||
| tst.js:25:18:25:22 | "two" |
|
||||
| tst.js:25:25:25:31 | "three" |
|
||||
| tst.js:29:10:29:37 | Array(" ... three") |
|
||||
| tst.js:29:10:29:46 | Array(" ... oin("") |
|
||||
| tst.js:29:16:29:20 | "one" |
|
||||
| tst.js:29:23:29:27 | "two" |
|
||||
| tst.js:29:30:29:36 | "three" |
|
||||
| tst.js:33:10:33:41 | new Arr ... three") |
|
||||
| tst.js:33:10:33:50 | new Arr ... oin("") |
|
||||
| tst.js:33:20:33:24 | "one" |
|
||||
| tst.js:33:27:33:31 | "two" |
|
||||
| tst.js:33:34:33:40 | "three" |
|
||||
| tst.js:37:12:37:18 | ["one"] |
|
||||
| tst.js:37:13:37:17 | "one" |
|
||||
| tst.js:40:10:40:20 | xs.join("") |
|
||||
| tst.js:44:12:44:20 | ["first"] |
|
||||
| tst.js:44:13:44:19 | "first" |
|
||||
| tst.js:49:10:49:20 | xs.join("") |
|
||||
| tst.js:53:10:53:34 | `one ${ ... three` |
|
||||
| tst.js:53:11:53:14 | one |
|
||||
| tst.js:53:17:53:17 | x |
|
||||
| tst.js:53:19:53:23 | two |
|
||||
| tst.js:53:26:53:26 | x |
|
||||
| tst.js:53:28:53:33 | three |
|
||||
| tst.js:61:10:61:34 | `first ... } last` |
|
||||
| tst.js:61:11:61:16 | first |
|
||||
| tst.js:61:19:61:19 | x |
|
||||
| tst.js:61:23:61:23 | x |
|
||||
| tst.js:61:27:61:27 | x |
|
||||
| tst.js:61:29:61:33 | last |
|
||||
| tst.js:87:5:87:5 | x |
|
||||
| tst.js:87:5:87:14 | x |
|
||||
| tst.js:87:5:87:14 | x += 'two' |
|
||||
| tst.js:87:10:87:14 | 'two' |
|
||||
| tst.js:89:3:89:3 | x |
|
||||
| tst.js:89:3:89:14 | x |
|
||||
| tst.js:89:3:89:14 | x += 'three' |
|
||||
| tst.js:89:8:89:14 | 'three' |
|
||||
operand
|
||||
| closure.js:5:1:5:37 | build(' ... 'four') | 0 | closure.js:5:7:5:11 | 'one' |
|
||||
| closure.js:5:1:5:37 | build(' ... 'four') | 1 | closure.js:5:14:5:28 | 'two' + 'three' |
|
||||
| closure.js:5:1:5:37 | build(' ... 'four') | 2 | closure.js:5:31:5:36 | 'four' |
|
||||
| closure.js:5:1:5:46 | build(' ... 'five' | 0 | closure.js:5:1:5:37 | build(' ... 'four') |
|
||||
| closure.js:5:1:5:46 | build(' ... 'five' | 1 | closure.js:5:41:5:46 | 'five' |
|
||||
| closure.js:5:14:5:28 | 'two' + 'three' | 0 | closure.js:5:14:5:18 | 'two' |
|
||||
| closure.js:5:14:5:28 | 'two' + 'three' | 1 | closure.js:5:22:5:28 | 'three' |
|
||||
| html-concat.js:2:14:2:26 | `<b>${x}</b>` | 0 | html-concat.js:2:15:2:17 | <b> |
|
||||
| html-concat.js:2:14:2:26 | `<b>${x}</b>` | 1 | html-concat.js:2:20:2:20 | x |
|
||||
| html-concat.js:2:14:2:26 | `<b>${x}</b>` | 2 | html-concat.js:2:22:2:25 | </b> |
|
||||
| html-concat.js:3:14:3:26 | `<B>${x}</B>` | 0 | html-concat.js:3:15:3:17 | <B> |
|
||||
| html-concat.js:3:14:3:26 | `<B>${x}</B>` | 1 | html-concat.js:3:20:3:20 | x |
|
||||
| html-concat.js:3:14:3:26 | `<B>${x}</B>` | 2 | html-concat.js:3:22:3:25 | </B> |
|
||||
| html-concat.js:5:21:5:47 | `Hey <s ... trong>` | 0 | html-concat.js:5:22:5:33 | Hey <strong> |
|
||||
| html-concat.js:5:21:5:47 | `Hey <s ... trong>` | 1 | html-concat.js:5:36:5:36 | x |
|
||||
| html-concat.js:5:21:5:47 | `Hey <s ... trong>` | 2 | html-concat.js:5:38:5:46 | </strong> |
|
||||
| html-concat.js:7:18:10:24 | `\\n H ... m!</i>` | 0 | html-concat.js:7:19:8:10 | \\n Hello |
|
||||
| html-concat.js:7:18:10:24 | `\\n H ... m!</i>` | 1 | html-concat.js:8:13:8:13 | x |
|
||||
| html-concat.js:7:18:10:24 | `\\n H ... m!</i>` | 2 | html-concat.js:8:15:10:23 | .\\n \\n ... um!</i> |
|
||||
| html-concat.js:13:3:13:18 | buffer | 0 | html-concat.js:13:3:13:8 | buffer |
|
||||
| html-concat.js:13:3:13:18 | buffer | 1 | html-concat.js:13:13:13:18 | '<li>' |
|
||||
| html-concat.js:13:3:13:18 | buffer += '<li>' | 0 | html-concat.js:13:3:13:8 | buffer |
|
||||
| html-concat.js:13:3:13:18 | buffer += '<li>' | 1 | html-concat.js:13:13:13:18 | '<li>' |
|
||||
| html-concat.js:14:3:14:13 | buffer | 0 | html-concat.js:14:3:14:8 | buffer |
|
||||
| html-concat.js:14:3:14:13 | buffer | 1 | html-concat.js:14:13:14:13 | x |
|
||||
| html-concat.js:14:3:14:13 | buffer += x | 0 | html-concat.js:14:3:14:8 | buffer |
|
||||
| html-concat.js:14:3:14:13 | buffer += x | 1 | html-concat.js:14:13:14:13 | x |
|
||||
| html-concat.js:15:3:15:15 | buffer | 0 | html-concat.js:15:3:15:8 | buffer |
|
||||
| html-concat.js:15:3:15:15 | buffer | 1 | html-concat.js:15:13:15:15 | '!' |
|
||||
| html-concat.js:15:3:15:15 | buffer += '!' | 0 | html-concat.js:15:3:15:8 | buffer |
|
||||
| html-concat.js:15:3:15:15 | buffer += '!' | 1 | html-concat.js:15:13:15:15 | '!' |
|
||||
| tst.js:3:3:3:12 | x | 0 | tst.js:3:3:3:3 | x |
|
||||
| tst.js:3:3:3:12 | x | 1 | tst.js:3:8:3:12 | "two" |
|
||||
| tst.js:3:3:3:12 | x += "two" | 0 | tst.js:3:3:3:3 | x |
|
||||
| tst.js:3:3:3:12 | x += "two" | 1 | tst.js:3:8:3:12 | "two" |
|
||||
| tst.js:4:3:4:14 | x | 0 | tst.js:4:3:4:3 | x |
|
||||
| tst.js:4:3:4:14 | x | 1 | tst.js:4:8:4:14 | "three" |
|
||||
| tst.js:4:3:4:14 | x += "three" | 0 | tst.js:4:3:4:3 | x |
|
||||
| tst.js:4:3:4:14 | x += "three" | 1 | tst.js:4:8:4:14 | "three" |
|
||||
| tst.js:5:3:5:13 | x | 0 | tst.js:5:3:5:3 | x |
|
||||
| tst.js:5:3:5:13 | x | 1 | tst.js:5:8:5:13 | "four" |
|
||||
| tst.js:5:3:5:13 | x += "four" | 0 | tst.js:5:3:5:3 | x |
|
||||
| tst.js:5:3:5:13 | x += "four" | 1 | tst.js:5:8:5:13 | "four" |
|
||||
| tst.js:12:5:12:26 | x | 0 | tst.js:12:5:12:5 | x |
|
||||
| tst.js:12:5:12:26 | x | 1 | tst.js:12:10:12:26 | "one" + y + "two" |
|
||||
| tst.js:12:5:12:26 | x += "o ... + "two" | 0 | tst.js:12:5:12:5 | x |
|
||||
| tst.js:12:5:12:26 | x += "o ... + "two" | 1 | tst.js:12:10:12:26 | "one" + y + "two" |
|
||||
| tst.js:12:10:12:18 | "one" + y | 0 | tst.js:12:10:12:14 | "one" |
|
||||
| tst.js:12:10:12:18 | "one" + y | 1 | tst.js:12:18:12:18 | y |
|
||||
| tst.js:12:10:12:26 | "one" + y + "two" | 0 | tst.js:12:10:12:18 | "one" + y |
|
||||
| tst.js:12:10:12:26 | "one" + y + "two" | 1 | tst.js:12:22:12:26 | "two" |
|
||||
| tst.js:14:3:14:13 | x | 0 | tst.js:14:3:14:3 | x |
|
||||
| tst.js:14:3:14:13 | x | 1 | tst.js:14:8:14:13 | "last" |
|
||||
| tst.js:14:3:14:13 | x += "last" | 0 | tst.js:14:3:14:3 | x |
|
||||
| tst.js:14:3:14:13 | x += "last" | 1 | tst.js:14:8:14:13 | "last" |
|
||||
| tst.js:19:11:19:23 | "one" + "two" | 0 | tst.js:19:11:19:15 | "one" |
|
||||
| tst.js:19:11:19:23 | "one" + "two" | 1 | tst.js:19:19:19:23 | "two" |
|
||||
| tst.js:20:3:20:25 | x | 0 | tst.js:20:3:20:3 | x |
|
||||
| tst.js:20:3:20:25 | x | 1 | tst.js:20:8:20:25 | ("three" + "four") |
|
||||
| tst.js:20:3:20:25 | x += (" ... "four") | 0 | tst.js:20:3:20:3 | x |
|
||||
| tst.js:20:3:20:25 | x += (" ... "four") | 1 | tst.js:20:8:20:25 | ("three" + "four") |
|
||||
| tst.js:20:9:20:24 | "three" + "four" | 0 | tst.js:20:9:20:15 | "three" |
|
||||
| tst.js:20:9:20:24 | "three" + "four" | 1 | tst.js:20:19:20:24 | "four" |
|
||||
| tst.js:21:10:21:19 | x + "five" | 0 | tst.js:21:10:21:10 | x |
|
||||
| tst.js:21:10:21:19 | x + "five" | 1 | tst.js:21:14:21:19 | "five" |
|
||||
| tst.js:25:10:25:32 | ["one", ... three"] | 0 | tst.js:25:11:25:15 | "one" |
|
||||
| tst.js:25:10:25:32 | ["one", ... three"] | 1 | tst.js:25:18:25:22 | "two" |
|
||||
| tst.js:25:10:25:32 | ["one", ... three"] | 2 | tst.js:25:25:25:31 | "three" |
|
||||
| tst.js:25:10:25:41 | ["one", ... oin("") | 0 | tst.js:25:10:25:32 | ["one", ... three"] |
|
||||
| tst.js:29:10:29:37 | Array(" ... three") | 0 | tst.js:29:16:29:20 | "one" |
|
||||
| tst.js:29:10:29:37 | Array(" ... three") | 1 | tst.js:29:23:29:27 | "two" |
|
||||
| tst.js:29:10:29:37 | Array(" ... three") | 2 | tst.js:29:30:29:36 | "three" |
|
||||
| tst.js:29:10:29:46 | Array(" ... oin("") | 0 | tst.js:29:10:29:37 | Array(" ... three") |
|
||||
| tst.js:33:10:33:41 | new Arr ... three") | 0 | tst.js:33:20:33:24 | "one" |
|
||||
| tst.js:33:10:33:41 | new Arr ... three") | 1 | tst.js:33:27:33:31 | "two" |
|
||||
| tst.js:33:10:33:41 | new Arr ... three") | 2 | tst.js:33:34:33:40 | "three" |
|
||||
| tst.js:33:10:33:50 | new Arr ... oin("") | 0 | tst.js:33:10:33:41 | new Arr ... three") |
|
||||
| tst.js:37:12:37:18 | ["one"] | 0 | tst.js:37:13:37:17 | "one" |
|
||||
| tst.js:40:10:40:20 | xs.join("") | 0 | tst.js:37:12:37:18 | ["one"] |
|
||||
| tst.js:44:12:44:20 | ["first"] | 0 | tst.js:44:13:44:19 | "first" |
|
||||
| tst.js:49:10:49:20 | xs.join("") | 0 | tst.js:44:12:44:20 | ["first"] |
|
||||
| tst.js:53:10:53:34 | `one ${ ... three` | 0 | tst.js:53:11:53:14 | one |
|
||||
| tst.js:53:10:53:34 | `one ${ ... three` | 1 | tst.js:53:17:53:17 | x |
|
||||
| tst.js:53:10:53:34 | `one ${ ... three` | 2 | tst.js:53:19:53:23 | two |
|
||||
| tst.js:53:10:53:34 | `one ${ ... three` | 3 | tst.js:53:26:53:26 | x |
|
||||
| tst.js:53:10:53:34 | `one ${ ... three` | 4 | tst.js:53:28:53:33 | three |
|
||||
| tst.js:61:10:61:34 | `first ... } last` | 0 | tst.js:61:11:61:16 | first |
|
||||
| tst.js:61:10:61:34 | `first ... } last` | 1 | tst.js:61:19:61:19 | x |
|
||||
| tst.js:61:10:61:34 | `first ... } last` | 2 | tst.js:61:23:61:23 | x |
|
||||
| tst.js:61:10:61:34 | `first ... } last` | 3 | tst.js:61:27:61:27 | x |
|
||||
| tst.js:61:10:61:34 | `first ... } last` | 4 | tst.js:61:29:61:33 | last |
|
||||
| tst.js:87:5:87:14 | x | 0 | tst.js:87:5:87:5 | x |
|
||||
| tst.js:87:5:87:14 | x | 1 | tst.js:87:10:87:14 | 'two' |
|
||||
| tst.js:87:5:87:14 | x += 'two' | 0 | tst.js:87:5:87:5 | x |
|
||||
| tst.js:87:5:87:14 | x += 'two' | 1 | tst.js:87:10:87:14 | 'two' |
|
||||
| tst.js:89:3:89:14 | x | 0 | tst.js:89:3:89:3 | x |
|
||||
| tst.js:89:3:89:14 | x | 1 | tst.js:89:8:89:14 | 'three' |
|
||||
| tst.js:89:3:89:14 | x += 'three' | 0 | tst.js:89:3:89:3 | x |
|
||||
| tst.js:89:3:89:14 | x += 'three' | 1 | tst.js:89:8:89:14 | 'three' |
|
||||
nextLeaf
|
||||
| closure.js:5:7:5:11 | 'one' | closure.js:5:14:5:18 | 'two' |
|
||||
| closure.js:5:14:5:18 | 'two' | closure.js:5:22:5:28 | 'three' |
|
||||
| closure.js:5:22:5:28 | 'three' | closure.js:5:31:5:36 | 'four' |
|
||||
| closure.js:5:31:5:36 | 'four' | closure.js:5:41:5:46 | 'five' |
|
||||
| html-concat.js:2:15:2:17 | <b> | html-concat.js:2:20:2:20 | x |
|
||||
| html-concat.js:2:20:2:20 | x | html-concat.js:2:22:2:25 | </b> |
|
||||
| html-concat.js:3:15:3:17 | <B> | html-concat.js:3:20:3:20 | x |
|
||||
| html-concat.js:3:20:3:20 | x | html-concat.js:3:22:3:25 | </B> |
|
||||
| html-concat.js:5:22:5:33 | Hey <strong> | html-concat.js:5:36:5:36 | x |
|
||||
| html-concat.js:5:36:5:36 | x | html-concat.js:5:38:5:46 | </strong> |
|
||||
| html-concat.js:7:19:8:10 | \\n Hello | html-concat.js:8:13:8:13 | x |
|
||||
| html-concat.js:8:13:8:13 | x | html-concat.js:8:15:10:23 | .\\n \\n ... um!</i> |
|
||||
| html-concat.js:13:3:13:8 | buffer | html-concat.js:13:13:13:18 | '<li>' |
|
||||
| html-concat.js:14:3:14:8 | buffer | html-concat.js:14:13:14:13 | x |
|
||||
| html-concat.js:15:3:15:8 | buffer | html-concat.js:15:13:15:15 | '!' |
|
||||
| tst.js:3:3:3:3 | x | tst.js:3:8:3:12 | "two" |
|
||||
| tst.js:4:3:4:3 | x | tst.js:4:8:4:14 | "three" |
|
||||
| tst.js:5:3:5:3 | x | tst.js:5:8:5:13 | "four" |
|
||||
| tst.js:12:5:12:5 | x | tst.js:12:10:12:14 | "one" |
|
||||
| tst.js:12:10:12:14 | "one" | tst.js:12:18:12:18 | y |
|
||||
| tst.js:12:18:12:18 | y | tst.js:12:22:12:26 | "two" |
|
||||
| tst.js:14:3:14:3 | x | tst.js:14:8:14:13 | "last" |
|
||||
| tst.js:19:11:19:15 | "one" | tst.js:19:19:19:23 | "two" |
|
||||
| tst.js:20:3:20:3 | x | tst.js:20:8:20:25 | ("three" + "four") |
|
||||
| tst.js:20:9:20:15 | "three" | tst.js:20:19:20:24 | "four" |
|
||||
| tst.js:21:10:21:10 | x | tst.js:21:14:21:19 | "five" |
|
||||
| tst.js:25:11:25:15 | "one" | tst.js:25:18:25:22 | "two" |
|
||||
| tst.js:25:18:25:22 | "two" | tst.js:25:25:25:31 | "three" |
|
||||
| tst.js:29:16:29:20 | "one" | tst.js:29:23:29:27 | "two" |
|
||||
| tst.js:29:23:29:27 | "two" | tst.js:29:30:29:36 | "three" |
|
||||
| tst.js:33:20:33:24 | "one" | tst.js:33:27:33:31 | "two" |
|
||||
| tst.js:33:27:33:31 | "two" | tst.js:33:34:33:40 | "three" |
|
||||
| tst.js:53:11:53:14 | one | tst.js:53:17:53:17 | x |
|
||||
| tst.js:53:17:53:17 | x | tst.js:53:19:53:23 | two |
|
||||
| tst.js:53:19:53:23 | two | tst.js:53:26:53:26 | x |
|
||||
| tst.js:53:26:53:26 | x | tst.js:53:28:53:33 | three |
|
||||
| tst.js:61:11:61:16 | first | tst.js:61:19:61:19 | x |
|
||||
| tst.js:61:19:61:19 | x | tst.js:61:23:61:23 | x |
|
||||
| tst.js:61:23:61:23 | x | tst.js:61:27:61:27 | x |
|
||||
| tst.js:61:27:61:27 | x | tst.js:61:29:61:33 | last |
|
||||
| tst.js:87:5:87:5 | x | tst.js:87:10:87:14 | 'two' |
|
||||
| tst.js:89:3:89:3 | x | tst.js:89:8:89:14 | 'three' |
|
||||
htmlRoot
|
||||
| html-concat.js:2:14:2:26 | `<b>${x}</b>` |
|
||||
| html-concat.js:3:14:3:26 | `<B>${x}</B>` |
|
||||
| html-concat.js:5:21:5:47 | `Hey <s ... trong>` |
|
||||
| html-concat.js:7:18:10:24 | `\\n H ... m!</i>` |
|
||||
| html-concat.js:13:3:13:18 | buffer |
|
||||
| html-concat.js:13:3:13:18 | buffer += '<li>' |
|
||||
htmlLeaf
|
||||
| html-concat.js:2:15:2:17 | <b> |
|
||||
| html-concat.js:2:20:2:20 | x |
|
||||
| html-concat.js:2:22:2:25 | </b> |
|
||||
| html-concat.js:3:15:3:17 | <B> |
|
||||
| html-concat.js:3:20:3:20 | x |
|
||||
| html-concat.js:3:22:3:25 | </B> |
|
||||
| html-concat.js:5:22:5:33 | Hey <strong> |
|
||||
| html-concat.js:5:36:5:36 | x |
|
||||
| html-concat.js:5:38:5:46 | </strong> |
|
||||
| html-concat.js:7:19:8:10 | \\n Hello |
|
||||
| html-concat.js:8:13:8:13 | x |
|
||||
| html-concat.js:8:15:10:23 | .\\n \\n ... um!</i> |
|
||||
| html-concat.js:13:3:13:8 | buffer |
|
||||
| html-concat.js:13:13:13:18 | '<li>' |
|
||||
@@ -0,0 +1,17 @@
|
||||
import javascript
|
||||
|
||||
query StringOps::Concatenation concatenation() { any() }
|
||||
query StringOps::ConcatenationOperand concatenationOperand() { any() }
|
||||
query StringOps::ConcatenationLeaf concatenationLeaf() { any() }
|
||||
query StringOps::ConcatenationNode concatenationNode() { any() }
|
||||
|
||||
query predicate operand(StringOps::ConcatenationNode node, int i, DataFlow::Node child) {
|
||||
child = node.getOperand(i)
|
||||
}
|
||||
|
||||
query predicate nextLeaf(StringOps::ConcatenationNode node, DataFlow::Node next) {
|
||||
next = node.getNextLeaf()
|
||||
}
|
||||
|
||||
query StringOps::HtmlConcatenationRoot htmlRoot() { any() }
|
||||
query StringOps::HtmlConcatenationLeaf htmlLeaf() { any() }
|
||||
@@ -0,0 +1,18 @@
|
||||
function f(x, y) {
|
||||
let bold = `<b>${x}</b>`;
|
||||
let Bold = `<B>${x}</B>`;
|
||||
|
||||
let longTagName = `Hey <strong>${x}</strong>`;
|
||||
|
||||
let longText = `
|
||||
Hello ${x}.
|
||||
|
||||
<i>Lorem ipsum!</i>`;
|
||||
|
||||
let buffer = '';
|
||||
buffer += '<li>';
|
||||
buffer += x;
|
||||
buffer += '!';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
Reference in New Issue
Block a user