Merge pull request #6403 from asgerf/js/handlebars-extraction

Approved by erik-krogh
This commit is contained in:
CodeQL CI
2021-08-25 13:54:52 +01:00
committed by GitHub
90 changed files with 8657 additions and 1588 deletions

View File

@@ -0,0 +1,6 @@
lgtm,codescanning
* Added support for more templating languages.
- EJS, Mustache, Handlebars, Nunjucks, Hogan, and Swig are now supported.
- Template tags from the above dialects are now recognized as sinks
when not escaped safely for the context, leading to additional results for `js/xss` and `js/code-injection`.
- Files with the extension `.ejs`, `.hbs`, or `.njk` are now extracted and analyzed.

View File

@@ -39,7 +39,7 @@ public class Options {
Position endLoc);
}
private boolean allowHashBang, allowReturnOutsideFunction, allowImportExportEverywhere;
private boolean allowHashBang, allowReturnOutsideFunction, allowImportExportEverywhere, allowGeneratedCodeExprs;
private boolean preserveParens, mozExtensions, jscript, esnext, v8Extensions, e4x;
private int ecmaVersion;
private AllowReserved allowReserved;
@@ -58,6 +58,7 @@ public class Options {
this.allowReserved = AllowReserved.YES;
this.allowReturnOutsideFunction = false;
this.allowImportExportEverywhere = false;
this.allowGeneratedCodeExprs = true;
this.allowHashBang = false;
this.onToken = null;
this.onComment = null;
@@ -75,6 +76,7 @@ public class Options {
this.allowHashBang = that.allowHashBang;
this.allowReturnOutsideFunction = that.allowReturnOutsideFunction;
this.allowImportExportEverywhere = that.allowImportExportEverywhere;
this.allowGeneratedCodeExprs = that.allowGeneratedCodeExprs;
this.preserveParens = that.preserveParens;
this.mozExtensions = that.mozExtensions;
this.jscript = that.jscript;
@@ -104,6 +106,10 @@ public class Options {
return allowImportExportEverywhere;
}
public boolean allowGeneratedCodeExprs() {
return allowGeneratedCodeExprs;
}
public boolean preserveParens() {
return preserveParens;
}

View File

@@ -52,6 +52,7 @@ import com.semmle.js.ast.ForOfStatement;
import com.semmle.js.ast.ForStatement;
import com.semmle.js.ast.FunctionDeclaration;
import com.semmle.js.ast.FunctionExpression;
import com.semmle.js.ast.GeneratedCodeExpr;
import com.semmle.js.ast.IFunction;
import com.semmle.js.ast.INode;
import com.semmle.js.ast.IPattern;
@@ -537,7 +538,7 @@ public class Parser {
}
return this.finishOp(TokenType.questionquestion, 2);
}
}
return this.finishOp(TokenType.question, 1);
}
@@ -617,6 +618,15 @@ public class Parser {
this.skipSpace();
return this.nextToken();
}
if (next == '%' && code == '<' && this.options.allowGeneratedCodeExprs()) {
// `<%`, the beginning of an EJS-style template tag
size = 2;
int nextNext = charAt(this.pos + 2);
if (nextNext == '=' || nextNext == '-') {
++size;
}
return this.finishOp(TokenType.generatedCodeDelimiterEJS, size);
}
if (next == 61) size = 2;
return this.finishOp(TokenType.relational, size);
}
@@ -1688,6 +1698,9 @@ public class Parser {
return this.parseNew();
} else if (this.type == TokenType.backQuote) {
return this.parseTemplate(false);
} else if (this.type == TokenType.generatedCodeDelimiterEJS) {
String openingDelimiter = (String) this.value;
return this.parseGeneratedCodeExpr(this.startLoc, openingDelimiter, "%>");
} else {
this.unexpected();
return null;
@@ -1929,10 +1942,16 @@ public class Parser {
// Parse an object literal or binding pattern.
protected Expression parseObj(boolean isPattern, DestructuringErrors refDestructuringErrors) {
Position startLoc = this.startLoc;
if (!isPattern && options.allowGeneratedCodeExprs() && charAt(pos) == '{') {
// Parse mustache-style placeholder expression: {{ ... }} or {{{ ... }}}
return charAt(pos + 1) == '{'
? parseGeneratedCodeExpr(startLoc, "{{{", "}}}")
: parseGeneratedCodeExpr(startLoc, "{{", "}}");
}
boolean first = true;
Map<String, PropInfo> propHash = new LinkedHashMap<>();
List<Property> properties = new ArrayList<Property>();
this.next();
this.next(); // skip '{'
while (!this.eat(TokenType.braceR)) {
if (!first) {
this.expect(TokenType.comma);
@@ -1949,6 +1968,42 @@ public class Parser {
return this.finishNode(node);
}
/** Emit a token ranging from the current position until <code>endOfToken</code>. */
private Token generateTokenEndingAt(int endOfToken, TokenType tokenType) {
this.lastTokEnd = this.end;
this.lastTokStart = this.start;
this.lastTokEndLoc = this.endLoc;
this.lastTokStartLoc = this.startLoc;
this.start = this.pos;
this.startLoc = this.curPosition();
this.pos = endOfToken;
return finishToken(tokenType);
}
/** Parse a generated expression. The current token refers to the opening delimiter. */
protected Expression parseGeneratedCodeExpr(Position startLoc, String openingDelimiter, String closingDelimiter) {
// Emit a token for what's left of the opening delimiter, if there are any remaining characters
int startOfBody = startLoc.getOffset() + openingDelimiter.length();
if (this.pos != startOfBody) {
this.generateTokenEndingAt(startOfBody, TokenType.generatedCodeDelimiter);
}
// Emit a token for the generated code body
int endOfBody = this.input.indexOf(closingDelimiter, startOfBody);
if (endOfBody == -1) {
this.unexpected(startLoc);
}
Token bodyToken = this.generateTokenEndingAt(endOfBody, TokenType.generatedCodeExpr);
// Emit a token for the closing delimiter
this.generateTokenEndingAt(endOfBody + closingDelimiter.length(), TokenType.generatedCodeDelimiter);
this.next(); // produce lookahead token
return finishNode(new GeneratedCodeExpr(new SourceLocation(startLoc), openingDelimiter, closingDelimiter,
bodyToken.getValue()));
}
protected Property parseProperty(
boolean isPattern,
DestructuringErrors refDestructuringErrors,

View File

@@ -1,9 +1,10 @@
package com.semmle.jcorn;
import com.semmle.jcorn.Parser.TokContext;
import java.util.LinkedHashMap;
import java.util.Map;
import com.semmle.jcorn.Parser.TokContext;
/// tokentype.js
// ## Token types
@@ -89,6 +90,9 @@ public class TokenType {
arrow = new TokenType(new Properties("=>").beforeExpr()),
template = new TokenType(new Properties("template")),
invalidTemplate = new TokenType(new Properties("invalidTemplate")),
generatedCodeExpr = new TokenType(new Properties("generatedCodeExpr")),
generatedCodeDelimiter = new TokenType(new Properties("generatedCodeDelimiter")),
generatedCodeDelimiterEJS = new TokenType(new Properties("<%/%>")),
ellipsis = new TokenType(new Properties("...").beforeExpr()),
backQuote =
new TokenType(new Properties("`").startsExpr()) {

View File

@@ -420,8 +420,9 @@ public class JSXParser extends Parser {
&& code == 60
&& this.exprAllowed
&&
// avoid getting confused on HTML comments
this.charAt(this.pos + 1) != '!') {
// avoid getting confused on HTML comments or EJS-style template tags
this.charAt(this.pos + 1) != '!' &&
this.charAt(this.pos + 1) != '%') {
++this.pos;
return this.finishToken(jsxTagStart);
}

View File

@@ -777,4 +777,9 @@ public class DefaultVisitor<C, R> implements Visitor<C, R> {
public R visit(XMLDotDotExpression nd, C c) {
return visit((Expression) nd, c);
}
@Override
public R visit(GeneratedCodeExpr nd, C c) {
return visit((Expression) nd, c);
}
}

View File

@@ -0,0 +1,45 @@
package com.semmle.js.ast;
/**
* A placeholder for generated code, speculatively parsed as a primary expression.
*
* <p>For example, in this snippet,
*
* <pre>
* let data = {{user_data}};
* </pre>
*
* the expression <code>{{user_data}}</code> is assumed to be filled in by a templating engine so
* that it can be parsed as an expression, and a <code>GeneratedCodeExpr</code> is thus created to
* represent it.
*/
public class GeneratedCodeExpr extends Expression {
private String openingDelimiter;
private String closingDelimiter;
private String body;
public GeneratedCodeExpr(
SourceLocation loc, String openingDelimiter, String closingDelimiter, String body) {
super("GeneratedCodeExpr", loc);
this.openingDelimiter = openingDelimiter;
this.closingDelimiter = closingDelimiter;
this.body = body;
}
public String getOpeningDelimiter() {
return openingDelimiter;
}
public String getClosingDelimiter() {
return closingDelimiter;
}
public String getBody() {
return body;
}
@Override
public <C, R> R accept(Visitor<C, R> v, C c) {
return v.visit(this, c);
}
}

View File

@@ -894,4 +894,9 @@ public class NodeCopier implements Visitor<Void, INode> {
public INode visit(XMLDotDotExpression nd, Void c) {
return new XMLDotDotExpression(visit(nd.getLoc()), copy(nd.getLeft()), copy(nd.getRight()));
}
@Override
public INode visit(GeneratedCodeExpr nd, Void c) {
return new GeneratedCodeExpr(visit(nd.getLoc()), nd.getOpeningDelimiter(), nd.getClosingDelimiter(), nd.getBody());
}
}

View File

@@ -313,4 +313,6 @@ public interface Visitor<C, R> {
public R visit(XMLQualifiedIdentifier nd, C c);
public R visit(XMLDotDotExpression nd, C c);
public R visit(GeneratedCodeExpr generatedCodeExpr, C c);
}

View File

@@ -6,6 +6,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Matcher;
import com.semmle.js.ast.AClass;
import com.semmle.js.ast.AFunction;
@@ -45,6 +46,7 @@ import com.semmle.js.ast.ForOfStatement;
import com.semmle.js.ast.ForStatement;
import com.semmle.js.ast.FunctionDeclaration;
import com.semmle.js.ast.FunctionExpression;
import com.semmle.js.ast.GeneratedCodeExpr;
import com.semmle.js.ast.IFunction;
import com.semmle.js.ast.INode;
import com.semmle.js.ast.IPattern;
@@ -172,7 +174,8 @@ public class ASTExtractor {
private final RegExpExtractor regexpExtractor;
private final ExtractorConfig config;
public ASTExtractor(ExtractorConfig config, LexicalExtractor lexicalExtractor, ScopeManager scopeManager) {
public ASTExtractor(
ExtractorConfig config, LexicalExtractor lexicalExtractor, ScopeManager scopeManager) {
this.config = config;
this.trapwriter = lexicalExtractor.getTrapwriter();
this.locationManager = lexicalExtractor.getLocationManager();
@@ -180,22 +183,22 @@ public class ASTExtractor {
this.scopeManager = scopeManager;
this.lexicalExtractor = lexicalExtractor;
this.regexpExtractor = new RegExpExtractor(trapwriter, locationManager);
this.toplevelLabel = makeTopLevelLabel(trapwriter, locationManager.getFileLabel(), locationManager.getStartLine(), locationManager.getStartColumn());
this.toplevelLabel =
makeTopLevelLabel(
trapwriter,
locationManager.getFileLabel(),
locationManager.getStartLine(),
locationManager.getStartColumn());
}
/**
* Returns the label for the top-level starting at the given location.
* <p>
* May be used to refer to the top-level before it has been extracted.
*
* <p>May be used to refer to the top-level before it has been extracted.
*/
public static Label makeTopLevelLabel(TrapWriter trapWriter, Label fileLabel, int startLine, int startColumn) {
return trapWriter.globalID(
"script;{"
+ fileLabel
+ "},"
+ startLine
+ ','
+ startColumn);
public static Label makeTopLevelLabel(
TrapWriter trapWriter, Label fileLabel, int startLine, int startColumn) {
return trapWriter.globalID("script;{" + fileLabel + "}," + startLine + ',' + startColumn);
}
public TrapWriter getTrapwriter() {
@@ -252,8 +255,8 @@ public class ASTExtractor {
TYPE_LABEL,
/**
* An identifier that refers to a variable from inside a type, i.e. the operand to a
* <code>typeof</code> type or left operand to an <code>is</code> type.
* An identifier that refers to a variable from inside a type, i.e. the operand to a <code>
* typeof</code> type or left operand to an <code>is</code> type.
*
* <p>This is generally treated as a type, except a variable binding will be emitted for it.
*/
@@ -271,16 +274,16 @@ public class ASTExtractor {
/**
* An identifier that occurs in a type-only import.
*
* These may declare a type and/or a namespace, but for compatibility with our AST,
* must be emitted as a VarDecl (with no variable binding).
* <p>These may declare a type and/or a namespace, but for compatibility with our AST, must be
* emitted as a VarDecl (with no variable binding).
*/
TYPE_ONLY_IMPORT,
/**
* An identifier that occurs in a type-only export.
*
* These may refer to a type and/or a namespace, but for compatibility with our AST,
* must be emitted as an ExportVarAccess (with no variable binding).
* <p>These may refer to a type and/or a namespace, but for compatibility with our AST, must be
* emitted as an ExportVarAccess (with no variable binding).
*/
TYPE_ONLY_EXPORT,
@@ -300,8 +303,8 @@ public class ASTExtractor {
EXPORT,
/**
* An identifier that occurs as a qualified name in a default export expression, such as
* <code>A</code> in <code>export default A.B</code>.
* An identifier that occurs as a qualified name in a default export expression, such as <code>A
* </code> in <code>export default A.B</code>.
*
* <p>This acts like {@link #EXPORT}, except it cannot refer to a type (i.e. it must be a
* variable and/or a namespace).
@@ -312,8 +315,8 @@ public class ASTExtractor {
* True if this occurs as part of a type annotation, i.e. it is {@link #TYPE_BIND} or {@link
* #TYPE_DECL}, {@link #TYPE_LABEL}, {@link #VAR_IN_TYPE_BIND}, or {@link #NAMESPACE_BIND}.
*
* <p>Does not hold for {@link #VAR_AND_TYPE_DECL}, {@link #TYPE_ONLY_IMPORT}, or @{link {@link #TYPE_ONLY_EXPORT}
* as these do not occur in type annotations.
* <p>Does not hold for {@link #VAR_AND_TYPE_DECL}, {@link #TYPE_ONLY_IMPORT}, or @{link {@link
* #TYPE_ONLY_EXPORT} as these do not occur in type annotations.
*/
public boolean isInsideType() {
return this == TYPE_BIND
@@ -569,6 +572,18 @@ public class ASTExtractor {
regexpExtractor.extract(source.substring(1, source.lastIndexOf('/')), offsets, nd, false);
} else if (nd.isStringLiteral() && !c.isInsideType() && nd.getRaw().length() < 1000) {
regexpExtractor.extract(valueString, makeStringLiteralOffsets(nd.getRaw()), nd, true);
// Scan the string for template tags, if we're in a context where such tags are relevant.
if (scopeManager.isInTemplateFile()) {
Matcher m = TemplateEngines.TEMPLATE_TAGS.matcher(nd.getRaw());
int offset = nd.getLoc().getStart().getOffset();
while (m.find()) {
Label locationLbl =
TemplateEngines.makeLocation(
lexicalExtractor.getTextualExtractor(), offset + m.start(), offset + m.end());
trapwriter.addTuple("expr_contains_template_tag_location", key, locationLbl);
}
}
}
return key;
}
@@ -704,7 +719,8 @@ public class ASTExtractor {
+ locationManager.getStartLine()
+ ","
+ locationManager.getStartColumn());
Scope moduleScope = scopeManager.enterScope(ScopeKind.MODULE, moduleScopeKey, toplevelLabel);
Scope moduleScope =
scopeManager.enterScope(ScopeKind.MODULE, moduleScopeKey, toplevelLabel);
if (sourceType.hasNoGlobalScope()) {
scopeManager.setImplicitVariableScope(moduleScope);
}
@@ -732,7 +748,10 @@ public class ASTExtractor {
visitAll(nd.getBody(), toplevelLabel);
// Leave the local scope again.
if (sourceType.hasLocalScope()) scopeManager.leaveScope();
if (sourceType.hasLocalScope()) {
scopeManager.leaveScope();
scopeManager.resetImplicitVariableScope();
}
contextManager.leaveContainer();
@@ -1159,13 +1178,11 @@ public class ASTExtractor {
if (!nd.isComputed() && "template".equals(tryGetIdentifierName(nd.getKey()))) {
extractStringValueAsHtml(nd.getValue(), valueLabel);
}
return propkey;
}
/**
* Extracts the string value of <code>expr</code> as an HTML snippet.
*/
/** Extracts the string value of <code>expr</code> as an HTML snippet. */
private void extractStringValueAsHtml(Expression expr, Label exprLabel) {
TextualExtractor textualExtractor = lexicalExtractor.getTextualExtractor();
if (textualExtractor.isSnippet()) {
@@ -1178,16 +1195,21 @@ public class ASTExtractor {
String source = sourceAndOffset.fst();
SourceLocation loc = expr.getLoc();
Path originalFile = textualExtractor.getExtractedFile().toPath();
Path vfile = originalFile.resolveSibling(originalFile.getFileName().toString() + "." + loc.getStart().getLine() + "." + loc.getStart().getColumn() + ".html");
SourceMap sourceMap = textualExtractor.getSourceMap().offsetBy(loc.getStart().getOffset(), sourceAndOffset.snd());
TextualExtractor innerTextualExtractor = new TextualExtractor(
trapwriter,
locationManager,
source,
false,
getMetrics(),
vfile.toFile(),
sourceMap);
Path vfile =
originalFile.resolveSibling(
originalFile.getFileName().toString()
+ "."
+ loc.getStart().getLine()
+ "."
+ loc.getStart().getColumn()
+ ".html");
SourceMap sourceMap =
textualExtractor
.getSourceMap()
.offsetBy(loc.getStart().getOffset(), sourceAndOffset.snd());
TextualExtractor innerTextualExtractor =
new TextualExtractor(
trapwriter, locationManager, source, false, getMetrics(), vfile.toFile(), sourceMap);
HTMLExtractor html = HTMLExtractor.forEmbeddedHtml(config);
List<Label> rootNodes = html.extractEx(innerTextualExtractor).fst();
int rootNodeIndex = 0;
@@ -1197,7 +1219,7 @@ public class ASTExtractor {
}
private String tryGetIdentifierName(Expression e) {
return e instanceof Identifier ? ((Identifier)e).getName() : null;
return e instanceof Identifier ? ((Identifier) e).getName() : null;
}
private Pair<String, OffsetTranslation> tryGetStringValueFromExpression(Expression e) {
@@ -1217,7 +1239,8 @@ public class ASTExtractor {
return null;
}
TemplateElement element = lit.getQuasis().get(0);
return Pair.make((String) element.getCooked(), makeStringLiteralOffsets("`" + element.getRaw() + "`"));
return Pair.make(
(String) element.getCooked(), makeStringLiteralOffsets("`" + element.getRaw() + "`"));
}
return null;
}
@@ -1662,9 +1685,9 @@ public class ASTExtractor {
visit(nd.getDeclaration(), lbl, -1);
visit(nd.getSource(), lbl, -2);
IdContext childContext =
nd.hasSource() ? IdContext.LABEL :
nd.hasTypeKeyword() ? IdContext.TYPE_ONLY_EXPORT :
IdContext.EXPORT;
nd.hasSource()
? IdContext.LABEL
: nd.hasTypeKeyword() ? IdContext.TYPE_ONLY_EXPORT : IdContext.EXPORT;
visitAll(nd.getSpecifiers(), lbl, childContext, 0);
if (nd.hasTypeKeyword()) {
trapwriter.addTuple("has_type_keyword", lbl);
@@ -1684,7 +1707,10 @@ public class ASTExtractor {
public Label visit(ImportDeclaration nd, Context c) {
Label lbl = super.visit(nd, c);
visit(nd.getSource(), lbl, -1);
IdContext childContext = nd.hasTypeKeyword() ? IdContext.TYPE_ONLY_IMPORT : IdContext.VAR_AND_TYPE_AND_NAMESPACE_DECL;
IdContext childContext =
nd.hasTypeKeyword()
? IdContext.TYPE_ONLY_IMPORT
: IdContext.VAR_AND_TYPE_AND_NAMESPACE_DECL;
visitAll(nd.getSpecifiers(), lbl, childContext, 0);
emitNodeSymbol(nd, lbl);
if (nd.hasTypeKeyword()) {
@@ -2217,6 +2243,18 @@ public class ASTExtractor {
visit(nd.getIdentifier(), key, 0, IdContext.LABEL);
return key;
}
@Override
public Label visit(GeneratedCodeExpr nd, Context c) {
Label key = super.visit(nd, c);
Label templateLbl =
TemplateEngines.makeLocation(
lexicalExtractor.getTextualExtractor(),
nd.getLoc().getStart().getOffset(),
nd.getLoc().getEnd().getOffset());
trapwriter.addTuple("expr_contains_template_tag_location", key, templateLbl);
return key;
}
}
public List<ParseError> extract(

View File

@@ -149,6 +149,7 @@ public class ExprKinds {
exprKinds.put("ExternalModuleReference", 98);
exprKinds.put("NonNullAssertion", 105);
exprKinds.put("AngularPipeRef", 119);
exprKinds.put("GeneratedCodeExpr", 120);
}
private static final Map<IdContext, Integer> idKinds =

View File

@@ -82,8 +82,8 @@ public class ExtractorConfig {
/** A CommonJS module that is not also an ES2015 module. */
COMMONJS_MODULE,
/** An Angular template expression. */
ANGULAR_TEMPLATE,
/** A template expression, using a dialect similar to that of Angular. */
ANGULAR_STYLE_TEMPLATE,
/** Automatically determined source type. */
AUTO;
@@ -98,7 +98,7 @@ public class ExtractorConfig {
*/
public Parser createParser(Options options, String input, int startPos) {
switch (this) {
case ANGULAR_TEMPLATE:
case ANGULAR_STYLE_TEMPLATE:
return new AngularExpressionParser(options, input, startPos);
default:
return new CustomParser(options, input, startPos);
@@ -118,7 +118,7 @@ public class ExtractorConfig {
* variables are implicitly declared in its local scope. Implies {@link #hasLocalScope()}.
*/
public boolean hasNoGlobalScope() {
return this == ANGULAR_TEMPLATE;
return this == ANGULAR_STYLE_TEMPLATE;
}
/** Returns true if this source is implicitly in strict mode. */

View File

@@ -104,7 +104,7 @@ public class FileExtractor {
/** Information about supported file types. */
public static enum FileType {
HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue") {
HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue", ".hbs", ".ejs", ".njk") {
@Override
public IExtractor mkExtractor(ExtractorConfig config, ExtractorState state) {
return new HTMLExtractor(config, state);
@@ -114,6 +114,14 @@ public class FileExtractor {
public String toString() {
return "html";
}
@Override
protected boolean contains(File f, String lcExt, ExtractorConfig config) {
if (isBinaryFile(f, lcExt, config)) {
return false;
}
return super.contains(f, lcExt, config);
}
},
JS(".js", ".jsx", ".mjs", ".cjs", ".es6", ".es") {
@@ -152,32 +160,6 @@ public class FileExtractor {
public String toString() {
return "javascript";
}
/** Number of bytes to read from the beginning of a ".js" file to detect if it is a binary file. */
private static final int fileHeaderSize = 128;
/** Computes if `f` is a binary file based on whether the initial `fileHeaderSize` bytes are printable UTF-8 chars. */
private boolean isBinaryFile(File f, String lcExt, ExtractorConfig config) {
if (!config.getDefaultEncoding().equals(StandardCharsets.UTF_8.name())) {
return false;
}
try (FileInputStream fis = new FileInputStream(f)) {
byte[] bytes = new byte[fileHeaderSize];
int length = fis.read(bytes);
if (length == -1) return false;
// Avoid invalid or unprintable UTF-8 files.
if (hasUnprintableUtf8(bytes, length)) {
return true;
}
return false;
} catch (IOException e) {
Exceptions.ignore(e, "Let extractor handle this one.");
}
return false;
}
},
JSON(".json") {
@@ -234,9 +216,6 @@ public class FileExtractor {
return super.contains(f, lcExt, config);
}
/** Number of bytes to read from the beginning of a ".ts" file for sniffing its file type. */
private static final int fileHeaderSize = 128;
private boolean hasBadFileHeader(File f, String lcExt, ExtractorConfig config) {
if (!".ts".equals(lcExt)) {
return false;
@@ -348,6 +327,9 @@ public class FileExtractor {
}
};
/** Number of bytes to read from the beginning of a file to sniff its file type. */
private static final int fileHeaderSize = 128;
/** The file extensions (lower-case, including leading dot) corresponding to this file type. */
private final Set<String> extensions = new LinkedHashSet<String>();
@@ -398,6 +380,29 @@ public class FileExtractor {
return true;
}
/** Computes if `f` is a binary file based on whether the initial `fileHeaderSize` bytes are printable UTF-8 chars. */
public static boolean isBinaryFile(File f, String lcExt, ExtractorConfig config) {
if (!config.getDefaultEncoding().equals(StandardCharsets.UTF_8.name())) {
return false;
}
try (FileInputStream fis = new FileInputStream(f)) {
byte[] bytes = new byte[fileHeaderSize];
int length = fis.read(bytes);
if (length == -1) return false;
// Avoid invalid or unprintable UTF-8 files.
if (hasUnprintableUtf8(bytes, length)) {
return true;
}
return false;
} catch (IOException e) {
Exceptions.ignore(e, "Let extractor handle this one.");
}
return false;
}
/** The names of all defined {@linkplain FileType}s. */
public static final Set<String> allNames = new LinkedHashSet<String>();

View File

@@ -4,10 +4,12 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.semmle.extractor.html.HtmlPopulator;
import com.semmle.js.extractor.ExtractorConfig.ECMAVersion;
import com.semmle.js.extractor.ExtractorConfig.Platform;
import com.semmle.js.extractor.ExtractorConfig.SourceType;
import com.semmle.js.parser.ParseError;
@@ -24,6 +26,7 @@ import net.htmlparser.jericho.Attributes;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;
/** Extractor for handling HTML and XHTML files. */
public class HTMLExtractor implements IExtractor {
@@ -32,12 +35,12 @@ public class HTMLExtractor implements IExtractor {
private class JavaScriptHTMLElementHandler implements HtmlPopulator.ElementHandler {
private final ScopeManager scopeManager;
private final TextualExtractor textualExtractor;
public JavaScriptHTMLElementHandler(TextualExtractor textualExtractor) {
this.textualExtractor = textualExtractor;
this.scopeManager =
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion());
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion(), true);
}
/*
@@ -81,8 +84,7 @@ public class HTMLExtractor implements IExtractor {
source,
content.getBegin(),
isTypeScript,
elt,
context);
context.getNodeLabel(elt));
}
}
} else {
@@ -93,6 +95,13 @@ public class HTMLExtractor implements IExtractor {
// ignore empty attributes
if (attr.getValue() == null || attr.getValue().isEmpty()) continue;
extractTemplateTags(
textualExtractor,
attr.getSource(),
attr.getBegin(),
attr.getEnd(),
() -> context.getNodeLabel(attr));
String source = attr.getValue();
int valueStart = attr.getValueSegment().getBegin();
if (JS_ATTRIBUTE.matcher(attr.getName()).matches()) {
@@ -104,8 +113,7 @@ public class HTMLExtractor implements IExtractor {
source,
valueStart,
false /* isTypeScript */,
attr,
context);
context.getNodeLabel(attr));
} else if (isAngularTemplateAttributeName(attr.getName())) {
// For an attribute *ngFor="let var of EXPR", start parsing at EXPR
int offset = 0;
@@ -118,15 +126,14 @@ public class HTMLExtractor implements IExtractor {
}
}
extractSnippet(
TopLevelKind.ANGULAR_TEMPLATE,
config.withSourceType(SourceType.ANGULAR_TEMPLATE),
TopLevelKind.ANGULAR_STYLE_TEMPLATE,
config.withSourceType(SourceType.ANGULAR_STYLE_TEMPLATE),
scopeManager,
textualExtractor,
source,
valueStart + offset,
false /* isTypeScript */,
attr,
context);
context.getNodeLabel(attr));
} else if (source.startsWith("javascript:")) {
source = source.substring(11);
extractSnippet(
@@ -137,13 +144,18 @@ public class HTMLExtractor implements IExtractor {
source,
valueStart + 11,
false /* isTypeScript */,
attr,
context);
context.getNodeLabel(attr));
}
}
}
}
@Override
public void handleText(
Source src, int textBegin, int textEnd, Label parentLabel, boolean isCData) {
extractTemplateTags(textualExtractor, src, textBegin, textEnd, () -> parentLabel);
}
@Override
public boolean shouldExtractAttributes(Element element) {
Attributes attributes = element.getAttributes();
@@ -158,14 +170,16 @@ public class HTMLExtractor implements IExtractor {
}
private boolean isAngularTemplateAttributeName(String name) {
return name.startsWith("[") && name.endsWith("]") ||
name.startsWith("(") && name.endsWith(")") ||
name.startsWith("*ng");
return name.startsWith("[") && name.endsWith("]")
|| name.startsWith("(") && name.endsWith(")")
|| name.startsWith("*ng");
}
private static final Pattern ANGULAR_FOR_LOOP_DECL = Pattern.compile("^ *let +(\\w+) +of(?: +|(?!\\w))(.*)");
private static final Pattern ANGULAR_FOR_LOOP_DECL =
Pattern.compile("^ *let +(\\w+) +of(?: +|(?!\\w))(.*)");
private static final Pattern VALID_ATTRIBUTE_NAME = Pattern.compile("\\*?\\[?\\(?[\\w:_\\-]+\\]?\\)?");
private static final Pattern VALID_ATTRIBUTE_NAME =
Pattern.compile("\\*?\\[?\\(?[\\w:_\\-]+\\]?\\)?");
/** List of HTML attributes whose value is interpreted as JavaScript. */
private static final Pattern JS_ATTRIBUTE =
@@ -191,15 +205,17 @@ public class HTMLExtractor implements IExtractor {
public static HTMLExtractor forEmbeddedHtml(ExtractorConfig config) {
return new HTMLExtractor(config, null, true);
}
@Override
public LoCInfo extract(TextualExtractor textualExtractor) throws IOException {
return extractEx(textualExtractor).snd();
}
public Pair<List<Label>, LoCInfo> extractEx(TextualExtractor textualExtractor) {
// Angular templates contain attribute names that are not valid HTML/XML, such as [foo], (foo), [(foo)], and *foo.
// Allow a large number of errors in attribute names, so the Jericho parser does not give up.
// Angular templates contain attribute names that are not valid HTML/XML, such
// as [foo], (foo), [(foo)], and *foo.
// Allow a large number of errors in attribute names, so the Jericho parser does
// not give up.
Attributes.setDefaultMaxErrorCount(100);
JavaScriptHTMLElementHandler eltHandler = new JavaScriptHTMLElementHandler(textualExtractor);
@@ -211,7 +227,8 @@ public class HTMLExtractor implements IExtractor {
textualExtractor.getTrapwriter(),
locationManager.getFileLabel());
// For efficiency, avoid building the source map if not needed (i.e. for plain HTML files).
// For efficiency, avoid building the source map if not needed (i.e. for plain
// HTML files).
if (textualExtractor.hasNonTrivialSourceMap()) {
extractor.setSourceMap(textualExtractor.getSourceMap());
}
@@ -271,7 +288,8 @@ public class HTMLExtractor implements IExtractor {
private boolean isTypeScriptTag(Element script) {
String language = getScriptLanguage(script);
if ("ts".equals(language) || "tsx".equals(language) || "typescript".equals(language)) return true;
if ("ts".equals(language) || "tsx".equals(language) || "typescript".equals(language))
return true;
String type = getAttributeValueLC(script, "type");
if (type != null && type.contains("typescript")) return true;
return false;
@@ -294,21 +312,22 @@ public class HTMLExtractor implements IExtractor {
String source,
int offset,
boolean isTypeScript,
Segment parentHtmlNode,
HtmlPopulator.Context context) {
Label parentLabel) {
TrapWriter trapWriter = textualExtractor.getTrapwriter();
LocationManager locationManager = textualExtractor.getLocationManager();
// JavaScript AST extraction does not currently support source maps, so just set
// line/column numbers on the location manager.
Position pos = textualExtractor.getSourceMap().getStart(offset);
LocationManager scriptLocationManager = locationManager.startingAt(pos.getLine(), pos.getColumn());
LocationManager scriptLocationManager =
locationManager.startingAt(pos.getLine(), pos.getColumn());
if (isTypeScript) {
if (isEmbedded) {
return; // Do not extract files from HTML embedded in other files.
}
Path file = textualExtractor.getExtractedFile().toPath();
FileSnippet snippet =
new FileSnippet(file, pos.getLine(), pos.getColumn(), toplevelKind, config.getSourceType());
new FileSnippet(
file, pos.getLine(), pos.getColumn(), toplevelKind, config.getSourceType());
VirtualSourceRoot vroot = config.getVirtualSourceRoot();
// Vue files are special in that they can be imported as modules, and may only
// contain one <script> tag.
@@ -325,12 +344,13 @@ public class HTMLExtractor implements IExtractor {
}
state.getSnippets().put(virtualFile, snippet);
}
Label topLevelLabel = ASTExtractor.makeTopLevelLabel(
textualExtractor.getTrapwriter(),
scriptLocationManager.getFileLabel(),
scriptLocationManager.getStartLine(),
scriptLocationManager.getStartColumn());
emitTopLevelXmlNodeBinding(parentHtmlNode, topLevelLabel, context, trapWriter);
Label topLevelLabel =
ASTExtractor.makeTopLevelLabel(
textualExtractor.getTrapwriter(),
scriptLocationManager.getFileLabel(),
scriptLocationManager.getStartLine(),
scriptLocationManager.getStartColumn());
emitTopLevelXmlNodeBinding(parentLabel, topLevelLabel, trapWriter);
// Note: LoC info is accounted for later, so not added here.
return;
}
@@ -347,7 +367,7 @@ public class HTMLExtractor implements IExtractor {
Pair<Label, LoCInfo> result = extractor.extract(tx, source, toplevelKind, scopeManager);
Label toplevelLabel = result.fst();
if (toplevelLabel != null) { // can be null when script ends up being parsed as JSON
emitTopLevelXmlNodeBinding(parentHtmlNode, toplevelLabel, context, trapWriter);
emitTopLevelXmlNodeBinding(parentLabel, toplevelLabel, trapWriter);
}
locInfo.add(result.snd());
} catch (ParseError e) {
@@ -356,8 +376,71 @@ public class HTMLExtractor implements IExtractor {
}
}
private void emitTopLevelXmlNodeBinding(Segment parentHtmlNode, Label topLevelLabel, HtmlPopulator.Context context, TrapWriter writer) {
Label htmlNodeLabel = context.getNodeLabel(parentHtmlNode);
private void emitTopLevelXmlNodeBinding(
Label htmlNodeLabel, Label topLevelLabel, TrapWriter writer) {
writer.addTuple("toplevel_parent_xml_node", topLevelLabel, htmlNodeLabel);
}
private void extractTemplateTags(
TextualExtractor textualExtractor,
Source root,
int start,
int end,
Supplier<Label> parentLabel) {
if (start >= end) return;
if (isEmbedded) return; // Do not extract template tags for HTML snippets embedded in a JS file
TrapWriter trapwriter = textualExtractor.getTrapwriter();
Matcher m =
TemplateEngines.TEMPLATE_TAGS.matcher(textualExtractor.getSource()).region(start, end);
while (m.find()) {
int startOffset = m.start();
int endOffset = m.end();
if (endOffset - startOffset > 10_000) {
// Do not extract long template strings as they're likely to be FP matches and
// unlikely to be parsed correctly.
continue;
}
// Emit an entity for the template tag
Label lbl = trapwriter.freshLabel();
String rawText = m.group();
trapwriter.addTuple("template_placeholder_tag_info", lbl, parentLabel.get(), rawText);
// Emit location entity
Label locationLbl = TemplateEngines.makeLocation(textualExtractor, startOffset, endOffset);
trapwriter.addTuple("hasLocation", lbl, locationLbl);
// Parse the contents as a template expression, if the delimiter expects an expression.
Matcher delimMatcher = TemplateEngines.TEMPLATE_EXPR_OPENING_TAG.matcher(rawText);
if (delimMatcher.find()) {
// The body of the template tag is stored in the first capture group of each pattern
int bodyGroup = getNonNullCaptureGroup(m);
if (bodyGroup != -1) {
extractSnippet(
TopLevelKind.ANGULAR_STYLE_TEMPLATE,
config.withSourceType(SourceType.ANGULAR_STYLE_TEMPLATE),
new ScopeManager(textualExtractor.getTrapwriter(), ECMAVersion.ECMA2020, true),
textualExtractor,
m.group(bodyGroup),
m.start(bodyGroup),
false /* isTypeScript */,
lbl);
}
}
}
}
/**
* Returns the index of the first capture group that captured something (apart from group zero
* which is the whole match).
*/
private static int getNonNullCaptureGroup(Matcher m) {
for (int i = 1; i <= m.groupCount(); ++i) {
if (m.group(i) != null) {
return i;
}
}
return -1;
}
}

View File

@@ -43,7 +43,7 @@ public class Main {
* A version identifier that should be updated every time the extractor changes in such a way that
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
*/
public static final String EXTRACTOR_VERSION = "2021-06-15";
public static final String EXTRACTOR_VERSION = "2021-07-28";
public static final Pattern NEWLINE = Pattern.compile("\n");

View File

@@ -103,12 +103,22 @@ public class ScopeManager {
private final ECMAVersion ecmaVersion;
private final Set<String> implicitGlobals = new LinkedHashSet<String>();
private Scope implicitVariableScope;
private final boolean isInTemplateScope;
public ScopeManager(TrapWriter trapWriter, ECMAVersion ecmaVersion) {
public ScopeManager(TrapWriter trapWriter, ECMAVersion ecmaVersion, boolean isInTemplateScope) {
this.trapWriter = trapWriter;
this.toplevelScope = enterScope(ScopeKind.GLOBAL, trapWriter.globalID("global_scope"), null);
this.ecmaVersion = ecmaVersion;
this.implicitVariableScope = toplevelScope;
this.isInTemplateScope = isInTemplateScope;
}
/**
* Returns true the current scope is potentially in a template file, and may contain
* relevant template tags.
*/
public boolean isInTemplateFile() {
return isInTemplateScope;
}
/**
@@ -119,6 +129,14 @@ public class ScopeManager {
this.implicitVariableScope = implicitVariableScope;
}
/**
* Reset the scope in which to declare variables that are referenced without
* being declared back to the global scope.
*/
public void resetImplicitVariableScope() {
this.implicitVariableScope = toplevelScope;
}
/**
* Enter a new scope.
*

View File

@@ -77,7 +77,7 @@ public class ScriptExtractor implements IExtractor {
}
ScopeManager scopeManager =
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion());
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion(), false);
Label toplevelLabel = null;
LoCInfo loc;
try {

View File

@@ -0,0 +1,37 @@
package com.semmle.js.extractor;
import java.util.regex.Pattern;
import com.semmle.util.data.StringUtil;
import com.semmle.util.locations.Position;
import com.semmle.util.trap.TrapWriter.Label;
public class TemplateEngines {
private static final String MUSTACHE_TAG_TRIPLE = "\\{\\{\\{(.*?)\\}\\}\\}"; // {{{ x }}}
private static final String MUSTACHE_TAG_DOUBLE = "\\{\\{(?!\\{)(.*?)\\}\\}"; // {{ x }}}
private static final String MUSTACHE_TAG_PERCENT = "\\{%(?!>)(.*?)%\\}"; // {% x %}
private static final String EJS_TAG = "<%(?![%<>}])[-=]?(.*?)[_-]?%>"; // <% x %>
/** Pattern for a template tag whose contents should be parsed as an expression */
public static final Pattern TEMPLATE_EXPR_OPENING_TAG =
Pattern.compile("^(?:\\{\\{\\{?|<%[-=])"); // {{, {{{, <%=, <%-
/**
* Pattern matching a template tag from a supported template engine.
*/
public static final Pattern TEMPLATE_TAGS =
Pattern.compile(
StringUtil.glue(
"|", TemplateEngines.MUSTACHE_TAG_DOUBLE, MUSTACHE_TAG_TRIPLE, MUSTACHE_TAG_PERCENT, EJS_TAG),
Pattern.DOTALL);
/**
* Returns the location label for a template tag at the given offsets.
*/
public static Label makeLocation(TextualExtractor extractor, int startOffset, int endOffset) {
Position startPos = extractor.getSourceMap().getStart(startOffset);
Position endPos = extractor.getSourceMap().getEnd(endOffset - 1);
int endColumn = endPos.getColumn() - 1; // Convert to inclusive end position (still 1-based)
return extractor.getLocationManager().emitLocationsDefault(startPos.getLine(), startPos.getColumn(), endPos.getLine(), endColumn);
}
}

View File

@@ -8,7 +8,7 @@ public enum TopLevelKind {
INLINE_SCRIPT(1),
EVENT_HANDLER(2),
JAVASCRIPT_URL(3),
ANGULAR_TEMPLATE(4);
ANGULAR_STYLE_TEMPLATE(4);
private int value;

View File

@@ -23,7 +23,7 @@ public class TypeScriptExtractor implements IExtractor {
File sourceFile = textualExtractor.getExtractedFile();
Result res = state.getTypeScriptParser().parse(sourceFile, source, textualExtractor.getMetrics());
ScopeManager scopeManager =
new ScopeManager(textualExtractor.getTrapwriter(), ECMAVersion.ECMA2017);
new ScopeManager(textualExtractor.getTrapwriter(), ECMAVersion.ECMA2017, false);
try {
FileSnippet snippet = state.getSnippets().get(sourceFile.toPath());
SourceType sourceType = snippet != null ? snippet.getSourceType() : jsExtractor.establishSourceType(source, false);

View File

@@ -0,0 +1,7 @@
let data1 = <%= user_data1 %>;
let data2 = <%- user_data2 %>;
if (<%something%>) {}
foo(<%bar%>, <%baz%>);
<% generated_code %>
let string = "<%= not_generated_code %>"; // parse as string literal

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<body>
<h1>{{title}}</h1>
{{{subtitle_html}}}
<p><%- body_html %></p>
<p><%= footer %></p>
<script>
var data1 = {{{ user_data1 }}};
var data2 = {{ user_data2 | json | safe }};
var data3 = <%- user_data3 %>;
</script>
<a href="{{ attr1 }}" title="{{{ attr2 }}}" data-foo="<%- attr3 %>"
data-bar=" {{ attr4 }} "></a>
</body>
</html>

View File

@@ -0,0 +1,9 @@
let data1 = {{ user_data1 }};
let data2 = {{{ user_data2 }}};
if ({{something}}) {}
foo({{bar}}, {{baz}});
{{not_generated_code}} // parse as block
{{ if (not_generated_code) { } }} // parse as block
if (1 == 2) {{not_generated_code}} // parse as block
let string = "{{ not_generated_code }}"; // parse as string literal

View File

@@ -0,0 +1,3 @@
{
"experimental": true
}

View File

@@ -0,0 +1,410 @@
#10000=@"/ejs.js;sourcefile"
files(#10000,"/ejs.js","ejs","js",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
#20002=*
comments(#20002,0,#20001," parse as string literal","// pars ... literal")
#20003=@"loc,{#10000},7,43,7,68"
locations_default(#20003,#10000,7,43,7,68)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"let data1 = <%= user_data1 %>;","
")
#20005=@"loc,{#10000},1,1,1,30"
locations_default(#20005,#10000,1,1,1,30)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"let data2 = <%- user_data2 %>;","
")
#20007=@"loc,{#10000},2,1,2,30"
locations_default(#20007,#10000,2,1,2,30)
hasLocation(#20006,#20007)
#20008=*
lines(#20008,#20001,"if (<%something%>) {}","
")
#20009=@"loc,{#10000},3,1,3,21"
locations_default(#20009,#10000,3,1,3,21)
hasLocation(#20008,#20009)
#20010=*
lines(#20010,#20001,"foo(<%bar%>, <%baz%>);","
")
#20011=@"loc,{#10000},4,1,4,22"
locations_default(#20011,#10000,4,1,4,22)
hasLocation(#20010,#20011)
#20012=*
lines(#20012,#20001,"","
")
#20013=@"loc,{#10000},5,1,5,0"
locations_default(#20013,#10000,5,1,5,0)
hasLocation(#20012,#20013)
#20014=*
lines(#20014,#20001,"<% generated_code %>","
")
#20015=@"loc,{#10000},6,1,6,20"
locations_default(#20015,#10000,6,1,6,20)
hasLocation(#20014,#20015)
#20016=*
lines(#20016,#20001,"let string = ""<%= not_generated_code %>""; // parse as string literal","
")
#20017=@"loc,{#10000},7,1,7,68"
locations_default(#20017,#10000,7,1,7,68)
hasLocation(#20016,#20017)
numlines(#20001,7,6,1)
#20018=*
tokeninfo(#20018,7,#20001,0,"let")
#20019=@"loc,{#10000},1,1,1,3"
locations_default(#20019,#10000,1,1,1,3)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,6,#20001,1,"data1")
#20021=@"loc,{#10000},1,5,1,9"
locations_default(#20021,#10000,1,5,1,9)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,8,#20001,2,"=")
#20023=@"loc,{#10000},1,11,1,11"
locations_default(#20023,#10000,1,11,1,11)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,8,#20001,3,"%>")
#20025=@"loc,{#10000},1,28,1,29"
locations_default(#20025,#10000,1,28,1,29)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,8,#20001,4,";")
#20027=@"loc,{#10000},1,30,1,30"
locations_default(#20027,#10000,1,30,1,30)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,7,#20001,5,"let")
#20029=@"loc,{#10000},2,1,2,3"
locations_default(#20029,#10000,2,1,2,3)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,6,#20001,6,"data2")
#20031=@"loc,{#10000},2,5,2,9"
locations_default(#20031,#10000,2,5,2,9)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,8,#20001,7,"=")
#20033=@"loc,{#10000},2,11,2,11"
locations_default(#20033,#10000,2,11,2,11)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,8,#20001,8,"%>")
#20035=@"loc,{#10000},2,28,2,29"
locations_default(#20035,#10000,2,28,2,29)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,8,#20001,9,";")
#20037=@"loc,{#10000},2,30,2,30"
locations_default(#20037,#10000,2,30,2,30)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,7,#20001,10,"if")
#20039=@"loc,{#10000},3,1,3,2"
locations_default(#20039,#10000,3,1,3,2)
hasLocation(#20038,#20039)
#20040=*
tokeninfo(#20040,8,#20001,11,"(")
#20041=@"loc,{#10000},3,4,3,4"
locations_default(#20041,#10000,3,4,3,4)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,8,#20001,12,"%>")
#20043=@"loc,{#10000},3,16,3,17"
locations_default(#20043,#10000,3,16,3,17)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,8,#20001,13,")")
#20045=@"loc,{#10000},3,18,3,18"
locations_default(#20045,#10000,3,18,3,18)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,8,#20001,14,"{")
#20047=@"loc,{#10000},3,20,3,20"
locations_default(#20047,#10000,3,20,3,20)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,8,#20001,15,"}")
#20049=@"loc,{#10000},3,21,3,21"
locations_default(#20049,#10000,3,21,3,21)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,6,#20001,16,"foo")
#20051=@"loc,{#10000},4,1,4,3"
locations_default(#20051,#10000,4,1,4,3)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,8,#20001,17,"(")
#20053=@"loc,{#10000},4,4,4,4"
locations_default(#20053,#10000,4,4,4,4)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,8,#20001,18,"%>")
#20055=@"loc,{#10000},4,10,4,11"
locations_default(#20055,#10000,4,10,4,11)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,8,#20001,19,",")
#20057=@"loc,{#10000},4,12,4,12"
locations_default(#20057,#10000,4,12,4,12)
hasLocation(#20056,#20057)
#20058=*
tokeninfo(#20058,8,#20001,20,"%>")
#20059=@"loc,{#10000},4,19,4,20"
locations_default(#20059,#10000,4,19,4,20)
hasLocation(#20058,#20059)
#20060=*
tokeninfo(#20060,8,#20001,21,")")
#20061=@"loc,{#10000},4,21,4,21"
locations_default(#20061,#10000,4,21,4,21)
hasLocation(#20060,#20061)
#20062=*
tokeninfo(#20062,8,#20001,22,";")
#20063=@"loc,{#10000},4,22,4,22"
locations_default(#20063,#10000,4,22,4,22)
hasLocation(#20062,#20063)
#20064=*
tokeninfo(#20064,8,#20001,23,"%>")
#20065=@"loc,{#10000},6,19,6,20"
locations_default(#20065,#10000,6,19,6,20)
hasLocation(#20064,#20065)
#20066=*
tokeninfo(#20066,7,#20001,24,"let")
#20067=@"loc,{#10000},7,1,7,3"
locations_default(#20067,#10000,7,1,7,3)
hasLocation(#20066,#20067)
#20068=*
tokeninfo(#20068,6,#20001,25,"string")
#20069=@"loc,{#10000},7,5,7,10"
locations_default(#20069,#10000,7,5,7,10)
hasLocation(#20068,#20069)
#20070=*
tokeninfo(#20070,8,#20001,26,"=")
#20071=@"loc,{#10000},7,12,7,12"
locations_default(#20071,#10000,7,12,7,12)
hasLocation(#20070,#20071)
#20072=*
tokeninfo(#20072,4,#20001,27,"""<%= not_generated_code %>""")
#20073=@"loc,{#10000},7,14,7,40"
locations_default(#20073,#10000,7,14,7,40)
hasLocation(#20072,#20073)
#20074=*
tokeninfo(#20074,8,#20001,28,";")
#20075=@"loc,{#10000},7,41,7,41"
locations_default(#20075,#10000,7,41,7,41)
hasLocation(#20074,#20075)
#20076=*
tokeninfo(#20076,0,#20001,29,"")
#20077=@"loc,{#10000},8,1,8,0"
locations_default(#20077,#10000,8,1,8,0)
hasLocation(#20076,#20077)
next_token(#20002,#20076)
toplevels(#20001,0)
#20078=@"loc,{#10000},1,1,8,0"
locations_default(#20078,#10000,1,1,8,0)
hasLocation(#20001,#20078)
#20079=@"var;{data1};{#20000}"
variables(#20079,"data1",#20000)
#20080=@"var;{data2};{#20000}"
variables(#20080,"data2",#20000)
#20081=@"var;{string};{#20000}"
variables(#20081,"string",#20000)
#20082=*
stmts(#20082,23,#20001,0,"let dat ... ta1 %>;")
hasLocation(#20082,#20005)
stmt_containers(#20082,#20001)
#20083=*
exprs(#20083,64,#20082,0,"data1 = ... ata1 %>")
#20084=@"loc,{#10000},1,5,1,29"
locations_default(#20084,#10000,1,5,1,29)
hasLocation(#20083,#20084)
enclosing_stmt(#20083,#20082)
expr_containers(#20083,#20001)
#20085=*
exprs(#20085,78,#20083,0,"data1")
hasLocation(#20085,#20021)
enclosing_stmt(#20085,#20082)
expr_containers(#20085,#20001)
literals("data1","data1",#20085)
decl(#20085,#20079)
#20086=*
exprs(#20086,120,#20083,1,"<%= user_data1 %>")
#20087=@"loc,{#10000},1,13,1,29"
locations_default(#20087,#10000,1,13,1,29)
hasLocation(#20086,#20087)
enclosing_stmt(#20086,#20082)
expr_containers(#20086,#20001)
expr_contains_template_tag_location(#20086,#20087)
#20088=*
stmts(#20088,23,#20001,1,"let dat ... ta2 %>;")
hasLocation(#20088,#20007)
stmt_containers(#20088,#20001)
#20089=*
exprs(#20089,64,#20088,0,"data2 = ... ata2 %>")
#20090=@"loc,{#10000},2,5,2,29"
locations_default(#20090,#10000,2,5,2,29)
hasLocation(#20089,#20090)
enclosing_stmt(#20089,#20088)
expr_containers(#20089,#20001)
#20091=*
exprs(#20091,78,#20089,0,"data2")
hasLocation(#20091,#20031)
enclosing_stmt(#20091,#20088)
expr_containers(#20091,#20001)
literals("data2","data2",#20091)
decl(#20091,#20080)
#20092=*
exprs(#20092,120,#20089,1,"<%- user_data2 %>")
#20093=@"loc,{#10000},2,13,2,29"
locations_default(#20093,#10000,2,13,2,29)
hasLocation(#20092,#20093)
enclosing_stmt(#20092,#20088)
expr_containers(#20092,#20001)
expr_contains_template_tag_location(#20092,#20093)
#20094=*
stmts(#20094,3,#20001,2,"if (<%s ... g%>) {}")
hasLocation(#20094,#20009)
stmt_containers(#20094,#20001)
#20095=*
exprs(#20095,120,#20094,0,"<%something%>")
#20096=@"loc,{#10000},3,5,3,17"
locations_default(#20096,#10000,3,5,3,17)
hasLocation(#20095,#20096)
enclosing_stmt(#20095,#20094)
expr_containers(#20095,#20001)
expr_contains_template_tag_location(#20095,#20096)
#20097=*
stmts(#20097,1,#20094,1,"{}")
#20098=@"loc,{#10000},3,20,3,21"
locations_default(#20098,#10000,3,20,3,21)
hasLocation(#20097,#20098)
stmt_containers(#20097,#20001)
#20099=*
stmts(#20099,2,#20001,3,"foo(<%b ... baz%>);")
hasLocation(#20099,#20011)
stmt_containers(#20099,#20001)
#20100=*
exprs(#20100,13,#20099,0,"foo(<%b ... %baz%>)")
#20101=@"loc,{#10000},4,1,4,21"
locations_default(#20101,#10000,4,1,4,21)
hasLocation(#20100,#20101)
enclosing_stmt(#20100,#20099)
expr_containers(#20100,#20001)
#20102=*
exprs(#20102,79,#20100,-1,"foo")
hasLocation(#20102,#20051)
enclosing_stmt(#20102,#20099)
expr_containers(#20102,#20001)
literals("foo","foo",#20102)
#20103=@"var;{foo};{#20000}"
variables(#20103,"foo",#20000)
bind(#20102,#20103)
#20104=*
exprs(#20104,120,#20100,0,"<%bar%>")
#20105=@"loc,{#10000},4,5,4,11"
locations_default(#20105,#10000,4,5,4,11)
hasLocation(#20104,#20105)
enclosing_stmt(#20104,#20099)
expr_containers(#20104,#20001)
expr_contains_template_tag_location(#20104,#20105)
#20106=*
exprs(#20106,120,#20100,1,"<%baz%>")
#20107=@"loc,{#10000},4,14,4,20"
locations_default(#20107,#10000,4,14,4,20)
hasLocation(#20106,#20107)
enclosing_stmt(#20106,#20099)
expr_containers(#20106,#20001)
expr_contains_template_tag_location(#20106,#20107)
#20108=*
stmts(#20108,2,#20001,4,"<% generated_code %>")
hasLocation(#20108,#20015)
stmt_containers(#20108,#20001)
#20109=*
exprs(#20109,120,#20108,0,"<% generated_code %>")
hasLocation(#20109,#20015)
enclosing_stmt(#20109,#20108)
expr_containers(#20109,#20001)
expr_contains_template_tag_location(#20109,#20015)
#20110=*
stmts(#20110,23,#20001,5,"let str ... de %>"";")
#20111=@"loc,{#10000},7,1,7,41"
locations_default(#20111,#10000,7,1,7,41)
hasLocation(#20110,#20111)
stmt_containers(#20110,#20001)
#20112=*
exprs(#20112,64,#20110,0,"string ... ode %>""")
#20113=@"loc,{#10000},7,5,7,40"
locations_default(#20113,#10000,7,5,7,40)
hasLocation(#20112,#20113)
enclosing_stmt(#20112,#20110)
expr_containers(#20112,#20001)
#20114=*
exprs(#20114,78,#20112,0,"string")
hasLocation(#20114,#20069)
enclosing_stmt(#20114,#20110)
expr_containers(#20114,#20001)
literals("string","string",#20114)
decl(#20114,#20081)
#20115=*
exprs(#20115,4,#20112,1,"""<%= no ... ode %>""")
hasLocation(#20115,#20073)
enclosing_stmt(#20115,#20110)
expr_containers(#20115,#20001)
literals("<%= not_generated_code %>","""<%= not_generated_code %>""",#20115)
#20116=*
regexpterm(#20116,14,#20115,0,"<%= not_generated_code %>")
#20117=@"loc,{#10000},7,15,7,39"
locations_default(#20117,#10000,7,15,7,39)
hasLocation(#20116,#20117)
regexp_const_value(#20116,"<%= not_generated_code %>")
#20118=*
entry_cfg_node(#20118,#20001)
#20119=@"loc,{#10000},1,1,1,0"
locations_default(#20119,#10000,1,1,1,0)
hasLocation(#20118,#20119)
#20120=*
exit_cfg_node(#20120,#20001)
hasLocation(#20120,#20077)
successor(#20110,#20114)
successor(#20115,#20112)
successor(#20114,#20115)
successor(#20112,#20120)
successor(#20108,#20109)
successor(#20109,#20110)
successor(#20099,#20102)
successor(#20106,#20100)
successor(#20104,#20106)
successor(#20102,#20104)
successor(#20100,#20108)
successor(#20094,#20095)
#20121=*
guard_node(#20121,1,#20095)
hasLocation(#20121,#20096)
successor(#20121,#20097)
#20122=*
guard_node(#20122,0,#20095)
hasLocation(#20122,#20096)
successor(#20122,#20099)
successor(#20095,#20121)
successor(#20095,#20122)
successor(#20097,#20099)
successor(#20088,#20091)
successor(#20092,#20089)
successor(#20091,#20092)
successor(#20089,#20094)
successor(#20082,#20085)
successor(#20086,#20083)
successor(#20085,#20086)
successor(#20083,#20088)
successor(#20118,#20082)
numlines(#10000,7,6,1)
filetype(#10000,"javascript")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,686 @@
#10000=@"/tst.js;sourcefile"
files(#10000,"/tst.js","tst","js",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
#20002=*
comments(#20002,0,#20001," parse as block","// parse as block")
#20003=@"loc,{#10000},6,24,6,40"
locations_default(#20003,#10000,6,24,6,40)
hasLocation(#20002,#20003)
#20004=*
comments(#20004,0,#20001," parse as block","// parse as block")
#20005=@"loc,{#10000},7,35,7,51"
locations_default(#20005,#10000,7,35,7,51)
hasLocation(#20004,#20005)
#20006=*
comments(#20006,0,#20001," parse as block","// parse as block")
#20007=@"loc,{#10000},8,36,8,52"
locations_default(#20007,#10000,8,36,8,52)
hasLocation(#20006,#20007)
#20008=*
comments(#20008,0,#20001," parse as string literal","// pars ... literal")
#20009=@"loc,{#10000},9,42,9,67"
locations_default(#20009,#10000,9,42,9,67)
hasLocation(#20008,#20009)
#20010=*
lines(#20010,#20001,"let data1 = {{ user_data1 }};","
")
#20011=@"loc,{#10000},1,1,1,29"
locations_default(#20011,#10000,1,1,1,29)
hasLocation(#20010,#20011)
#20012=*
lines(#20012,#20001,"let data2 = {{{ user_data2 }}};","
")
#20013=@"loc,{#10000},2,1,2,31"
locations_default(#20013,#10000,2,1,2,31)
hasLocation(#20012,#20013)
#20014=*
lines(#20014,#20001,"if ({{something}}) {}","
")
#20015=@"loc,{#10000},3,1,3,21"
locations_default(#20015,#10000,3,1,3,21)
hasLocation(#20014,#20015)
#20016=*
lines(#20016,#20001,"foo({{bar}}, {{baz}});","
")
#20017=@"loc,{#10000},4,1,4,22"
locations_default(#20017,#10000,4,1,4,22)
hasLocation(#20016,#20017)
#20018=*
lines(#20018,#20001,"","
")
#20019=@"loc,{#10000},5,1,5,0"
locations_default(#20019,#10000,5,1,5,0)
hasLocation(#20018,#20019)
#20020=*
lines(#20020,#20001,"{{not_generated_code}} // parse as block","
")
#20021=@"loc,{#10000},6,1,6,40"
locations_default(#20021,#10000,6,1,6,40)
hasLocation(#20020,#20021)
#20022=*
lines(#20022,#20001,"{{ if (not_generated_code) { } }} // parse as block","
")
#20023=@"loc,{#10000},7,1,7,51"
locations_default(#20023,#10000,7,1,7,51)
hasLocation(#20022,#20023)
#20024=*
lines(#20024,#20001,"if (1 == 2) {{not_generated_code}} // parse as block","
")
#20025=@"loc,{#10000},8,1,8,52"
locations_default(#20025,#10000,8,1,8,52)
hasLocation(#20024,#20025)
#20026=*
lines(#20026,#20001,"let string = ""{{ not_generated_code }}""; // parse as string literal","
")
#20027=@"loc,{#10000},9,1,9,67"
locations_default(#20027,#10000,9,1,9,67)
hasLocation(#20026,#20027)
numlines(#20001,9,8,4)
#20028=*
tokeninfo(#20028,7,#20001,0,"let")
#20029=@"loc,{#10000},1,1,1,3"
locations_default(#20029,#10000,1,1,1,3)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,6,#20001,1,"data1")
#20031=@"loc,{#10000},1,5,1,9"
locations_default(#20031,#10000,1,5,1,9)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,8,#20001,2,"=")
#20033=@"loc,{#10000},1,11,1,11"
locations_default(#20033,#10000,1,11,1,11)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,8,#20001,3,"}}")
#20035=@"loc,{#10000},1,27,1,28"
locations_default(#20035,#10000,1,27,1,28)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,8,#20001,4,";")
#20037=@"loc,{#10000},1,29,1,29"
locations_default(#20037,#10000,1,29,1,29)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,7,#20001,5,"let")
#20039=@"loc,{#10000},2,1,2,3"
locations_default(#20039,#10000,2,1,2,3)
hasLocation(#20038,#20039)
#20040=*
tokeninfo(#20040,6,#20001,6,"data2")
#20041=@"loc,{#10000},2,5,2,9"
locations_default(#20041,#10000,2,5,2,9)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,8,#20001,7,"=")
#20043=@"loc,{#10000},2,11,2,11"
locations_default(#20043,#10000,2,11,2,11)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,8,#20001,8,"}}}")
#20045=@"loc,{#10000},2,28,2,30"
locations_default(#20045,#10000,2,28,2,30)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,8,#20001,9,";")
#20047=@"loc,{#10000},2,31,2,31"
locations_default(#20047,#10000,2,31,2,31)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,7,#20001,10,"if")
#20049=@"loc,{#10000},3,1,3,2"
locations_default(#20049,#10000,3,1,3,2)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,8,#20001,11,"(")
#20051=@"loc,{#10000},3,4,3,4"
locations_default(#20051,#10000,3,4,3,4)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,8,#20001,12,"}}")
#20053=@"loc,{#10000},3,16,3,17"
locations_default(#20053,#10000,3,16,3,17)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,8,#20001,13,")")
#20055=@"loc,{#10000},3,18,3,18"
locations_default(#20055,#10000,3,18,3,18)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,8,#20001,14,"{")
#20057=@"loc,{#10000},3,20,3,20"
locations_default(#20057,#10000,3,20,3,20)
hasLocation(#20056,#20057)
#20058=*
tokeninfo(#20058,8,#20001,15,"}")
#20059=@"loc,{#10000},3,21,3,21"
locations_default(#20059,#10000,3,21,3,21)
hasLocation(#20058,#20059)
#20060=*
tokeninfo(#20060,6,#20001,16,"foo")
#20061=@"loc,{#10000},4,1,4,3"
locations_default(#20061,#10000,4,1,4,3)
hasLocation(#20060,#20061)
#20062=*
tokeninfo(#20062,8,#20001,17,"(")
#20063=@"loc,{#10000},4,4,4,4"
locations_default(#20063,#10000,4,4,4,4)
hasLocation(#20062,#20063)
#20064=*
tokeninfo(#20064,8,#20001,18,"}}")
#20065=@"loc,{#10000},4,10,4,11"
locations_default(#20065,#10000,4,10,4,11)
hasLocation(#20064,#20065)
#20066=*
tokeninfo(#20066,8,#20001,19,",")
#20067=@"loc,{#10000},4,12,4,12"
locations_default(#20067,#10000,4,12,4,12)
hasLocation(#20066,#20067)
#20068=*
tokeninfo(#20068,8,#20001,20,"}}")
#20069=@"loc,{#10000},4,19,4,20"
locations_default(#20069,#10000,4,19,4,20)
hasLocation(#20068,#20069)
#20070=*
tokeninfo(#20070,8,#20001,21,")")
#20071=@"loc,{#10000},4,21,4,21"
locations_default(#20071,#10000,4,21,4,21)
hasLocation(#20070,#20071)
#20072=*
tokeninfo(#20072,8,#20001,22,";")
#20073=@"loc,{#10000},4,22,4,22"
locations_default(#20073,#10000,4,22,4,22)
hasLocation(#20072,#20073)
#20074=*
tokeninfo(#20074,8,#20001,23,"{")
#20075=@"loc,{#10000},6,1,6,1"
locations_default(#20075,#10000,6,1,6,1)
hasLocation(#20074,#20075)
#20076=*
tokeninfo(#20076,8,#20001,24,"{")
#20077=@"loc,{#10000},6,2,6,2"
locations_default(#20077,#10000,6,2,6,2)
hasLocation(#20076,#20077)
#20078=*
tokeninfo(#20078,6,#20001,25,"not_generated_code")
#20079=@"loc,{#10000},6,3,6,20"
locations_default(#20079,#10000,6,3,6,20)
hasLocation(#20078,#20079)
#20080=*
tokeninfo(#20080,8,#20001,26,"}")
#20081=@"loc,{#10000},6,21,6,21"
locations_default(#20081,#10000,6,21,6,21)
hasLocation(#20080,#20081)
#20082=*
tokeninfo(#20082,8,#20001,27,"}")
#20083=@"loc,{#10000},6,22,6,22"
locations_default(#20083,#10000,6,22,6,22)
hasLocation(#20082,#20083)
#20084=*
tokeninfo(#20084,8,#20001,28,"{")
#20085=@"loc,{#10000},7,1,7,1"
locations_default(#20085,#10000,7,1,7,1)
hasLocation(#20084,#20085)
next_token(#20002,#20084)
#20086=*
tokeninfo(#20086,8,#20001,29,"{")
#20087=@"loc,{#10000},7,2,7,2"
locations_default(#20087,#10000,7,2,7,2)
hasLocation(#20086,#20087)
#20088=*
tokeninfo(#20088,7,#20001,30,"if")
#20089=@"loc,{#10000},7,4,7,5"
locations_default(#20089,#10000,7,4,7,5)
hasLocation(#20088,#20089)
#20090=*
tokeninfo(#20090,8,#20001,31,"(")
#20091=@"loc,{#10000},7,7,7,7"
locations_default(#20091,#10000,7,7,7,7)
hasLocation(#20090,#20091)
#20092=*
tokeninfo(#20092,6,#20001,32,"not_generated_code")
#20093=@"loc,{#10000},7,8,7,25"
locations_default(#20093,#10000,7,8,7,25)
hasLocation(#20092,#20093)
#20094=*
tokeninfo(#20094,8,#20001,33,")")
#20095=@"loc,{#10000},7,26,7,26"
locations_default(#20095,#10000,7,26,7,26)
hasLocation(#20094,#20095)
#20096=*
tokeninfo(#20096,8,#20001,34,"{")
#20097=@"loc,{#10000},7,28,7,28"
locations_default(#20097,#10000,7,28,7,28)
hasLocation(#20096,#20097)
#20098=*
tokeninfo(#20098,8,#20001,35,"}")
#20099=@"loc,{#10000},7,30,7,30"
locations_default(#20099,#10000,7,30,7,30)
hasLocation(#20098,#20099)
#20100=*
tokeninfo(#20100,8,#20001,36,"}")
#20101=@"loc,{#10000},7,32,7,32"
locations_default(#20101,#10000,7,32,7,32)
hasLocation(#20100,#20101)
#20102=*
tokeninfo(#20102,8,#20001,37,"}")
#20103=@"loc,{#10000},7,33,7,33"
locations_default(#20103,#10000,7,33,7,33)
hasLocation(#20102,#20103)
#20104=*
tokeninfo(#20104,7,#20001,38,"if")
#20105=@"loc,{#10000},8,1,8,2"
locations_default(#20105,#10000,8,1,8,2)
hasLocation(#20104,#20105)
next_token(#20004,#20104)
#20106=*
tokeninfo(#20106,8,#20001,39,"(")
#20107=@"loc,{#10000},8,4,8,4"
locations_default(#20107,#10000,8,4,8,4)
hasLocation(#20106,#20107)
#20108=*
tokeninfo(#20108,3,#20001,40,"1")
#20109=@"loc,{#10000},8,5,8,5"
locations_default(#20109,#10000,8,5,8,5)
hasLocation(#20108,#20109)
#20110=*
tokeninfo(#20110,8,#20001,41,"==")
#20111=@"loc,{#10000},8,7,8,8"
locations_default(#20111,#10000,8,7,8,8)
hasLocation(#20110,#20111)
#20112=*
tokeninfo(#20112,3,#20001,42,"2")
#20113=@"loc,{#10000},8,10,8,10"
locations_default(#20113,#10000,8,10,8,10)
hasLocation(#20112,#20113)
#20114=*
tokeninfo(#20114,8,#20001,43,")")
#20115=@"loc,{#10000},8,11,8,11"
locations_default(#20115,#10000,8,11,8,11)
hasLocation(#20114,#20115)
#20116=*
tokeninfo(#20116,8,#20001,44,"{")
#20117=@"loc,{#10000},8,13,8,13"
locations_default(#20117,#10000,8,13,8,13)
hasLocation(#20116,#20117)
#20118=*
tokeninfo(#20118,8,#20001,45,"{")
#20119=@"loc,{#10000},8,14,8,14"
locations_default(#20119,#10000,8,14,8,14)
hasLocation(#20118,#20119)
#20120=*
tokeninfo(#20120,6,#20001,46,"not_generated_code")
#20121=@"loc,{#10000},8,15,8,32"
locations_default(#20121,#10000,8,15,8,32)
hasLocation(#20120,#20121)
#20122=*
tokeninfo(#20122,8,#20001,47,"}")
#20123=@"loc,{#10000},8,33,8,33"
locations_default(#20123,#10000,8,33,8,33)
hasLocation(#20122,#20123)
#20124=*
tokeninfo(#20124,8,#20001,48,"}")
#20125=@"loc,{#10000},8,34,8,34"
locations_default(#20125,#10000,8,34,8,34)
hasLocation(#20124,#20125)
#20126=*
tokeninfo(#20126,7,#20001,49,"let")
#20127=@"loc,{#10000},9,1,9,3"
locations_default(#20127,#10000,9,1,9,3)
hasLocation(#20126,#20127)
next_token(#20006,#20126)
#20128=*
tokeninfo(#20128,6,#20001,50,"string")
#20129=@"loc,{#10000},9,5,9,10"
locations_default(#20129,#10000,9,5,9,10)
hasLocation(#20128,#20129)
#20130=*
tokeninfo(#20130,8,#20001,51,"=")
#20131=@"loc,{#10000},9,12,9,12"
locations_default(#20131,#10000,9,12,9,12)
hasLocation(#20130,#20131)
#20132=*
tokeninfo(#20132,4,#20001,52,"""{{ not_generated_code }}""")
#20133=@"loc,{#10000},9,14,9,39"
locations_default(#20133,#10000,9,14,9,39)
hasLocation(#20132,#20133)
#20134=*
tokeninfo(#20134,8,#20001,53,";")
#20135=@"loc,{#10000},9,40,9,40"
locations_default(#20135,#10000,9,40,9,40)
hasLocation(#20134,#20135)
#20136=*
tokeninfo(#20136,0,#20001,54,"")
#20137=@"loc,{#10000},10,1,10,0"
locations_default(#20137,#10000,10,1,10,0)
hasLocation(#20136,#20137)
next_token(#20008,#20136)
toplevels(#20001,0)
#20138=@"loc,{#10000},1,1,10,0"
locations_default(#20138,#10000,1,1,10,0)
hasLocation(#20001,#20138)
#20139=@"var;{data1};{#20000}"
variables(#20139,"data1",#20000)
#20140=@"var;{data2};{#20000}"
variables(#20140,"data2",#20000)
#20141=@"var;{string};{#20000}"
variables(#20141,"string",#20000)
#20142=*
stmts(#20142,23,#20001,0,"let dat ... ta1 }};")
hasLocation(#20142,#20011)
stmt_containers(#20142,#20001)
#20143=*
exprs(#20143,64,#20142,0,"data1 = ... ata1 }}")
#20144=@"loc,{#10000},1,5,1,28"
locations_default(#20144,#10000,1,5,1,28)
hasLocation(#20143,#20144)
enclosing_stmt(#20143,#20142)
expr_containers(#20143,#20001)
#20145=*
exprs(#20145,78,#20143,0,"data1")
hasLocation(#20145,#20031)
enclosing_stmt(#20145,#20142)
expr_containers(#20145,#20001)
literals("data1","data1",#20145)
decl(#20145,#20139)
#20146=*
exprs(#20146,120,#20143,1,"{{ user_data1 }}")
#20147=@"loc,{#10000},1,13,1,28"
locations_default(#20147,#10000,1,13,1,28)
hasLocation(#20146,#20147)
enclosing_stmt(#20146,#20142)
expr_containers(#20146,#20001)
expr_contains_template_tag_location(#20146,#20147)
#20148=*
stmts(#20148,23,#20001,1,"let dat ... a2 }}};")
hasLocation(#20148,#20013)
stmt_containers(#20148,#20001)
#20149=*
exprs(#20149,64,#20148,0,"data2 = ... ta2 }}}")
#20150=@"loc,{#10000},2,5,2,30"
locations_default(#20150,#10000,2,5,2,30)
hasLocation(#20149,#20150)
enclosing_stmt(#20149,#20148)
expr_containers(#20149,#20001)
#20151=*
exprs(#20151,78,#20149,0,"data2")
hasLocation(#20151,#20041)
enclosing_stmt(#20151,#20148)
expr_containers(#20151,#20001)
literals("data2","data2",#20151)
decl(#20151,#20140)
#20152=*
exprs(#20152,120,#20149,1,"{{{ user_data2 }}}")
#20153=@"loc,{#10000},2,13,2,30"
locations_default(#20153,#10000,2,13,2,30)
hasLocation(#20152,#20153)
enclosing_stmt(#20152,#20148)
expr_containers(#20152,#20001)
expr_contains_template_tag_location(#20152,#20153)
#20154=*
stmts(#20154,3,#20001,2,"if ({{s ... g}}) {}")
hasLocation(#20154,#20015)
stmt_containers(#20154,#20001)
#20155=*
exprs(#20155,120,#20154,0,"{{something}}")
#20156=@"loc,{#10000},3,5,3,17"
locations_default(#20156,#10000,3,5,3,17)
hasLocation(#20155,#20156)
enclosing_stmt(#20155,#20154)
expr_containers(#20155,#20001)
expr_contains_template_tag_location(#20155,#20156)
#20157=*
stmts(#20157,1,#20154,1,"{}")
#20158=@"loc,{#10000},3,20,3,21"
locations_default(#20158,#10000,3,20,3,21)
hasLocation(#20157,#20158)
stmt_containers(#20157,#20001)
#20159=*
stmts(#20159,2,#20001,3,"foo({{b ... baz}});")
hasLocation(#20159,#20017)
stmt_containers(#20159,#20001)
#20160=*
exprs(#20160,13,#20159,0,"foo({{b ... {baz}})")
#20161=@"loc,{#10000},4,1,4,21"
locations_default(#20161,#10000,4,1,4,21)
hasLocation(#20160,#20161)
enclosing_stmt(#20160,#20159)
expr_containers(#20160,#20001)
#20162=*
exprs(#20162,79,#20160,-1,"foo")
hasLocation(#20162,#20061)
enclosing_stmt(#20162,#20159)
expr_containers(#20162,#20001)
literals("foo","foo",#20162)
#20163=@"var;{foo};{#20000}"
variables(#20163,"foo",#20000)
bind(#20162,#20163)
#20164=*
exprs(#20164,120,#20160,0,"{{bar}}")
#20165=@"loc,{#10000},4,5,4,11"
locations_default(#20165,#10000,4,5,4,11)
hasLocation(#20164,#20165)
enclosing_stmt(#20164,#20159)
expr_containers(#20164,#20001)
expr_contains_template_tag_location(#20164,#20165)
#20166=*
exprs(#20166,120,#20160,1,"{{baz}}")
#20167=@"loc,{#10000},4,14,4,20"
locations_default(#20167,#10000,4,14,4,20)
hasLocation(#20166,#20167)
enclosing_stmt(#20166,#20159)
expr_containers(#20166,#20001)
expr_contains_template_tag_location(#20166,#20167)
#20168=*
stmts(#20168,1,#20001,4,"{{not_g ... _code}}")
#20169=@"loc,{#10000},6,1,6,22"
locations_default(#20169,#10000,6,1,6,22)
hasLocation(#20168,#20169)
stmt_containers(#20168,#20001)
#20170=*
stmts(#20170,1,#20168,0,"{not_generated_code}")
#20171=@"loc,{#10000},6,2,6,21"
locations_default(#20171,#10000,6,2,6,21)
hasLocation(#20170,#20171)
stmt_containers(#20170,#20001)
#20172=*
stmts(#20172,2,#20170,0,"not_generated_code")
hasLocation(#20172,#20079)
stmt_containers(#20172,#20001)
#20173=*
exprs(#20173,79,#20172,0,"not_generated_code")
hasLocation(#20173,#20079)
enclosing_stmt(#20173,#20172)
expr_containers(#20173,#20001)
literals("not_generated_code","not_generated_code",#20173)
#20174=@"var;{not_generated_code};{#20000}"
variables(#20174,"not_generated_code",#20000)
bind(#20173,#20174)
#20175=*
stmts(#20175,1,#20001,5,"{{ if ( ... { } }}")
#20176=@"loc,{#10000},7,1,7,33"
locations_default(#20176,#10000,7,1,7,33)
hasLocation(#20175,#20176)
stmt_containers(#20175,#20001)
#20177=*
stmts(#20177,1,#20175,0,"{ if (n ... ) { } }")
#20178=@"loc,{#10000},7,2,7,32"
locations_default(#20178,#10000,7,2,7,32)
hasLocation(#20177,#20178)
stmt_containers(#20177,#20001)
#20179=*
stmts(#20179,3,#20177,0,"if (not ... de) { }")
#20180=@"loc,{#10000},7,4,7,30"
locations_default(#20180,#10000,7,4,7,30)
hasLocation(#20179,#20180)
stmt_containers(#20179,#20001)
#20181=*
exprs(#20181,79,#20179,0,"not_generated_code")
hasLocation(#20181,#20093)
enclosing_stmt(#20181,#20179)
expr_containers(#20181,#20001)
literals("not_generated_code","not_generated_code",#20181)
bind(#20181,#20174)
#20182=*
stmts(#20182,1,#20179,1,"{ }")
#20183=@"loc,{#10000},7,28,7,30"
locations_default(#20183,#10000,7,28,7,30)
hasLocation(#20182,#20183)
stmt_containers(#20182,#20001)
#20184=*
stmts(#20184,3,#20001,6,"if (1 = ... _code}}")
#20185=@"loc,{#10000},8,1,8,34"
locations_default(#20185,#10000,8,1,8,34)
hasLocation(#20184,#20185)
stmt_containers(#20184,#20001)
#20186=*
exprs(#20186,23,#20184,0,"1 == 2")
#20187=@"loc,{#10000},8,5,8,10"
locations_default(#20187,#10000,8,5,8,10)
hasLocation(#20186,#20187)
enclosing_stmt(#20186,#20184)
expr_containers(#20186,#20001)
#20188=*
exprs(#20188,3,#20186,0,"1")
hasLocation(#20188,#20109)
enclosing_stmt(#20188,#20184)
expr_containers(#20188,#20001)
literals("1","1",#20188)
#20189=*
exprs(#20189,3,#20186,1,"2")
hasLocation(#20189,#20113)
enclosing_stmt(#20189,#20184)
expr_containers(#20189,#20001)
literals("2","2",#20189)
#20190=*
stmts(#20190,1,#20184,1,"{{not_g ... _code}}")
#20191=@"loc,{#10000},8,13,8,34"
locations_default(#20191,#10000,8,13,8,34)
hasLocation(#20190,#20191)
stmt_containers(#20190,#20001)
#20192=*
stmts(#20192,1,#20190,0,"{not_generated_code}")
#20193=@"loc,{#10000},8,14,8,33"
locations_default(#20193,#10000,8,14,8,33)
hasLocation(#20192,#20193)
stmt_containers(#20192,#20001)
#20194=*
stmts(#20194,2,#20192,0,"not_generated_code")
hasLocation(#20194,#20121)
stmt_containers(#20194,#20001)
#20195=*
exprs(#20195,79,#20194,0,"not_generated_code")
hasLocation(#20195,#20121)
enclosing_stmt(#20195,#20194)
expr_containers(#20195,#20001)
literals("not_generated_code","not_generated_code",#20195)
bind(#20195,#20174)
#20196=*
stmts(#20196,23,#20001,7,"let str ... de }}"";")
#20197=@"loc,{#10000},9,1,9,40"
locations_default(#20197,#10000,9,1,9,40)
hasLocation(#20196,#20197)
stmt_containers(#20196,#20001)
#20198=*
exprs(#20198,64,#20196,0,"string ... ode }}""")
#20199=@"loc,{#10000},9,5,9,39"
locations_default(#20199,#10000,9,5,9,39)
hasLocation(#20198,#20199)
enclosing_stmt(#20198,#20196)
expr_containers(#20198,#20001)
#20200=*
exprs(#20200,78,#20198,0,"string")
hasLocation(#20200,#20129)
enclosing_stmt(#20200,#20196)
expr_containers(#20200,#20001)
literals("string","string",#20200)
decl(#20200,#20141)
#20201=*
exprs(#20201,4,#20198,1,"""{{ not ... ode }}""")
hasLocation(#20201,#20133)
enclosing_stmt(#20201,#20196)
expr_containers(#20201,#20001)
literals("{{ not_generated_code }}","""{{ not_generated_code }}""",#20201)
#20202=*
entry_cfg_node(#20202,#20001)
#20203=@"loc,{#10000},1,1,1,0"
locations_default(#20203,#10000,1,1,1,0)
hasLocation(#20202,#20203)
#20204=*
exit_cfg_node(#20204,#20001)
hasLocation(#20204,#20137)
successor(#20196,#20200)
successor(#20201,#20198)
successor(#20200,#20201)
successor(#20198,#20204)
successor(#20184,#20188)
successor(#20189,#20186)
successor(#20188,#20189)
#20205=*
guard_node(#20205,1,#20186)
hasLocation(#20205,#20187)
successor(#20205,#20190)
#20206=*
guard_node(#20206,0,#20186)
hasLocation(#20206,#20187)
successor(#20206,#20196)
successor(#20186,#20205)
successor(#20186,#20206)
successor(#20190,#20192)
successor(#20192,#20194)
successor(#20194,#20195)
successor(#20195,#20196)
successor(#20175,#20177)
successor(#20177,#20179)
successor(#20179,#20181)
#20207=*
guard_node(#20207,1,#20181)
hasLocation(#20207,#20093)
successor(#20207,#20182)
#20208=*
guard_node(#20208,0,#20181)
hasLocation(#20208,#20093)
successor(#20208,#20184)
successor(#20181,#20207)
successor(#20181,#20208)
successor(#20182,#20184)
successor(#20168,#20170)
successor(#20170,#20172)
successor(#20172,#20173)
successor(#20173,#20175)
successor(#20159,#20162)
successor(#20166,#20160)
successor(#20164,#20166)
successor(#20162,#20164)
successor(#20160,#20168)
successor(#20154,#20155)
#20209=*
guard_node(#20209,1,#20155)
hasLocation(#20209,#20156)
successor(#20209,#20157)
#20210=*
guard_node(#20210,0,#20155)
hasLocation(#20210,#20156)
successor(#20210,#20159)
successor(#20155,#20209)
successor(#20155,#20210)
successor(#20157,#20159)
successor(#20148,#20151)
successor(#20152,#20149)
successor(#20151,#20152)
successor(#20149,#20154)
successor(#20142,#20145)
successor(#20146,#20143)
successor(#20145,#20146)
successor(#20143,#20148)
successor(#20202,#20142)
numlines(#10000,9,8,4)
filetype(#10000,"javascript")

View File

@@ -8,116 +8,116 @@ locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},6,29"
#20002=*
lines(#20002,#20001,"void(alert(""Nope!""))","")
#20003=@"loc,{#10000},6,29,6,48"
locations_default(#20003,#10000,6,29,6,48)
hasLocation(#20002,#20003)
numlines(#20001,1,1,0)
#20004=*
tokeninfo(#20004,7,#20001,0,"void")
#20005=@"loc,{#10000},6,29,6,32"
locations_default(#20005,#10000,6,29,6,32)
hasLocation(#20004,#20005)
#20006=*
tokeninfo(#20006,8,#20001,1,"(")
#20007=@"loc,{#10000},6,33,6,33"
locations_default(#20007,#10000,6,33,6,33)
hasLocation(#20006,#20007)
#20008=*
tokeninfo(#20008,6,#20001,2,"alert")
#20009=@"loc,{#10000},6,34,6,38"
locations_default(#20009,#10000,6,34,6,38)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,8,#20001,3,"(")
#20011=@"loc,{#10000},6,39,6,39"
locations_default(#20011,#10000,6,39,6,39)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,4,#20001,4,"""Nope!""")
#20013=@"loc,{#10000},6,40,6,46"
locations_default(#20013,#10000,6,40,6,46)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,8,#20001,5,")")
#20015=@"loc,{#10000},6,47,6,47"
locations_default(#20015,#10000,6,47,6,47)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,8,#20001,6,")")
#20017=@"loc,{#10000},6,48,6,48"
locations_default(#20017,#10000,6,48,6,48)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,0,#20001,7,"")
#20019=@"loc,{#10000},6,49,6,48"
locations_default(#20019,#10000,6,49,6,48)
hasLocation(#20018,#20019)
toplevels(#20001,3)
hasLocation(#20001,#20003)
#20020=*
stmts(#20020,2,#20001,0,"void(alert(""Nope!""))")
hasLocation(#20020,#20003)
stmt_containers(#20020,#20001)
#20001=*
#20002=@"script;{#10000},6,29"
#20003=*
lines(#20003,#20002,"void(alert(""Nope!""))","")
#20004=@"loc,{#10000},6,29,6,48"
locations_default(#20004,#10000,6,29,6,48)
hasLocation(#20003,#20004)
numlines(#20002,1,1,0)
#20005=*
tokeninfo(#20005,7,#20002,0,"void")
#20006=@"loc,{#10000},6,29,6,32"
locations_default(#20006,#10000,6,29,6,32)
hasLocation(#20005,#20006)
#20007=*
tokeninfo(#20007,8,#20002,1,"(")
#20008=@"loc,{#10000},6,33,6,33"
locations_default(#20008,#10000,6,33,6,33)
hasLocation(#20007,#20008)
#20009=*
tokeninfo(#20009,6,#20002,2,"alert")
#20010=@"loc,{#10000},6,34,6,38"
locations_default(#20010,#10000,6,34,6,38)
hasLocation(#20009,#20010)
#20011=*
tokeninfo(#20011,8,#20002,3,"(")
#20012=@"loc,{#10000},6,39,6,39"
locations_default(#20012,#10000,6,39,6,39)
hasLocation(#20011,#20012)
#20013=*
tokeninfo(#20013,4,#20002,4,"""Nope!""")
#20014=@"loc,{#10000},6,40,6,46"
locations_default(#20014,#10000,6,40,6,46)
hasLocation(#20013,#20014)
#20015=*
tokeninfo(#20015,8,#20002,5,")")
#20016=@"loc,{#10000},6,47,6,47"
locations_default(#20016,#10000,6,47,6,47)
hasLocation(#20015,#20016)
#20017=*
tokeninfo(#20017,8,#20002,6,")")
#20018=@"loc,{#10000},6,48,6,48"
locations_default(#20018,#10000,6,48,6,48)
hasLocation(#20017,#20018)
#20019=*
tokeninfo(#20019,0,#20002,7,"")
#20020=@"loc,{#10000},6,49,6,48"
locations_default(#20020,#10000,6,49,6,48)
hasLocation(#20019,#20020)
toplevels(#20002,3)
hasLocation(#20002,#20004)
#20021=*
exprs(#20021,21,#20020,0,"void(alert(""Nope!""))")
hasLocation(#20021,#20003)
enclosing_stmt(#20021,#20020)
expr_containers(#20021,#20001)
stmts(#20021,2,#20002,0,"void(alert(""Nope!""))")
hasLocation(#20021,#20004)
stmt_containers(#20021,#20002)
#20022=*
exprs(#20022,63,#20021,0,"(alert(""Nope!""))")
#20023=@"loc,{#10000},6,33,6,48"
locations_default(#20023,#10000,6,33,6,48)
hasLocation(#20022,#20023)
enclosing_stmt(#20022,#20020)
expr_containers(#20022,#20001)
#20024=*
exprs(#20024,13,#20022,0,"alert(""Nope!"")")
#20025=@"loc,{#10000},6,34,6,47"
locations_default(#20025,#10000,6,34,6,47)
hasLocation(#20024,#20025)
enclosing_stmt(#20024,#20020)
expr_containers(#20024,#20001)
#20026=*
exprs(#20026,79,#20024,-1,"alert")
hasLocation(#20026,#20009)
enclosing_stmt(#20026,#20020)
expr_containers(#20026,#20001)
literals("alert","alert",#20026)
#20027=@"var;{alert};{#20000}"
variables(#20027,"alert",#20000)
bind(#20026,#20027)
#20028=*
exprs(#20028,4,#20024,0,"""Nope!""")
hasLocation(#20028,#20013)
enclosing_stmt(#20028,#20020)
expr_containers(#20028,#20001)
literals("Nope!","""Nope!""",#20028)
exprs(#20022,21,#20021,0,"void(alert(""Nope!""))")
hasLocation(#20022,#20004)
enclosing_stmt(#20022,#20021)
expr_containers(#20022,#20002)
#20023=*
exprs(#20023,63,#20022,0,"(alert(""Nope!""))")
#20024=@"loc,{#10000},6,33,6,48"
locations_default(#20024,#10000,6,33,6,48)
hasLocation(#20023,#20024)
enclosing_stmt(#20023,#20021)
expr_containers(#20023,#20002)
#20025=*
exprs(#20025,13,#20023,0,"alert(""Nope!"")")
#20026=@"loc,{#10000},6,34,6,47"
locations_default(#20026,#10000,6,34,6,47)
hasLocation(#20025,#20026)
enclosing_stmt(#20025,#20021)
expr_containers(#20025,#20002)
#20027=*
exprs(#20027,79,#20025,-1,"alert")
hasLocation(#20027,#20010)
enclosing_stmt(#20027,#20021)
expr_containers(#20027,#20002)
literals("alert","alert",#20027)
#20028=@"var;{alert};{#20000}"
variables(#20028,"alert",#20000)
bind(#20027,#20028)
#20029=*
regexpterm(#20029,14,#20028,0,"Nope!")
#20030=@"loc,{#10000},6,41,6,45"
locations_default(#20030,#10000,6,41,6,45)
hasLocation(#20029,#20030)
regexp_const_value(#20029,"Nope!")
#20031=*
entry_cfg_node(#20031,#20001)
#20032=@"loc,{#10000},6,29,6,28"
locations_default(#20032,#10000,6,29,6,28)
hasLocation(#20031,#20032)
#20033=*
exit_cfg_node(#20033,#20001)
hasLocation(#20033,#20019)
successor(#20020,#20022)
successor(#20022,#20026)
successor(#20028,#20024)
successor(#20026,#20028)
successor(#20024,#20021)
successor(#20021,#20033)
successor(#20031,#20020)
exprs(#20029,4,#20025,0,"""Nope!""")
hasLocation(#20029,#20014)
enclosing_stmt(#20029,#20021)
expr_containers(#20029,#20002)
literals("Nope!","""Nope!""",#20029)
#20030=*
regexpterm(#20030,14,#20029,0,"Nope!")
#20031=@"loc,{#10000},6,41,6,45"
locations_default(#20031,#10000,6,41,6,45)
hasLocation(#20030,#20031)
regexp_const_value(#20030,"Nope!")
#20032=*
entry_cfg_node(#20032,#20002)
#20033=@"loc,{#10000},6,29,6,28"
locations_default(#20033,#10000,6,29,6,28)
hasLocation(#20032,#20033)
#20034=*
toplevel_parent_xml_node(#20001,#20034)
exit_cfg_node(#20034,#20002)
hasLocation(#20034,#20020)
successor(#20021,#20023)
successor(#20023,#20027)
successor(#20029,#20025)
successor(#20027,#20029)
successor(#20025,#20022)
successor(#20022,#20034)
successor(#20032,#20021)
toplevel_parent_xml_node(#20002,#20001)
#20035=*
xmlElements(#20035,"html",#10000,0,#10000)
#20036=@"loc,{#10000},1,1,8,7"
@@ -133,10 +133,10 @@ xmlElements(#20039,"a",#20037,0,#10000)
#20040=@"loc,{#10000},6,9,6,80"
locations_default(#20040,#10000,6,9,6,80)
xmllocations(#20039,#20040)
xmlAttrs(#20034,#20039,"href","javascript:void(alert(""Nope!""))",0,#10000)
xmlAttrs(#20001,#20039,"href","javascript:void(alert(""Nope!""))",0,#10000)
#20041=@"loc,{#10000},6,12,6,65"
locations_default(#20041,#10000,6,12,6,65)
xmllocations(#20034,#20041)
xmllocations(#20001,#20041)
#20042=*
xmlElements(#20042,"head",#20035,0,#10000)
#20043=@"loc,{#10000},2,5,4,11"

View File

@@ -9,26 +9,26 @@ hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=*
json(#20001,5,#10000,0,"{""Hello"": 123}")
#20002=@"loc,{#10000},3,1,3,14"
locations_default(#20002,#10000,3,1,3,14)
json_locations(#20001,#20002)
#20003=*
json(#20003,2,#20001,0,"123")
#20004=@"loc,{#10000},3,11,3,13"
locations_default(#20004,#10000,3,11,3,13)
json_locations(#20003,#20004)
json_literals("123","123",#20003)
json_properties(#20001,"Hello",#20003)
#20005=*
xmlElements(#20005,"html",#10000,0,#10000)
#20006=@"loc,{#10000},1,1,5,7"
locations_default(#20006,#10000,1,1,5,7)
xmllocations(#20005,#20006)
#20007=*
xmlElements(#20007,"script",#20005,0,#10000)
#20002=*
json(#20002,5,#10000,0,"{""Hello"": 123}")
#20003=@"loc,{#10000},3,1,3,14"
locations_default(#20003,#10000,3,1,3,14)
json_locations(#20002,#20003)
#20004=*
json(#20004,2,#20002,0,"123")
#20005=@"loc,{#10000},3,11,3,13"
locations_default(#20005,#10000,3,11,3,13)
json_locations(#20004,#20005)
json_literals("123","123",#20004)
json_properties(#20002,"Hello",#20004)
#20006=*
xmlElements(#20006,"html",#10000,0,#10000)
#20007=@"loc,{#10000},1,1,5,7"
locations_default(#20007,#10000,1,1,5,7)
xmllocations(#20006,#20007)
xmlElements(#20001,"script",#20006,0,#10000)
#20008=@"loc,{#10000},2,1,4,9"
locations_default(#20008,#10000,2,1,4,9)
xmllocations(#20007,#20008)
xmllocations(#20001,#20008)
numlines(#10000,5,0,0)
filetype(#10000,"html")

View File

@@ -8,193 +8,193 @@ locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},4,31"
#20002=*
lines(#20002,#20001,"","
#20001=*
#20002=@"script;{#10000},4,31"
#20003=*
lines(#20003,#20002,"","
")
#20003=@"loc,{#10000},4,31,4,30"
locations_default(#20003,#10000,4,31,4,30)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001," import foo from 'bar';","
#20004=@"loc,{#10000},4,31,4,30"
locations_default(#20004,#10000,4,31,4,30)
hasLocation(#20003,#20004)
#20005=*
lines(#20005,#20002," import foo from 'bar';","
")
#20005=@"loc,{#10000},5,1,5,34"
locations_default(#20005,#10000,5,1,5,34)
hasLocation(#20004,#20005)
#20006=@"loc,{#10000},5,1,5,34"
locations_default(#20006,#10000,5,1,5,34)
hasLocation(#20005,#20006)
indentation(#10000,5," ",12)
#20006=*
lines(#20006,#20001," foo.baz();","
#20007=*
lines(#20007,#20002," foo.baz();","
")
#20007=@"loc,{#10000},6,1,6,22"
locations_default(#20007,#10000,6,1,6,22)
hasLocation(#20006,#20007)
#20008=@"loc,{#10000},6,1,6,22"
locations_default(#20008,#10000,6,1,6,22)
hasLocation(#20007,#20008)
indentation(#10000,6," ",12)
#20008=*
lines(#20008,#20001," ","")
#20009=@"loc,{#10000},7,1,7,8"
locations_default(#20009,#10000,7,1,7,8)
hasLocation(#20008,#20009)
numlines(#20001,4,2,0)
#20010=*
tokeninfo(#20010,7,#20001,0,"import")
#20011=@"loc,{#10000},5,13,5,18"
locations_default(#20011,#10000,5,13,5,18)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,6,#20001,1,"foo")
#20013=@"loc,{#10000},5,20,5,22"
locations_default(#20013,#10000,5,20,5,22)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,6,#20001,2,"from")
#20015=@"loc,{#10000},5,24,5,27"
locations_default(#20015,#10000,5,24,5,27)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,4,#20001,3,"'bar'")
#20017=@"loc,{#10000},5,29,5,33"
locations_default(#20017,#10000,5,29,5,33)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,8,#20001,4,";")
#20019=@"loc,{#10000},5,34,5,34"
locations_default(#20019,#10000,5,34,5,34)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,6,#20001,5,"foo")
#20021=@"loc,{#10000},6,13,6,15"
locations_default(#20021,#10000,6,13,6,15)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,8,#20001,6,".")
#20023=@"loc,{#10000},6,16,6,16"
locations_default(#20023,#10000,6,16,6,16)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,6,#20001,7,"baz")
#20025=@"loc,{#10000},6,17,6,19"
locations_default(#20025,#10000,6,17,6,19)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,8,#20001,8,"(")
#20027=@"loc,{#10000},6,20,6,20"
locations_default(#20027,#10000,6,20,6,20)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,8,#20001,9,")")
#20029=@"loc,{#10000},6,21,6,21"
locations_default(#20029,#10000,6,21,6,21)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,8,#20001,10,";")
#20031=@"loc,{#10000},6,22,6,22"
locations_default(#20031,#10000,6,22,6,22)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,0,#20001,11,"")
#20033=@"loc,{#10000},7,9,7,8"
locations_default(#20033,#10000,7,9,7,8)
hasLocation(#20032,#20033)
toplevels(#20001,1)
#20034=@"loc,{#10000},4,31,7,8"
locations_default(#20034,#10000,4,31,7,8)
hasLocation(#20001,#20034)
#20035=@"module;{#10000},4,31"
scopes(#20035,3)
scopenodes(#20001,#20035)
scopenesting(#20035,#20000)
is_module(#20001)
is_es2015_module(#20001)
#20036=@"var;{foo};{#20035}"
variables(#20036,"foo",#20035)
#20037=@"local_type_name;{foo};{#20035}"
local_type_names(#20037,"foo",#20035)
#20038=@"local_namespace_name;{foo};{#20035}"
local_namespace_names(#20038,"foo",#20035)
variables(#20036,"foo",#20035)
local_type_names(#20037,"foo",#20035)
local_namespace_names(#20038,"foo",#20035)
#20039=*
stmts(#20039,27,#20001,0,"import ... 'bar';")
#20040=@"loc,{#10000},5,13,5,34"
locations_default(#20040,#10000,5,13,5,34)
hasLocation(#20039,#20040)
stmt_containers(#20039,#20001)
#20041=*
exprs(#20041,4,#20039,-1,"'bar'")
hasLocation(#20041,#20017)
enclosing_stmt(#20041,#20039)
expr_containers(#20041,#20001)
literals("bar","'bar'",#20041)
#20009=*
lines(#20009,#20002," ","")
#20010=@"loc,{#10000},7,1,7,8"
locations_default(#20010,#10000,7,1,7,8)
hasLocation(#20009,#20010)
numlines(#20002,4,2,0)
#20011=*
tokeninfo(#20011,7,#20002,0,"import")
#20012=@"loc,{#10000},5,13,5,18"
locations_default(#20012,#10000,5,13,5,18)
hasLocation(#20011,#20012)
#20013=*
tokeninfo(#20013,6,#20002,1,"foo")
#20014=@"loc,{#10000},5,20,5,22"
locations_default(#20014,#10000,5,20,5,22)
hasLocation(#20013,#20014)
#20015=*
tokeninfo(#20015,6,#20002,2,"from")
#20016=@"loc,{#10000},5,24,5,27"
locations_default(#20016,#10000,5,24,5,27)
hasLocation(#20015,#20016)
#20017=*
tokeninfo(#20017,4,#20002,3,"'bar'")
#20018=@"loc,{#10000},5,29,5,33"
locations_default(#20018,#10000,5,29,5,33)
hasLocation(#20017,#20018)
#20019=*
tokeninfo(#20019,8,#20002,4,";")
#20020=@"loc,{#10000},5,34,5,34"
locations_default(#20020,#10000,5,34,5,34)
hasLocation(#20019,#20020)
#20021=*
tokeninfo(#20021,6,#20002,5,"foo")
#20022=@"loc,{#10000},6,13,6,15"
locations_default(#20022,#10000,6,13,6,15)
hasLocation(#20021,#20022)
#20023=*
tokeninfo(#20023,8,#20002,6,".")
#20024=@"loc,{#10000},6,16,6,16"
locations_default(#20024,#10000,6,16,6,16)
hasLocation(#20023,#20024)
#20025=*
tokeninfo(#20025,6,#20002,7,"baz")
#20026=@"loc,{#10000},6,17,6,19"
locations_default(#20026,#10000,6,17,6,19)
hasLocation(#20025,#20026)
#20027=*
tokeninfo(#20027,8,#20002,8,"(")
#20028=@"loc,{#10000},6,20,6,20"
locations_default(#20028,#10000,6,20,6,20)
hasLocation(#20027,#20028)
#20029=*
tokeninfo(#20029,8,#20002,9,")")
#20030=@"loc,{#10000},6,21,6,21"
locations_default(#20030,#10000,6,21,6,21)
hasLocation(#20029,#20030)
#20031=*
tokeninfo(#20031,8,#20002,10,";")
#20032=@"loc,{#10000},6,22,6,22"
locations_default(#20032,#10000,6,22,6,22)
hasLocation(#20031,#20032)
#20033=*
tokeninfo(#20033,0,#20002,11,"")
#20034=@"loc,{#10000},7,9,7,8"
locations_default(#20034,#10000,7,9,7,8)
hasLocation(#20033,#20034)
toplevels(#20002,1)
#20035=@"loc,{#10000},4,31,7,8"
locations_default(#20035,#10000,4,31,7,8)
hasLocation(#20002,#20035)
#20036=@"module;{#10000},4,31"
scopes(#20036,3)
scopenodes(#20002,#20036)
scopenesting(#20036,#20000)
is_module(#20002)
is_es2015_module(#20002)
#20037=@"var;{foo};{#20036}"
variables(#20037,"foo",#20036)
#20038=@"local_type_name;{foo};{#20036}"
local_type_names(#20038,"foo",#20036)
#20039=@"local_namespace_name;{foo};{#20036}"
local_namespace_names(#20039,"foo",#20036)
variables(#20037,"foo",#20036)
local_type_names(#20038,"foo",#20036)
local_namespace_names(#20039,"foo",#20036)
#20040=*
stmts(#20040,27,#20002,0,"import ... 'bar';")
#20041=@"loc,{#10000},5,13,5,34"
locations_default(#20041,#10000,5,13,5,34)
hasLocation(#20040,#20041)
stmt_containers(#20040,#20002)
#20042=*
regexpterm(#20042,14,#20041,0,"bar")
#20043=@"loc,{#10000},5,30,5,32"
locations_default(#20043,#10000,5,30,5,32)
hasLocation(#20042,#20043)
regexp_const_value(#20042,"bar")
#20044=*
exprs(#20044,84,#20039,0,"foo")
hasLocation(#20044,#20013)
enclosing_stmt(#20044,#20039)
expr_containers(#20044,#20001)
exprs(#20042,4,#20040,-1,"'bar'")
hasLocation(#20042,#20018)
enclosing_stmt(#20042,#20040)
expr_containers(#20042,#20002)
literals("bar","'bar'",#20042)
#20043=*
regexpterm(#20043,14,#20042,0,"bar")
#20044=@"loc,{#10000},5,30,5,32"
locations_default(#20044,#10000,5,30,5,32)
hasLocation(#20043,#20044)
regexp_const_value(#20043,"bar")
#20045=*
exprs(#20045,78,#20044,1,"foo")
hasLocation(#20045,#20013)
enclosing_stmt(#20045,#20039)
expr_containers(#20045,#20001)
literals("foo","foo",#20045)
decl(#20045,#20036)
typedecl(#20045,#20037)
namespacedecl(#20045,#20038)
exprs(#20045,84,#20040,0,"foo")
hasLocation(#20045,#20014)
enclosing_stmt(#20045,#20040)
expr_containers(#20045,#20002)
#20046=*
stmts(#20046,2,#20001,1,"foo.baz();")
#20047=@"loc,{#10000},6,13,6,22"
locations_default(#20047,#10000,6,13,6,22)
hasLocation(#20046,#20047)
stmt_containers(#20046,#20001)
#20048=*
exprs(#20048,13,#20046,0,"foo.baz()")
#20049=@"loc,{#10000},6,13,6,21"
locations_default(#20049,#10000,6,13,6,21)
hasLocation(#20048,#20049)
enclosing_stmt(#20048,#20046)
expr_containers(#20048,#20001)
#20050=*
exprs(#20050,14,#20048,-1,"foo.baz")
#20051=@"loc,{#10000},6,13,6,19"
locations_default(#20051,#10000,6,13,6,19)
hasLocation(#20050,#20051)
enclosing_stmt(#20050,#20046)
expr_containers(#20050,#20001)
#20052=*
exprs(#20052,79,#20050,0,"foo")
hasLocation(#20052,#20021)
enclosing_stmt(#20052,#20046)
expr_containers(#20052,#20001)
literals("foo","foo",#20052)
bind(#20052,#20036)
exprs(#20046,78,#20045,1,"foo")
hasLocation(#20046,#20014)
enclosing_stmt(#20046,#20040)
expr_containers(#20046,#20002)
literals("foo","foo",#20046)
decl(#20046,#20037)
typedecl(#20046,#20038)
namespacedecl(#20046,#20039)
#20047=*
stmts(#20047,2,#20002,1,"foo.baz();")
#20048=@"loc,{#10000},6,13,6,22"
locations_default(#20048,#10000,6,13,6,22)
hasLocation(#20047,#20048)
stmt_containers(#20047,#20002)
#20049=*
exprs(#20049,13,#20047,0,"foo.baz()")
#20050=@"loc,{#10000},6,13,6,21"
locations_default(#20050,#10000,6,13,6,21)
hasLocation(#20049,#20050)
enclosing_stmt(#20049,#20047)
expr_containers(#20049,#20002)
#20051=*
exprs(#20051,14,#20049,-1,"foo.baz")
#20052=@"loc,{#10000},6,13,6,19"
locations_default(#20052,#10000,6,13,6,19)
hasLocation(#20051,#20052)
enclosing_stmt(#20051,#20047)
expr_containers(#20051,#20002)
#20053=*
exprs(#20053,0,#20050,1,"baz")
hasLocation(#20053,#20025)
enclosing_stmt(#20053,#20046)
expr_containers(#20053,#20001)
literals("baz","baz",#20053)
exprs(#20053,79,#20051,0,"foo")
hasLocation(#20053,#20022)
enclosing_stmt(#20053,#20047)
expr_containers(#20053,#20002)
literals("foo","foo",#20053)
bind(#20053,#20037)
#20054=*
entry_cfg_node(#20054,#20001)
hasLocation(#20054,#20003)
exprs(#20054,0,#20051,1,"baz")
hasLocation(#20054,#20026)
enclosing_stmt(#20054,#20047)
expr_containers(#20054,#20002)
literals("baz","baz",#20054)
#20055=*
exit_cfg_node(#20055,#20001)
hasLocation(#20055,#20033)
successor(#20046,#20052)
successor(#20053,#20050)
successor(#20052,#20053)
successor(#20050,#20048)
successor(#20048,#20055)
successor(#20039,#20046)
successor(#20044,#20039)
successor(#20054,#20044)
entry_cfg_node(#20055,#20002)
hasLocation(#20055,#20004)
#20056=*
toplevel_parent_xml_node(#20001,#20056)
exit_cfg_node(#20056,#20002)
hasLocation(#20056,#20034)
successor(#20047,#20053)
successor(#20054,#20051)
successor(#20053,#20054)
successor(#20051,#20049)
successor(#20049,#20056)
successor(#20040,#20047)
successor(#20045,#20040)
successor(#20055,#20045)
toplevel_parent_xml_node(#20002,#20001)
#20057=*
xmlElements(#20057,"html",#10000,0,#10000)
#20058=@"loc,{#10000},1,1,11,7"
@@ -210,12 +210,12 @@ xmlElements(#20061,"head",#20057,0,#10000)
#20062=@"loc,{#10000},2,5,8,11"
locations_default(#20062,#10000,2,5,8,11)
xmllocations(#20061,#20062)
xmlElements(#20056,"script",#20061,1,#10000)
xmlElements(#20001,"script",#20061,1,#10000)
#20063=@"loc,{#10000},4,9,7,17"
locations_default(#20063,#10000,4,9,7,17)
xmllocations(#20056,#20063)
xmllocations(#20001,#20063)
#20064=*
xmlAttrs(#20064,#20056,"type","module",0,#10000)
xmlAttrs(#20064,#20001,"type","module",0,#10000)
#20065=@"loc,{#10000},4,17,4,29"
locations_default(#20065,#10000,4,17,4,29)
xmllocations(#20064,#20065)

View File

@@ -8,377 +8,377 @@ locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},5,17"
#20002=*
lines(#20002,#20001,"","
#20001=*
#20002=@"script;{#10000},5,17"
#20003=*
lines(#20003,#20002,"","
")
#20003=@"loc,{#10000},5,17,5,16"
locations_default(#20003,#10000,5,17,5,16)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001," alert(""Hello, world!"");","
#20004=@"loc,{#10000},5,17,5,16"
locations_default(#20004,#10000,5,17,5,16)
hasLocation(#20003,#20004)
#20005=*
lines(#20005,#20002," alert(""Hello, world!"");","
")
#20005=@"loc,{#10000},6,1,6,35"
locations_default(#20005,#10000,6,1,6,35)
hasLocation(#20004,#20005)
#20006=@"loc,{#10000},6,1,6,35"
locations_default(#20006,#10000,6,1,6,35)
hasLocation(#20005,#20006)
indentation(#10000,6," ",12)
#20006=*
lines(#20006,#20001," ","")
#20007=@"loc,{#10000},7,1,7,8"
locations_default(#20007,#10000,7,1,7,8)
hasLocation(#20006,#20007)
numlines(#20001,3,1,0)
#20008=*
tokeninfo(#20008,6,#20001,0,"alert")
#20009=@"loc,{#10000},6,13,6,17"
locations_default(#20009,#10000,6,13,6,17)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,8,#20001,1,"(")
#20011=@"loc,{#10000},6,18,6,18"
locations_default(#20011,#10000,6,18,6,18)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,4,#20001,2,"""Hello, world!""")
#20013=@"loc,{#10000},6,19,6,33"
locations_default(#20013,#10000,6,19,6,33)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,8,#20001,3,")")
#20015=@"loc,{#10000},6,34,6,34"
locations_default(#20015,#10000,6,34,6,34)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,8,#20001,4,";")
#20017=@"loc,{#10000},6,35,6,35"
locations_default(#20017,#10000,6,35,6,35)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,0,#20001,5,"")
#20019=@"loc,{#10000},7,9,7,8"
locations_default(#20019,#10000,7,9,7,8)
hasLocation(#20018,#20019)
toplevels(#20001,1)
#20020=@"loc,{#10000},5,17,7,8"
locations_default(#20020,#10000,5,17,7,8)
hasLocation(#20001,#20020)
#20021=*
stmts(#20021,2,#20001,0,"alert("" ... rld!"");")
#20022=@"loc,{#10000},6,13,6,35"
locations_default(#20022,#10000,6,13,6,35)
hasLocation(#20021,#20022)
stmt_containers(#20021,#20001)
#20023=*
exprs(#20023,13,#20021,0,"alert("" ... orld!"")")
#20024=@"loc,{#10000},6,13,6,34"
locations_default(#20024,#10000,6,13,6,34)
hasLocation(#20023,#20024)
enclosing_stmt(#20023,#20021)
expr_containers(#20023,#20001)
#20025=*
exprs(#20025,79,#20023,-1,"alert")
hasLocation(#20025,#20009)
enclosing_stmt(#20025,#20021)
expr_containers(#20025,#20001)
literals("alert","alert",#20025)
#20026=@"var;{alert};{#20000}"
variables(#20026,"alert",#20000)
bind(#20025,#20026)
#20027=*
exprs(#20027,4,#20023,0,"""Hello, world!""")
hasLocation(#20027,#20013)
enclosing_stmt(#20027,#20021)
expr_containers(#20027,#20001)
literals("Hello, world!","""Hello, world!""",#20027)
#20007=*
lines(#20007,#20002," ","")
#20008=@"loc,{#10000},7,1,7,8"
locations_default(#20008,#10000,7,1,7,8)
hasLocation(#20007,#20008)
numlines(#20002,3,1,0)
#20009=*
tokeninfo(#20009,6,#20002,0,"alert")
#20010=@"loc,{#10000},6,13,6,17"
locations_default(#20010,#10000,6,13,6,17)
hasLocation(#20009,#20010)
#20011=*
tokeninfo(#20011,8,#20002,1,"(")
#20012=@"loc,{#10000},6,18,6,18"
locations_default(#20012,#10000,6,18,6,18)
hasLocation(#20011,#20012)
#20013=*
tokeninfo(#20013,4,#20002,2,"""Hello, world!""")
#20014=@"loc,{#10000},6,19,6,33"
locations_default(#20014,#10000,6,19,6,33)
hasLocation(#20013,#20014)
#20015=*
tokeninfo(#20015,8,#20002,3,")")
#20016=@"loc,{#10000},6,34,6,34"
locations_default(#20016,#10000,6,34,6,34)
hasLocation(#20015,#20016)
#20017=*
tokeninfo(#20017,8,#20002,4,";")
#20018=@"loc,{#10000},6,35,6,35"
locations_default(#20018,#10000,6,35,6,35)
hasLocation(#20017,#20018)
#20019=*
tokeninfo(#20019,0,#20002,5,"")
#20020=@"loc,{#10000},7,9,7,8"
locations_default(#20020,#10000,7,9,7,8)
hasLocation(#20019,#20020)
toplevels(#20002,1)
#20021=@"loc,{#10000},5,17,7,8"
locations_default(#20021,#10000,5,17,7,8)
hasLocation(#20002,#20021)
#20022=*
stmts(#20022,2,#20002,0,"alert("" ... rld!"");")
#20023=@"loc,{#10000},6,13,6,35"
locations_default(#20023,#10000,6,13,6,35)
hasLocation(#20022,#20023)
stmt_containers(#20022,#20002)
#20024=*
exprs(#20024,13,#20022,0,"alert("" ... orld!"")")
#20025=@"loc,{#10000},6,13,6,34"
locations_default(#20025,#10000,6,13,6,34)
hasLocation(#20024,#20025)
enclosing_stmt(#20024,#20022)
expr_containers(#20024,#20002)
#20026=*
exprs(#20026,79,#20024,-1,"alert")
hasLocation(#20026,#20010)
enclosing_stmt(#20026,#20022)
expr_containers(#20026,#20002)
literals("alert","alert",#20026)
#20027=@"var;{alert};{#20000}"
variables(#20027,"alert",#20000)
bind(#20026,#20027)
#20028=*
regexpterm(#20028,14,#20027,0,"Hello, world!")
#20029=@"loc,{#10000},6,20,6,32"
locations_default(#20029,#10000,6,20,6,32)
hasLocation(#20028,#20029)
regexp_const_value(#20028,"Hello, world!")
#20030=*
entry_cfg_node(#20030,#20001)
hasLocation(#20030,#20003)
exprs(#20028,4,#20024,0,"""Hello, world!""")
hasLocation(#20028,#20014)
enclosing_stmt(#20028,#20022)
expr_containers(#20028,#20002)
literals("Hello, world!","""Hello, world!""",#20028)
#20029=*
regexpterm(#20029,14,#20028,0,"Hello, world!")
#20030=@"loc,{#10000},6,20,6,32"
locations_default(#20030,#10000,6,20,6,32)
hasLocation(#20029,#20030)
regexp_const_value(#20029,"Hello, world!")
#20031=*
exit_cfg_node(#20031,#20001)
hasLocation(#20031,#20019)
successor(#20021,#20025)
successor(#20027,#20023)
successor(#20025,#20027)
successor(#20023,#20031)
successor(#20030,#20021)
entry_cfg_node(#20031,#20002)
hasLocation(#20031,#20004)
#20032=*
toplevel_parent_xml_node(#20001,#20032)
#20033=@"script;{#10000},8,17"
#20034=*
lines(#20034,#20033,";","")
#20035=@"loc,{#10000},8,17,8,17"
locations_default(#20035,#10000,8,17,8,17)
hasLocation(#20034,#20035)
numlines(#20033,1,1,0)
#20036=*
tokeninfo(#20036,8,#20033,0,";")
hasLocation(#20036,#20035)
exit_cfg_node(#20032,#20002)
hasLocation(#20032,#20020)
successor(#20022,#20026)
successor(#20028,#20024)
successor(#20026,#20028)
successor(#20024,#20032)
successor(#20031,#20022)
toplevel_parent_xml_node(#20002,#20001)
#20033=*
#20034=@"script;{#10000},8,17"
#20035=*
lines(#20035,#20034,";","")
#20036=@"loc,{#10000},8,17,8,17"
locations_default(#20036,#10000,8,17,8,17)
hasLocation(#20035,#20036)
numlines(#20034,1,1,0)
#20037=*
tokeninfo(#20037,0,#20033,1,"")
#20038=@"loc,{#10000},8,18,8,17"
locations_default(#20038,#10000,8,18,8,17)
hasLocation(#20037,#20038)
toplevels(#20033,1)
hasLocation(#20033,#20035)
#20039=*
stmts(#20039,0,#20033,0,";")
hasLocation(#20039,#20035)
stmt_containers(#20039,#20033)
tokeninfo(#20037,8,#20034,0,";")
hasLocation(#20037,#20036)
#20038=*
tokeninfo(#20038,0,#20034,1,"")
#20039=@"loc,{#10000},8,18,8,17"
locations_default(#20039,#10000,8,18,8,17)
hasLocation(#20038,#20039)
toplevels(#20034,1)
hasLocation(#20034,#20036)
#20040=*
entry_cfg_node(#20040,#20033)
#20041=@"loc,{#10000},8,17,8,16"
locations_default(#20041,#10000,8,17,8,16)
hasLocation(#20040,#20041)
#20042=*
exit_cfg_node(#20042,#20033)
hasLocation(#20042,#20038)
successor(#20039,#20042)
successor(#20040,#20039)
stmts(#20040,0,#20034,0,";")
hasLocation(#20040,#20036)
stmt_containers(#20040,#20034)
#20041=*
entry_cfg_node(#20041,#20034)
#20042=@"loc,{#10000},8,17,8,16"
locations_default(#20042,#10000,8,17,8,16)
hasLocation(#20041,#20042)
#20043=*
toplevel_parent_xml_node(#20033,#20043)
#20044=@"script;{#10000},11,29"
#20045=*
lines(#20045,#20044,"void(alert('Nope!'))","")
#20046=@"loc,{#10000},11,29,11,48"
locations_default(#20046,#10000,11,29,11,48)
hasLocation(#20045,#20046)
numlines(#20044,1,1,0)
#20047=*
tokeninfo(#20047,7,#20044,0,"void")
#20048=@"loc,{#10000},11,29,11,32"
locations_default(#20048,#10000,11,29,11,32)
hasLocation(#20047,#20048)
#20049=*
tokeninfo(#20049,8,#20044,1,"(")
#20050=@"loc,{#10000},11,33,11,33"
locations_default(#20050,#10000,11,33,11,33)
hasLocation(#20049,#20050)
#20051=*
tokeninfo(#20051,6,#20044,2,"alert")
#20052=@"loc,{#10000},11,34,11,38"
locations_default(#20052,#10000,11,34,11,38)
hasLocation(#20051,#20052)
#20053=*
tokeninfo(#20053,8,#20044,3,"(")
#20054=@"loc,{#10000},11,39,11,39"
locations_default(#20054,#10000,11,39,11,39)
hasLocation(#20053,#20054)
#20055=*
tokeninfo(#20055,4,#20044,4,"'Nope!'")
#20056=@"loc,{#10000},11,40,11,46"
locations_default(#20056,#10000,11,40,11,46)
hasLocation(#20055,#20056)
#20057=*
tokeninfo(#20057,8,#20044,5,")")
#20058=@"loc,{#10000},11,47,11,47"
locations_default(#20058,#10000,11,47,11,47)
hasLocation(#20057,#20058)
#20059=*
tokeninfo(#20059,8,#20044,6,")")
#20060=@"loc,{#10000},11,48,11,48"
locations_default(#20060,#10000,11,48,11,48)
hasLocation(#20059,#20060)
#20061=*
tokeninfo(#20061,0,#20044,7,"")
#20062=@"loc,{#10000},11,49,11,48"
locations_default(#20062,#10000,11,49,11,48)
hasLocation(#20061,#20062)
toplevels(#20044,3)
hasLocation(#20044,#20046)
#20063=*
stmts(#20063,2,#20044,0,"void(alert('Nope!'))")
hasLocation(#20063,#20046)
stmt_containers(#20063,#20044)
exit_cfg_node(#20043,#20034)
hasLocation(#20043,#20039)
successor(#20040,#20043)
successor(#20041,#20040)
toplevel_parent_xml_node(#20034,#20033)
#20044=*
#20045=@"script;{#10000},11,29"
#20046=*
lines(#20046,#20045,"void(alert('Nope!'))","")
#20047=@"loc,{#10000},11,29,11,48"
locations_default(#20047,#10000,11,29,11,48)
hasLocation(#20046,#20047)
numlines(#20045,1,1,0)
#20048=*
tokeninfo(#20048,7,#20045,0,"void")
#20049=@"loc,{#10000},11,29,11,32"
locations_default(#20049,#10000,11,29,11,32)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,8,#20045,1,"(")
#20051=@"loc,{#10000},11,33,11,33"
locations_default(#20051,#10000,11,33,11,33)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,6,#20045,2,"alert")
#20053=@"loc,{#10000},11,34,11,38"
locations_default(#20053,#10000,11,34,11,38)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,8,#20045,3,"(")
#20055=@"loc,{#10000},11,39,11,39"
locations_default(#20055,#10000,11,39,11,39)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,4,#20045,4,"'Nope!'")
#20057=@"loc,{#10000},11,40,11,46"
locations_default(#20057,#10000,11,40,11,46)
hasLocation(#20056,#20057)
#20058=*
tokeninfo(#20058,8,#20045,5,")")
#20059=@"loc,{#10000},11,47,11,47"
locations_default(#20059,#10000,11,47,11,47)
hasLocation(#20058,#20059)
#20060=*
tokeninfo(#20060,8,#20045,6,")")
#20061=@"loc,{#10000},11,48,11,48"
locations_default(#20061,#10000,11,48,11,48)
hasLocation(#20060,#20061)
#20062=*
tokeninfo(#20062,0,#20045,7,"")
#20063=@"loc,{#10000},11,49,11,48"
locations_default(#20063,#10000,11,49,11,48)
hasLocation(#20062,#20063)
toplevels(#20045,3)
hasLocation(#20045,#20047)
#20064=*
exprs(#20064,21,#20063,0,"void(alert('Nope!'))")
hasLocation(#20064,#20046)
enclosing_stmt(#20064,#20063)
expr_containers(#20064,#20044)
stmts(#20064,2,#20045,0,"void(alert('Nope!'))")
hasLocation(#20064,#20047)
stmt_containers(#20064,#20045)
#20065=*
exprs(#20065,63,#20064,0,"(alert('Nope!'))")
#20066=@"loc,{#10000},11,33,11,48"
locations_default(#20066,#10000,11,33,11,48)
hasLocation(#20065,#20066)
enclosing_stmt(#20065,#20063)
expr_containers(#20065,#20044)
#20067=*
exprs(#20067,13,#20065,0,"alert('Nope!')")
#20068=@"loc,{#10000},11,34,11,47"
locations_default(#20068,#10000,11,34,11,47)
hasLocation(#20067,#20068)
enclosing_stmt(#20067,#20063)
expr_containers(#20067,#20044)
#20069=*
exprs(#20069,79,#20067,-1,"alert")
hasLocation(#20069,#20052)
enclosing_stmt(#20069,#20063)
expr_containers(#20069,#20044)
literals("alert","alert",#20069)
bind(#20069,#20026)
exprs(#20065,21,#20064,0,"void(alert('Nope!'))")
hasLocation(#20065,#20047)
enclosing_stmt(#20065,#20064)
expr_containers(#20065,#20045)
#20066=*
exprs(#20066,63,#20065,0,"(alert('Nope!'))")
#20067=@"loc,{#10000},11,33,11,48"
locations_default(#20067,#10000,11,33,11,48)
hasLocation(#20066,#20067)
enclosing_stmt(#20066,#20064)
expr_containers(#20066,#20045)
#20068=*
exprs(#20068,13,#20066,0,"alert('Nope!')")
#20069=@"loc,{#10000},11,34,11,47"
locations_default(#20069,#10000,11,34,11,47)
hasLocation(#20068,#20069)
enclosing_stmt(#20068,#20064)
expr_containers(#20068,#20045)
#20070=*
exprs(#20070,4,#20067,0,"'Nope!'")
hasLocation(#20070,#20056)
enclosing_stmt(#20070,#20063)
expr_containers(#20070,#20044)
literals("Nope!","'Nope!'",#20070)
exprs(#20070,79,#20068,-1,"alert")
hasLocation(#20070,#20053)
enclosing_stmt(#20070,#20064)
expr_containers(#20070,#20045)
literals("alert","alert",#20070)
bind(#20070,#20027)
#20071=*
regexpterm(#20071,14,#20070,0,"Nope!")
#20072=@"loc,{#10000},11,41,11,45"
locations_default(#20072,#10000,11,41,11,45)
hasLocation(#20071,#20072)
regexp_const_value(#20071,"Nope!")
#20073=*
entry_cfg_node(#20073,#20044)
#20074=@"loc,{#10000},11,29,11,28"
locations_default(#20074,#10000,11,29,11,28)
hasLocation(#20073,#20074)
#20075=*
exit_cfg_node(#20075,#20044)
hasLocation(#20075,#20062)
successor(#20063,#20065)
successor(#20065,#20069)
successor(#20070,#20067)
successor(#20069,#20070)
successor(#20067,#20064)
successor(#20064,#20075)
successor(#20073,#20063)
exprs(#20071,4,#20068,0,"'Nope!'")
hasLocation(#20071,#20057)
enclosing_stmt(#20071,#20064)
expr_containers(#20071,#20045)
literals("Nope!","'Nope!'",#20071)
#20072=*
regexpterm(#20072,14,#20071,0,"Nope!")
#20073=@"loc,{#10000},11,41,11,45"
locations_default(#20073,#10000,11,41,11,45)
hasLocation(#20072,#20073)
regexp_const_value(#20072,"Nope!")
#20074=*
entry_cfg_node(#20074,#20045)
#20075=@"loc,{#10000},11,29,11,28"
locations_default(#20075,#10000,11,29,11,28)
hasLocation(#20074,#20075)
#20076=*
toplevel_parent_xml_node(#20044,#20076)
#20077=@"script;{#10000},12,23"
#20078=*
lines(#20078,#20077,"alert('I said don\'t click!')","")
#20079=@"loc,{#10000},12,23,12,51"
locations_default(#20079,#10000,12,23,12,51)
hasLocation(#20078,#20079)
numlines(#20077,1,1,0)
#20080=*
tokeninfo(#20080,6,#20077,0,"alert")
#20081=@"loc,{#10000},12,23,12,27"
locations_default(#20081,#10000,12,23,12,27)
hasLocation(#20080,#20081)
#20082=*
tokeninfo(#20082,8,#20077,1,"(")
#20083=@"loc,{#10000},12,28,12,28"
locations_default(#20083,#10000,12,28,12,28)
hasLocation(#20082,#20083)
#20084=*
tokeninfo(#20084,4,#20077,2,"'I said don\'t click!'")
#20085=@"loc,{#10000},12,29,12,50"
locations_default(#20085,#10000,12,29,12,50)
hasLocation(#20084,#20085)
#20086=*
tokeninfo(#20086,8,#20077,3,")")
#20087=@"loc,{#10000},12,51,12,51"
locations_default(#20087,#10000,12,51,12,51)
hasLocation(#20086,#20087)
#20088=*
tokeninfo(#20088,0,#20077,4,"")
#20089=@"loc,{#10000},12,52,12,51"
locations_default(#20089,#10000,12,52,12,51)
hasLocation(#20088,#20089)
toplevels(#20077,2)
hasLocation(#20077,#20079)
#20090=*
stmts(#20090,2,#20077,0,"alert(' ... lick!')")
hasLocation(#20090,#20079)
stmt_containers(#20090,#20077)
exit_cfg_node(#20076,#20045)
hasLocation(#20076,#20063)
successor(#20064,#20066)
successor(#20066,#20070)
successor(#20071,#20068)
successor(#20070,#20071)
successor(#20068,#20065)
successor(#20065,#20076)
successor(#20074,#20064)
toplevel_parent_xml_node(#20045,#20044)
#20077=*
#20078=@"script;{#10000},12,23"
#20079=*
lines(#20079,#20078,"alert('I said don\'t click!')","")
#20080=@"loc,{#10000},12,23,12,51"
locations_default(#20080,#10000,12,23,12,51)
hasLocation(#20079,#20080)
numlines(#20078,1,1,0)
#20081=*
tokeninfo(#20081,6,#20078,0,"alert")
#20082=@"loc,{#10000},12,23,12,27"
locations_default(#20082,#10000,12,23,12,27)
hasLocation(#20081,#20082)
#20083=*
tokeninfo(#20083,8,#20078,1,"(")
#20084=@"loc,{#10000},12,28,12,28"
locations_default(#20084,#10000,12,28,12,28)
hasLocation(#20083,#20084)
#20085=*
tokeninfo(#20085,4,#20078,2,"'I said don\'t click!'")
#20086=@"loc,{#10000},12,29,12,50"
locations_default(#20086,#10000,12,29,12,50)
hasLocation(#20085,#20086)
#20087=*
tokeninfo(#20087,8,#20078,3,")")
#20088=@"loc,{#10000},12,51,12,51"
locations_default(#20088,#10000,12,51,12,51)
hasLocation(#20087,#20088)
#20089=*
tokeninfo(#20089,0,#20078,4,"")
#20090=@"loc,{#10000},12,52,12,51"
locations_default(#20090,#10000,12,52,12,51)
hasLocation(#20089,#20090)
toplevels(#20078,2)
hasLocation(#20078,#20080)
#20091=*
exprs(#20091,13,#20090,0,"alert(' ... lick!')")
hasLocation(#20091,#20079)
enclosing_stmt(#20091,#20090)
expr_containers(#20091,#20077)
stmts(#20091,2,#20078,0,"alert(' ... lick!')")
hasLocation(#20091,#20080)
stmt_containers(#20091,#20078)
#20092=*
exprs(#20092,79,#20091,-1,"alert")
hasLocation(#20092,#20081)
enclosing_stmt(#20092,#20090)
expr_containers(#20092,#20077)
literals("alert","alert",#20092)
bind(#20092,#20026)
exprs(#20092,13,#20091,0,"alert(' ... lick!')")
hasLocation(#20092,#20080)
enclosing_stmt(#20092,#20091)
expr_containers(#20092,#20078)
#20093=*
exprs(#20093,4,#20091,0,"'I said ... click!'")
hasLocation(#20093,#20085)
enclosing_stmt(#20093,#20090)
expr_containers(#20093,#20077)
literals("I said don't click!","'I said don\'t click!'",#20093)
exprs(#20093,79,#20092,-1,"alert")
hasLocation(#20093,#20082)
enclosing_stmt(#20093,#20091)
expr_containers(#20093,#20078)
literals("alert","alert",#20093)
bind(#20093,#20027)
#20094=*
regexpterm(#20094,14,#20093,0,"I said don't click!")
#20095=@"loc,{#10000},12,30,12,49"
locations_default(#20095,#10000,12,30,12,49)
hasLocation(#20094,#20095)
regexp_const_value(#20094,"I said don't click!")
#20096=*
entry_cfg_node(#20096,#20077)
#20097=@"loc,{#10000},12,23,12,22"
locations_default(#20097,#10000,12,23,12,22)
hasLocation(#20096,#20097)
#20098=*
exit_cfg_node(#20098,#20077)
hasLocation(#20098,#20089)
successor(#20090,#20092)
successor(#20093,#20091)
successor(#20092,#20093)
successor(#20091,#20098)
successor(#20096,#20090)
exprs(#20094,4,#20092,0,"'I said ... click!'")
hasLocation(#20094,#20086)
enclosing_stmt(#20094,#20091)
expr_containers(#20094,#20078)
literals("I said don't click!","'I said don\'t click!'",#20094)
#20095=*
regexpterm(#20095,14,#20094,0,"I said don't click!")
#20096=@"loc,{#10000},12,30,12,49"
locations_default(#20096,#10000,12,30,12,49)
hasLocation(#20095,#20096)
regexp_const_value(#20095,"I said don't click!")
#20097=*
entry_cfg_node(#20097,#20078)
#20098=@"loc,{#10000},12,23,12,22"
locations_default(#20098,#10000,12,23,12,22)
hasLocation(#20097,#20098)
#20099=*
toplevel_parent_xml_node(#20077,#20099)
#20100=@"script;{#10000},13,21"
#20101=*
lines(#20101,#20100,"return false;","")
#20102=@"loc,{#10000},13,21,13,33"
locations_default(#20102,#10000,13,21,13,33)
hasLocation(#20101,#20102)
numlines(#20100,1,1,0)
#20103=*
tokeninfo(#20103,7,#20100,0,"return")
#20104=@"loc,{#10000},13,21,13,26"
locations_default(#20104,#10000,13,21,13,26)
hasLocation(#20103,#20104)
#20105=*
tokeninfo(#20105,2,#20100,1,"false")
#20106=@"loc,{#10000},13,28,13,32"
locations_default(#20106,#10000,13,28,13,32)
hasLocation(#20105,#20106)
#20107=*
tokeninfo(#20107,8,#20100,2,";")
#20108=@"loc,{#10000},13,33,13,33"
locations_default(#20108,#10000,13,33,13,33)
hasLocation(#20107,#20108)
#20109=*
tokeninfo(#20109,0,#20100,3,"")
#20110=@"loc,{#10000},13,34,13,33"
locations_default(#20110,#10000,13,34,13,33)
hasLocation(#20109,#20110)
toplevels(#20100,2)
hasLocation(#20100,#20102)
#20111=*
stmts(#20111,9,#20100,0,"return false;")
hasLocation(#20111,#20102)
stmt_containers(#20111,#20100)
exit_cfg_node(#20099,#20078)
hasLocation(#20099,#20090)
successor(#20091,#20093)
successor(#20094,#20092)
successor(#20093,#20094)
successor(#20092,#20099)
successor(#20097,#20091)
toplevel_parent_xml_node(#20078,#20077)
#20100=*
#20101=@"script;{#10000},13,21"
#20102=*
lines(#20102,#20101,"return false;","")
#20103=@"loc,{#10000},13,21,13,33"
locations_default(#20103,#10000,13,21,13,33)
hasLocation(#20102,#20103)
numlines(#20101,1,1,0)
#20104=*
tokeninfo(#20104,7,#20101,0,"return")
#20105=@"loc,{#10000},13,21,13,26"
locations_default(#20105,#10000,13,21,13,26)
hasLocation(#20104,#20105)
#20106=*
tokeninfo(#20106,2,#20101,1,"false")
#20107=@"loc,{#10000},13,28,13,32"
locations_default(#20107,#10000,13,28,13,32)
hasLocation(#20106,#20107)
#20108=*
tokeninfo(#20108,8,#20101,2,";")
#20109=@"loc,{#10000},13,33,13,33"
locations_default(#20109,#10000,13,33,13,33)
hasLocation(#20108,#20109)
#20110=*
tokeninfo(#20110,0,#20101,3,"")
#20111=@"loc,{#10000},13,34,13,33"
locations_default(#20111,#10000,13,34,13,33)
hasLocation(#20110,#20111)
toplevels(#20101,2)
hasLocation(#20101,#20103)
#20112=*
exprs(#20112,2,#20111,0,"false")
hasLocation(#20112,#20106)
enclosing_stmt(#20112,#20111)
expr_containers(#20112,#20100)
literals("false","false",#20112)
stmts(#20112,9,#20101,0,"return false;")
hasLocation(#20112,#20103)
stmt_containers(#20112,#20101)
#20113=*
entry_cfg_node(#20113,#20100)
#20114=@"loc,{#10000},13,21,13,20"
locations_default(#20114,#10000,13,21,13,20)
hasLocation(#20113,#20114)
#20115=*
exit_cfg_node(#20115,#20100)
hasLocation(#20115,#20110)
successor(#20112,#20111)
successor(#20111,#20115)
successor(#20113,#20112)
exprs(#20113,2,#20112,0,"false")
hasLocation(#20113,#20107)
enclosing_stmt(#20113,#20112)
expr_containers(#20113,#20101)
literals("false","false",#20113)
#20114=*
entry_cfg_node(#20114,#20101)
#20115=@"loc,{#10000},13,21,13,20"
locations_default(#20115,#10000,13,21,13,20)
hasLocation(#20114,#20115)
#20116=*
toplevel_parent_xml_node(#20100,#20116)
exit_cfg_node(#20116,#20101)
hasLocation(#20116,#20111)
successor(#20113,#20112)
successor(#20112,#20116)
successor(#20114,#20113)
toplevel_parent_xml_node(#20101,#20100)
#20117=*
xmlElements(#20117,"html",#10000,0,#10000)
#20118=@"loc,{#10000},1,1,18,7"
@@ -405,74 +405,180 @@ xmlAttrs(#20125,#20123,"TYPE","text/x-handlebars-template",0,#10000)
locations_default(#20126,#10000,16,13,16,45)
xmllocations(#20125,#20126)
#20127=*
xmlElements(#20127,"script",#20117,2,#10000)
#20128=@"loc,{#10000},15,5,15,71"
locations_default(#20128,#10000,15,5,15,71)
xmllocations(#20127,#20128)
#20129=*
xmlAttrs(#20129,#20127,"type","text/x-handlebars-template",0,#10000)
#20130=@"loc,{#10000},15,13,15,45"
locations_default(#20130,#10000,15,13,15,45)
xmllocations(#20129,#20130)
#20131=*
xmlElements(#20131,"body",#20117,1,#10000)
#20132=@"loc,{#10000},10,5,14,11"
locations_default(#20132,#10000,10,5,14,11)
xmllocations(#20131,#20132)
template_placeholder_tag_info(#20127,#20123,"{{name}}")
#20128=@"loc,{#10000},16,54,16,61"
locations_default(#20128,#10000,16,54,16,61)
hasLocation(#20127,#20128)
scopes(#20000,0)
#20129=@"script;{#10000},16,56"
#20130=*
lines(#20130,#20129,"name","")
#20131=@"loc,{#10000},16,56,16,59"
locations_default(#20131,#10000,16,56,16,59)
hasLocation(#20130,#20131)
numlines(#20129,1,1,0)
#20132=*
tokeninfo(#20132,6,#20129,0,"name")
hasLocation(#20132,#20131)
#20133=*
xmlElements(#20133,"a",#20131,2,#10000)
#20134=@"loc,{#10000},13,9,13,59"
locations_default(#20134,#10000,13,9,13,59)
xmllocations(#20133,#20134)
xmlAttrs(#20116,#20133,"onclick","return false;",0,#10000)
#20135=@"loc,{#10000},13,12,13,34"
locations_default(#20135,#10000,13,12,13,34)
xmllocations(#20116,#20135)
tokeninfo(#20133,0,#20129,1,"")
#20134=@"loc,{#10000},16,60,16,59"
locations_default(#20134,#10000,16,60,16,59)
hasLocation(#20133,#20134)
toplevels(#20129,4)
hasLocation(#20129,#20131)
#20135=@"module;{#10000},16,56"
scopes(#20135,3)
scopenodes(#20129,#20135)
scopenesting(#20135,#20000)
is_module(#20129)
#20136=*
xmlElements(#20136,"div",#20131,1,#10000)
#20137=@"loc,{#10000},12,9,12,75"
locations_default(#20137,#10000,12,9,12,75)
xmllocations(#20136,#20137)
xmlAttrs(#20099,#20136,"onclick","alert('I said don\'t click!')",0,#10000)
#20138=@"loc,{#10000},12,14,12,52"
locations_default(#20138,#10000,12,14,12,52)
xmllocations(#20099,#20138)
stmts(#20136,2,#20129,0,"name")
hasLocation(#20136,#20131)
stmt_containers(#20136,#20129)
#20137=*
exprs(#20137,79,#20136,0,"name")
hasLocation(#20137,#20131)
enclosing_stmt(#20137,#20136)
expr_containers(#20137,#20129)
literals("name","name",#20137)
#20138=@"var;{name};{#20135}"
variables(#20138,"name",#20135)
bind(#20137,#20138)
#20139=*
xmlElements(#20139,"a",#20131,0,#10000)
#20140=@"loc,{#10000},11,9,11,64"
locations_default(#20140,#10000,11,9,11,64)
xmllocations(#20139,#20140)
xmlAttrs(#20076,#20139,"href","javascript:void(alert('Nope!'))",0,#10000)
#20141=@"loc,{#10000},11,12,11,49"
locations_default(#20141,#10000,11,12,11,49)
xmllocations(#20076,#20141)
entry_cfg_node(#20139,#20129)
#20140=@"loc,{#10000},16,56,16,55"
locations_default(#20140,#10000,16,56,16,55)
hasLocation(#20139,#20140)
#20141=*
exit_cfg_node(#20141,#20129)
hasLocation(#20141,#20134)
successor(#20136,#20137)
successor(#20137,#20141)
successor(#20139,#20136)
toplevel_parent_xml_node(#20129,#20127)
#20142=*
xmlElements(#20142,"head",#20117,0,#10000)
#20143=@"loc,{#10000},2,5,9,11"
locations_default(#20143,#10000,2,5,9,11)
xmlElements(#20142,"script",#20117,2,#10000)
#20143=@"loc,{#10000},15,5,15,71"
locations_default(#20143,#10000,15,5,15,71)
xmllocations(#20142,#20143)
xmlElements(#20043,"script",#20142,3,#10000)
#20144=@"loc,{#10000},8,9,8,26"
locations_default(#20144,#10000,8,9,8,26)
xmllocations(#20043,#20144)
xmlElements(#20032,"script",#20142,2,#10000)
#20145=@"loc,{#10000},5,9,7,17"
locations_default(#20145,#10000,5,9,7,17)
xmllocations(#20032,#20145)
#20144=*
xmlAttrs(#20144,#20142,"type","text/x-handlebars-template",0,#10000)
#20145=@"loc,{#10000},15,13,15,45"
locations_default(#20145,#10000,15,13,15,45)
xmllocations(#20144,#20145)
#20146=*
xmlElements(#20146,"script",#20142,1,#10000)
#20147=@"loc,{#10000},4,9,4,43"
locations_default(#20147,#10000,4,9,4,43)
xmllocations(#20146,#20147)
#20148=*
xmlAttrs(#20148,#20146,"src","external.js",0,#10000)
#20149=@"loc,{#10000},4,17,4,33"
locations_default(#20149,#10000,4,17,4,33)
xmllocations(#20148,#20149)
#20150=*
xmlElements(#20150,"title",#20142,0,#10000)
#20151=@"loc,{#10000},3,9,3,32"
locations_default(#20151,#10000,3,9,3,32)
xmllocations(#20150,#20151)
numlines(#10000,18,5,0)
template_placeholder_tag_info(#20146,#20142,"{{name}}")
#20147=@"loc,{#10000},15,54,15,61"
locations_default(#20147,#10000,15,54,15,61)
hasLocation(#20146,#20147)
scopes(#20000,0)
#20148=@"script;{#10000},15,56"
#20149=*
lines(#20149,#20148,"name","")
#20150=@"loc,{#10000},15,56,15,59"
locations_default(#20150,#10000,15,56,15,59)
hasLocation(#20149,#20150)
numlines(#20148,1,1,0)
#20151=*
tokeninfo(#20151,6,#20148,0,"name")
hasLocation(#20151,#20150)
#20152=*
tokeninfo(#20152,0,#20148,1,"")
#20153=@"loc,{#10000},15,60,15,59"
locations_default(#20153,#10000,15,60,15,59)
hasLocation(#20152,#20153)
toplevels(#20148,4)
hasLocation(#20148,#20150)
#20154=@"module;{#10000},15,56"
scopes(#20154,3)
scopenodes(#20148,#20154)
scopenesting(#20154,#20000)
is_module(#20148)
#20155=*
stmts(#20155,2,#20148,0,"name")
hasLocation(#20155,#20150)
stmt_containers(#20155,#20148)
#20156=*
exprs(#20156,79,#20155,0,"name")
hasLocation(#20156,#20150)
enclosing_stmt(#20156,#20155)
expr_containers(#20156,#20148)
literals("name","name",#20156)
#20157=@"var;{name};{#20154}"
variables(#20157,"name",#20154)
bind(#20156,#20157)
#20158=*
entry_cfg_node(#20158,#20148)
#20159=@"loc,{#10000},15,56,15,55"
locations_default(#20159,#10000,15,56,15,55)
hasLocation(#20158,#20159)
#20160=*
exit_cfg_node(#20160,#20148)
hasLocation(#20160,#20153)
successor(#20155,#20156)
successor(#20156,#20160)
successor(#20158,#20155)
toplevel_parent_xml_node(#20148,#20146)
#20161=*
xmlElements(#20161,"body",#20117,1,#10000)
#20162=@"loc,{#10000},10,5,14,11"
locations_default(#20162,#10000,10,5,14,11)
xmllocations(#20161,#20162)
#20163=*
xmlElements(#20163,"a",#20161,2,#10000)
#20164=@"loc,{#10000},13,9,13,59"
locations_default(#20164,#10000,13,9,13,59)
xmllocations(#20163,#20164)
xmlAttrs(#20100,#20163,"onclick","return false;",0,#10000)
#20165=@"loc,{#10000},13,12,13,34"
locations_default(#20165,#10000,13,12,13,34)
xmllocations(#20100,#20165)
#20166=*
xmlElements(#20166,"div",#20161,1,#10000)
#20167=@"loc,{#10000},12,9,12,75"
locations_default(#20167,#10000,12,9,12,75)
xmllocations(#20166,#20167)
xmlAttrs(#20077,#20166,"onclick","alert('I said don\'t click!')",0,#10000)
#20168=@"loc,{#10000},12,14,12,52"
locations_default(#20168,#10000,12,14,12,52)
xmllocations(#20077,#20168)
#20169=*
xmlElements(#20169,"a",#20161,0,#10000)
#20170=@"loc,{#10000},11,9,11,64"
locations_default(#20170,#10000,11,9,11,64)
xmllocations(#20169,#20170)
xmlAttrs(#20044,#20169,"href","javascript:void(alert('Nope!'))",0,#10000)
#20171=@"loc,{#10000},11,12,11,49"
locations_default(#20171,#10000,11,12,11,49)
xmllocations(#20044,#20171)
#20172=*
xmlElements(#20172,"head",#20117,0,#10000)
#20173=@"loc,{#10000},2,5,9,11"
locations_default(#20173,#10000,2,5,9,11)
xmllocations(#20172,#20173)
xmlElements(#20033,"script",#20172,3,#10000)
#20174=@"loc,{#10000},8,9,8,26"
locations_default(#20174,#10000,8,9,8,26)
xmllocations(#20033,#20174)
xmlElements(#20001,"script",#20172,2,#10000)
#20175=@"loc,{#10000},5,9,7,17"
locations_default(#20175,#10000,5,9,7,17)
xmllocations(#20001,#20175)
#20176=*
xmlElements(#20176,"script",#20172,1,#10000)
#20177=@"loc,{#10000},4,9,4,43"
locations_default(#20177,#10000,4,9,4,43)
xmllocations(#20176,#20177)
#20178=*
xmlAttrs(#20178,#20176,"src","external.js",0,#10000)
#20179=@"loc,{#10000},4,17,4,33"
locations_default(#20179,#10000,4,17,4,33)
xmllocations(#20178,#20179)
#20180=*
xmlElements(#20180,"title",#20172,0,#10000)
#20181=@"loc,{#10000},3,9,3,32"
locations_default(#20181,#10000,3,9,3,32)
xmllocations(#20180,#20181)
numlines(#10000,18,7,0)
filetype(#10000,"html")

View File

@@ -8,74 +8,74 @@ locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},7,43"
#20002=*
lines(#20002,#20001,"","
#20001=*
#20002=@"script;{#10000},7,43"
#20003=*
lines(#20003,#20002,"","
")
#20003=@"loc,{#10000},7,43,7,42"
locations_default(#20003,#10000,7,43,7,42)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001," ","
#20004=@"loc,{#10000},7,43,7,42"
locations_default(#20004,#10000,7,43,7,42)
hasLocation(#20003,#20004)
#20005=*
lines(#20005,#20002," ","
")
#20005=@"loc,{#10000},8,1,8,14"
locations_default(#20005,#10000,8,1,8,14)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001," 42;","
#20006=@"loc,{#10000},8,1,8,14"
locations_default(#20006,#10000,8,1,8,14)
hasLocation(#20005,#20006)
#20007=*
lines(#20007,#20002," 42;","
")
#20007=@"loc,{#10000},9,1,9,7"
locations_default(#20007,#10000,9,1,9,7)
hasLocation(#20006,#20007)
#20008=@"loc,{#10000},9,1,9,7"
locations_default(#20008,#10000,9,1,9,7)
hasLocation(#20007,#20008)
indentation(#10000,9," ",4)
#20008=*
lines(#20008,#20001," ","")
#20009=@"loc,{#10000},10,1,10,7"
locations_default(#20009,#10000,10,1,10,7)
hasLocation(#20008,#20009)
numlines(#20001,4,1,0)
#20010=*
tokeninfo(#20010,3,#20001,0,"42")
#20011=@"loc,{#10000},9,5,9,6"
locations_default(#20011,#10000,9,5,9,6)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,8,#20001,1,";")
#20013=@"loc,{#10000},9,7,9,7"
locations_default(#20013,#10000,9,7,9,7)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,0,#20001,2,"")
#20015=@"loc,{#10000},10,8,10,7"
locations_default(#20015,#10000,10,8,10,7)
hasLocation(#20014,#20015)
toplevels(#20001,1)
#20016=@"loc,{#10000},7,43,10,7"
locations_default(#20016,#10000,7,43,10,7)
hasLocation(#20001,#20016)
#20017=*
stmts(#20017,2,#20001,0,"42;")
#20018=@"loc,{#10000},9,5,9,7"
locations_default(#20018,#10000,9,5,9,7)
hasLocation(#20017,#20018)
stmt_containers(#20017,#20001)
#20019=*
exprs(#20019,3,#20017,0,"42")
hasLocation(#20019,#20011)
enclosing_stmt(#20019,#20017)
expr_containers(#20019,#20001)
literals("42","42",#20019)
#20009=*
lines(#20009,#20002," ","")
#20010=@"loc,{#10000},10,1,10,7"
locations_default(#20010,#10000,10,1,10,7)
hasLocation(#20009,#20010)
numlines(#20002,4,1,0)
#20011=*
tokeninfo(#20011,3,#20002,0,"42")
#20012=@"loc,{#10000},9,5,9,6"
locations_default(#20012,#10000,9,5,9,6)
hasLocation(#20011,#20012)
#20013=*
tokeninfo(#20013,8,#20002,1,";")
#20014=@"loc,{#10000},9,7,9,7"
locations_default(#20014,#10000,9,7,9,7)
hasLocation(#20013,#20014)
#20015=*
tokeninfo(#20015,0,#20002,2,"")
#20016=@"loc,{#10000},10,8,10,7"
locations_default(#20016,#10000,10,8,10,7)
hasLocation(#20015,#20016)
toplevels(#20002,1)
#20017=@"loc,{#10000},7,43,10,7"
locations_default(#20017,#10000,7,43,10,7)
hasLocation(#20002,#20017)
#20018=*
stmts(#20018,2,#20002,0,"42;")
#20019=@"loc,{#10000},9,5,9,7"
locations_default(#20019,#10000,9,5,9,7)
hasLocation(#20018,#20019)
stmt_containers(#20018,#20002)
#20020=*
entry_cfg_node(#20020,#20001)
hasLocation(#20020,#20003)
exprs(#20020,3,#20018,0,"42")
hasLocation(#20020,#20012)
enclosing_stmt(#20020,#20018)
expr_containers(#20020,#20002)
literals("42","42",#20020)
#20021=*
exit_cfg_node(#20021,#20001)
hasLocation(#20021,#20015)
successor(#20017,#20019)
successor(#20019,#20021)
successor(#20020,#20017)
entry_cfg_node(#20021,#20002)
hasLocation(#20021,#20004)
#20022=*
toplevel_parent_xml_node(#20001,#20022)
exit_cfg_node(#20022,#20002)
hasLocation(#20022,#20016)
successor(#20018,#20020)
successor(#20020,#20022)
successor(#20021,#20018)
toplevel_parent_xml_node(#20002,#20001)
#20023=*
xmlElements(#20023,"html",#10000,0,#10000)
#20024=@"loc,{#10000},2,1,12,7"
@@ -96,12 +96,12 @@ xmlElements(#20029,"body",#20023,1,#10000)
#20030=@"loc,{#10000},6,1,11,7"
locations_default(#20030,#10000,6,1,11,7)
xmllocations(#20029,#20030)
xmlElements(#20022,"script",#20029,0,#10000)
xmlElements(#20001,"script",#20029,0,#10000)
#20031=@"loc,{#10000},7,5,10,16"
locations_default(#20031,#10000,7,5,10,16)
xmllocations(#20022,#20031)
xmllocations(#20001,#20031)
#20032=*
xmlAttrs(#20032,#20022,"type","application/javascript",0,#10000)
xmlAttrs(#20032,#20001,"type","application/javascript",0,#10000)
#20033=@"loc,{#10000},7,13,7,41"
locations_default(#20033,#10000,7,13,7,41)
xmllocations(#20032,#20033)

View File

@@ -8,365 +8,365 @@ locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},2,31"
#20002=*
lines(#20002,#20001,"var hello;","")
#20003=@"loc,{#10000},2,31,2,40"
locations_default(#20003,#10000,2,31,2,40)
hasLocation(#20002,#20003)
numlines(#20001,1,1,0)
#20004=*
tokeninfo(#20004,7,#20001,0,"var")
#20005=@"loc,{#10000},2,31,2,33"
locations_default(#20005,#10000,2,31,2,33)
hasLocation(#20004,#20005)
#20006=*
tokeninfo(#20006,6,#20001,1,"hello")
#20007=@"loc,{#10000},2,35,2,39"
locations_default(#20007,#10000,2,35,2,39)
hasLocation(#20006,#20007)
#20008=*
tokeninfo(#20008,8,#20001,2,";")
#20009=@"loc,{#10000},2,40,2,40"
locations_default(#20009,#10000,2,40,2,40)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,0,#20001,3,"")
#20011=@"loc,{#10000},2,41,2,40"
locations_default(#20011,#10000,2,41,2,40)
hasLocation(#20010,#20011)
toplevels(#20001,1)
hasLocation(#20001,#20003)
#20012=@"var;{hello};{#20000}"
variables(#20012,"hello",#20000)
#20013=*
stmts(#20013,18,#20001,0,"var hello;")
hasLocation(#20013,#20003)
stmt_containers(#20013,#20001)
#20001=*
#20002=@"script;{#10000},2,31"
#20003=*
lines(#20003,#20002,"var hello;","")
#20004=@"loc,{#10000},2,31,2,40"
locations_default(#20004,#10000,2,31,2,40)
hasLocation(#20003,#20004)
numlines(#20002,1,1,0)
#20005=*
tokeninfo(#20005,7,#20002,0,"var")
#20006=@"loc,{#10000},2,31,2,33"
locations_default(#20006,#10000,2,31,2,33)
hasLocation(#20005,#20006)
#20007=*
tokeninfo(#20007,6,#20002,1,"hello")
#20008=@"loc,{#10000},2,35,2,39"
locations_default(#20008,#10000,2,35,2,39)
hasLocation(#20007,#20008)
#20009=*
tokeninfo(#20009,8,#20002,2,";")
#20010=@"loc,{#10000},2,40,2,40"
locations_default(#20010,#10000,2,40,2,40)
hasLocation(#20009,#20010)
#20011=*
tokeninfo(#20011,0,#20002,3,"")
#20012=@"loc,{#10000},2,41,2,40"
locations_default(#20012,#10000,2,41,2,40)
hasLocation(#20011,#20012)
toplevels(#20002,1)
hasLocation(#20002,#20004)
#20013=@"var;{hello};{#20000}"
variables(#20013,"hello",#20000)
#20014=*
exprs(#20014,64,#20013,0,"hello")
hasLocation(#20014,#20007)
enclosing_stmt(#20014,#20013)
expr_containers(#20014,#20001)
stmts(#20014,18,#20002,0,"var hello;")
hasLocation(#20014,#20004)
stmt_containers(#20014,#20002)
#20015=*
exprs(#20015,78,#20014,0,"hello")
hasLocation(#20015,#20007)
enclosing_stmt(#20015,#20013)
expr_containers(#20015,#20001)
literals("hello","hello",#20015)
decl(#20015,#20012)
exprs(#20015,64,#20014,0,"hello")
hasLocation(#20015,#20008)
enclosing_stmt(#20015,#20014)
expr_containers(#20015,#20002)
#20016=*
entry_cfg_node(#20016,#20001)
#20017=@"loc,{#10000},2,31,2,30"
locations_default(#20017,#10000,2,31,2,30)
hasLocation(#20016,#20017)
#20018=*
exit_cfg_node(#20018,#20001)
hasLocation(#20018,#20011)
successor(#20013,#20015)
successor(#20015,#20014)
successor(#20014,#20018)
successor(#20016,#20013)
exprs(#20016,78,#20015,0,"hello")
hasLocation(#20016,#20008)
enclosing_stmt(#20016,#20014)
expr_containers(#20016,#20002)
literals("hello","hello",#20016)
decl(#20016,#20013)
#20017=*
entry_cfg_node(#20017,#20002)
#20018=@"loc,{#10000},2,31,2,30"
locations_default(#20018,#10000,2,31,2,30)
hasLocation(#20017,#20018)
#20019=*
toplevel_parent_xml_node(#20001,#20019)
#20020=@"script;{#10000},3,29"
#20021=*
lines(#20021,#20020,"var world;","")
#20022=@"loc,{#10000},3,29,3,38"
locations_default(#20022,#10000,3,29,3,38)
hasLocation(#20021,#20022)
numlines(#20020,1,1,0)
#20023=*
tokeninfo(#20023,7,#20020,0,"var")
#20024=@"loc,{#10000},3,29,3,31"
locations_default(#20024,#10000,3,29,3,31)
hasLocation(#20023,#20024)
#20025=*
tokeninfo(#20025,6,#20020,1,"world")
#20026=@"loc,{#10000},3,33,3,37"
locations_default(#20026,#10000,3,33,3,37)
hasLocation(#20025,#20026)
#20027=*
tokeninfo(#20027,8,#20020,2,";")
#20028=@"loc,{#10000},3,38,3,38"
locations_default(#20028,#10000,3,38,3,38)
hasLocation(#20027,#20028)
#20029=*
tokeninfo(#20029,0,#20020,3,"")
#20030=@"loc,{#10000},3,39,3,38"
locations_default(#20030,#10000,3,39,3,38)
hasLocation(#20029,#20030)
toplevels(#20020,1)
hasLocation(#20020,#20022)
#20031=@"var;{world};{#20000}"
variables(#20031,"world",#20000)
#20032=*
stmts(#20032,18,#20020,0,"var world;")
hasLocation(#20032,#20022)
stmt_containers(#20032,#20020)
exit_cfg_node(#20019,#20002)
hasLocation(#20019,#20012)
successor(#20014,#20016)
successor(#20016,#20015)
successor(#20015,#20019)
successor(#20017,#20014)
toplevel_parent_xml_node(#20002,#20001)
#20020=*
#20021=@"script;{#10000},3,29"
#20022=*
lines(#20022,#20021,"var world;","")
#20023=@"loc,{#10000},3,29,3,38"
locations_default(#20023,#10000,3,29,3,38)
hasLocation(#20022,#20023)
numlines(#20021,1,1,0)
#20024=*
tokeninfo(#20024,7,#20021,0,"var")
#20025=@"loc,{#10000},3,29,3,31"
locations_default(#20025,#10000,3,29,3,31)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,6,#20021,1,"world")
#20027=@"loc,{#10000},3,33,3,37"
locations_default(#20027,#10000,3,33,3,37)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,8,#20021,2,";")
#20029=@"loc,{#10000},3,38,3,38"
locations_default(#20029,#10000,3,38,3,38)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,0,#20021,3,"")
#20031=@"loc,{#10000},3,39,3,38"
locations_default(#20031,#10000,3,39,3,38)
hasLocation(#20030,#20031)
toplevels(#20021,1)
hasLocation(#20021,#20023)
#20032=@"var;{world};{#20000}"
variables(#20032,"world",#20000)
#20033=*
exprs(#20033,64,#20032,0,"world")
hasLocation(#20033,#20026)
enclosing_stmt(#20033,#20032)
expr_containers(#20033,#20020)
stmts(#20033,18,#20021,0,"var world;")
hasLocation(#20033,#20023)
stmt_containers(#20033,#20021)
#20034=*
exprs(#20034,78,#20033,0,"world")
hasLocation(#20034,#20026)
enclosing_stmt(#20034,#20032)
expr_containers(#20034,#20020)
literals("world","world",#20034)
decl(#20034,#20031)
exprs(#20034,64,#20033,0,"world")
hasLocation(#20034,#20027)
enclosing_stmt(#20034,#20033)
expr_containers(#20034,#20021)
#20035=*
entry_cfg_node(#20035,#20020)
#20036=@"loc,{#10000},3,29,3,28"
locations_default(#20036,#10000,3,29,3,28)
hasLocation(#20035,#20036)
#20037=*
exit_cfg_node(#20037,#20020)
hasLocation(#20037,#20030)
successor(#20032,#20034)
successor(#20034,#20033)
successor(#20033,#20037)
successor(#20035,#20032)
exprs(#20035,78,#20034,0,"world")
hasLocation(#20035,#20027)
enclosing_stmt(#20035,#20033)
expr_containers(#20035,#20021)
literals("world","world",#20035)
decl(#20035,#20032)
#20036=*
entry_cfg_node(#20036,#20021)
#20037=@"loc,{#10000},3,29,3,28"
locations_default(#20037,#10000,3,29,3,28)
hasLocation(#20036,#20037)
#20038=*
toplevel_parent_xml_node(#20020,#20038)
#20039=@"script;{#10000},4,75"
#20040=*
lines(#20040,#20039,"","
exit_cfg_node(#20038,#20021)
hasLocation(#20038,#20031)
successor(#20033,#20035)
successor(#20035,#20034)
successor(#20034,#20038)
successor(#20036,#20033)
toplevel_parent_xml_node(#20021,#20020)
#20039=*
#20040=@"script;{#10000},4,75"
#20041=*
lines(#20041,#20040,"","
")
#20041=@"loc,{#10000},4,75,4,74"
locations_default(#20041,#10000,4,75,4,74)
hasLocation(#20040,#20041)
#20042=*
lines(#20042,#20039," var inAModule;","
#20042=@"loc,{#10000},4,75,4,74"
locations_default(#20042,#10000,4,75,4,74)
hasLocation(#20041,#20042)
#20043=*
lines(#20043,#20040," var inAModule;","
")
#20043=@"loc,{#10000},5,1,5,20"
locations_default(#20043,#10000,5,1,5,20)
hasLocation(#20042,#20043)
#20044=@"loc,{#10000},5,1,5,20"
locations_default(#20044,#10000,5,1,5,20)
hasLocation(#20043,#20044)
indentation(#10000,5," ",6)
#20044=*
lines(#20044,#20039," ","")
#20045=@"loc,{#10000},6,1,6,4"
locations_default(#20045,#10000,6,1,6,4)
hasLocation(#20044,#20045)
numlines(#20039,3,1,0)
#20046=*
tokeninfo(#20046,7,#20039,0,"var")
#20047=@"loc,{#10000},5,7,5,9"
locations_default(#20047,#10000,5,7,5,9)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,6,#20039,1,"inAModule")
#20049=@"loc,{#10000},5,11,5,19"
locations_default(#20049,#10000,5,11,5,19)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,8,#20039,2,";")
#20051=@"loc,{#10000},5,20,5,20"
locations_default(#20051,#10000,5,20,5,20)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,0,#20039,3,"")
#20053=@"loc,{#10000},6,5,6,4"
locations_default(#20053,#10000,6,5,6,4)
hasLocation(#20052,#20053)
toplevels(#20039,1)
#20054=@"loc,{#10000},4,75,6,4"
locations_default(#20054,#10000,4,75,6,4)
hasLocation(#20039,#20054)
#20055=@"module;{#10000},4,75"
scopes(#20055,3)
scopenodes(#20039,#20055)
scopenesting(#20055,#20000)
is_module(#20039)
is_es2015_module(#20039)
#20056=@"var;{inAModule};{#20055}"
variables(#20056,"inAModule",#20055)
#20057=*
stmts(#20057,18,#20039,0,"var inAModule;")
#20058=@"loc,{#10000},5,7,5,20"
locations_default(#20058,#10000,5,7,5,20)
hasLocation(#20057,#20058)
stmt_containers(#20057,#20039)
#20059=*
exprs(#20059,64,#20057,0,"inAModule")
hasLocation(#20059,#20049)
enclosing_stmt(#20059,#20057)
expr_containers(#20059,#20039)
#20045=*
lines(#20045,#20040," ","")
#20046=@"loc,{#10000},6,1,6,4"
locations_default(#20046,#10000,6,1,6,4)
hasLocation(#20045,#20046)
numlines(#20040,3,1,0)
#20047=*
tokeninfo(#20047,7,#20040,0,"var")
#20048=@"loc,{#10000},5,7,5,9"
locations_default(#20048,#10000,5,7,5,9)
hasLocation(#20047,#20048)
#20049=*
tokeninfo(#20049,6,#20040,1,"inAModule")
#20050=@"loc,{#10000},5,11,5,19"
locations_default(#20050,#10000,5,11,5,19)
hasLocation(#20049,#20050)
#20051=*
tokeninfo(#20051,8,#20040,2,";")
#20052=@"loc,{#10000},5,20,5,20"
locations_default(#20052,#10000,5,20,5,20)
hasLocation(#20051,#20052)
#20053=*
tokeninfo(#20053,0,#20040,3,"")
#20054=@"loc,{#10000},6,5,6,4"
locations_default(#20054,#10000,6,5,6,4)
hasLocation(#20053,#20054)
toplevels(#20040,1)
#20055=@"loc,{#10000},4,75,6,4"
locations_default(#20055,#10000,4,75,6,4)
hasLocation(#20040,#20055)
#20056=@"module;{#10000},4,75"
scopes(#20056,3)
scopenodes(#20040,#20056)
scopenesting(#20056,#20000)
is_module(#20040)
is_es2015_module(#20040)
#20057=@"var;{inAModule};{#20056}"
variables(#20057,"inAModule",#20056)
#20058=*
stmts(#20058,18,#20040,0,"var inAModule;")
#20059=@"loc,{#10000},5,7,5,20"
locations_default(#20059,#10000,5,7,5,20)
hasLocation(#20058,#20059)
stmt_containers(#20058,#20040)
#20060=*
exprs(#20060,78,#20059,0,"inAModule")
hasLocation(#20060,#20049)
enclosing_stmt(#20060,#20057)
expr_containers(#20060,#20039)
literals("inAModule","inAModule",#20060)
decl(#20060,#20056)
exprs(#20060,64,#20058,0,"inAModule")
hasLocation(#20060,#20050)
enclosing_stmt(#20060,#20058)
expr_containers(#20060,#20040)
#20061=*
entry_cfg_node(#20061,#20039)
hasLocation(#20061,#20041)
exprs(#20061,78,#20060,0,"inAModule")
hasLocation(#20061,#20050)
enclosing_stmt(#20061,#20058)
expr_containers(#20061,#20040)
literals("inAModule","inAModule",#20061)
decl(#20061,#20057)
#20062=*
exit_cfg_node(#20062,#20039)
hasLocation(#20062,#20053)
successor(#20057,#20060)
successor(#20060,#20059)
successor(#20059,#20062)
successor(#20061,#20057)
entry_cfg_node(#20062,#20040)
hasLocation(#20062,#20042)
#20063=*
toplevel_parent_xml_node(#20039,#20063)
#20064=@"script;{#10000},7,75"
#20065=*
lines(#20065,#20064,"","
exit_cfg_node(#20063,#20040)
hasLocation(#20063,#20054)
successor(#20058,#20061)
successor(#20061,#20060)
successor(#20060,#20063)
successor(#20062,#20058)
toplevel_parent_xml_node(#20040,#20039)
#20064=*
#20065=@"script;{#10000},7,75"
#20066=*
lines(#20066,#20065,"","
")
#20066=@"loc,{#10000},7,75,7,74"
locations_default(#20066,#10000,7,75,7,74)
hasLocation(#20065,#20066)
#20067=*
lines(#20067,#20064," import f from ""f""","
#20067=@"loc,{#10000},7,75,7,74"
locations_default(#20067,#10000,7,75,7,74)
hasLocation(#20066,#20067)
#20068=*
lines(#20068,#20065," import f from ""f""","
")
#20068=@"loc,{#10000},8,1,8,23"
locations_default(#20068,#10000,8,1,8,23)
hasLocation(#20067,#20068)
#20069=@"loc,{#10000},8,1,8,23"
locations_default(#20069,#10000,8,1,8,23)
hasLocation(#20068,#20069)
indentation(#10000,8," ",6)
#20069=*
lines(#20069,#20064," ","")
#20070=@"loc,{#10000},9,1,9,4"
locations_default(#20070,#10000,9,1,9,4)
hasLocation(#20069,#20070)
numlines(#20064,3,1,0)
#20071=*
tokeninfo(#20071,7,#20064,0,"import")
#20072=@"loc,{#10000},8,7,8,12"
locations_default(#20072,#10000,8,7,8,12)
hasLocation(#20071,#20072)
#20073=*
tokeninfo(#20073,6,#20064,1,"f")
#20074=@"loc,{#10000},8,14,8,14"
locations_default(#20074,#10000,8,14,8,14)
hasLocation(#20073,#20074)
#20075=*
tokeninfo(#20075,6,#20064,2,"from")
#20076=@"loc,{#10000},8,16,8,19"
locations_default(#20076,#10000,8,16,8,19)
hasLocation(#20075,#20076)
#20077=*
tokeninfo(#20077,4,#20064,3,"""f""")
#20078=@"loc,{#10000},8,21,8,23"
locations_default(#20078,#10000,8,21,8,23)
hasLocation(#20077,#20078)
#20079=*
tokeninfo(#20079,0,#20064,4,"")
#20080=@"loc,{#10000},9,5,9,4"
locations_default(#20080,#10000,9,5,9,4)
hasLocation(#20079,#20080)
toplevels(#20064,1)
#20081=@"loc,{#10000},7,75,9,4"
locations_default(#20081,#10000,7,75,9,4)
hasLocation(#20064,#20081)
#20082=@"module;{#10000},7,75"
scopes(#20082,3)
scopenodes(#20064,#20082)
scopenesting(#20082,#20000)
is_module(#20064)
is_es2015_module(#20064)
#20083=@"var;{f};{#20082}"
variables(#20083,"f",#20082)
#20084=@"local_type_name;{f};{#20082}"
local_type_names(#20084,"f",#20082)
#20085=@"local_namespace_name;{f};{#20082}"
local_namespace_names(#20085,"f",#20082)
variables(#20083,"f",#20082)
local_type_names(#20084,"f",#20082)
local_namespace_names(#20085,"f",#20082)
#20086=*
stmts(#20086,27,#20064,0,"import f from ""f""")
#20087=@"loc,{#10000},8,7,8,23"
locations_default(#20087,#10000,8,7,8,23)
hasLocation(#20086,#20087)
stmt_containers(#20086,#20064)
#20088=*
exprs(#20088,4,#20086,-1,"""f""")
hasLocation(#20088,#20078)
enclosing_stmt(#20088,#20086)
expr_containers(#20088,#20064)
literals("f","""f""",#20088)
#20070=*
lines(#20070,#20065," ","")
#20071=@"loc,{#10000},9,1,9,4"
locations_default(#20071,#10000,9,1,9,4)
hasLocation(#20070,#20071)
numlines(#20065,3,1,0)
#20072=*
tokeninfo(#20072,7,#20065,0,"import")
#20073=@"loc,{#10000},8,7,8,12"
locations_default(#20073,#10000,8,7,8,12)
hasLocation(#20072,#20073)
#20074=*
tokeninfo(#20074,6,#20065,1,"f")
#20075=@"loc,{#10000},8,14,8,14"
locations_default(#20075,#10000,8,14,8,14)
hasLocation(#20074,#20075)
#20076=*
tokeninfo(#20076,6,#20065,2,"from")
#20077=@"loc,{#10000},8,16,8,19"
locations_default(#20077,#10000,8,16,8,19)
hasLocation(#20076,#20077)
#20078=*
tokeninfo(#20078,4,#20065,3,"""f""")
#20079=@"loc,{#10000},8,21,8,23"
locations_default(#20079,#10000,8,21,8,23)
hasLocation(#20078,#20079)
#20080=*
tokeninfo(#20080,0,#20065,4,"")
#20081=@"loc,{#10000},9,5,9,4"
locations_default(#20081,#10000,9,5,9,4)
hasLocation(#20080,#20081)
toplevels(#20065,1)
#20082=@"loc,{#10000},7,75,9,4"
locations_default(#20082,#10000,7,75,9,4)
hasLocation(#20065,#20082)
#20083=@"module;{#10000},7,75"
scopes(#20083,3)
scopenodes(#20065,#20083)
scopenesting(#20083,#20000)
is_module(#20065)
is_es2015_module(#20065)
#20084=@"var;{f};{#20083}"
variables(#20084,"f",#20083)
#20085=@"local_type_name;{f};{#20083}"
local_type_names(#20085,"f",#20083)
#20086=@"local_namespace_name;{f};{#20083}"
local_namespace_names(#20086,"f",#20083)
variables(#20084,"f",#20083)
local_type_names(#20085,"f",#20083)
local_namespace_names(#20086,"f",#20083)
#20087=*
stmts(#20087,27,#20065,0,"import f from ""f""")
#20088=@"loc,{#10000},8,7,8,23"
locations_default(#20088,#10000,8,7,8,23)
hasLocation(#20087,#20088)
stmt_containers(#20087,#20065)
#20089=*
regexpterm(#20089,14,#20088,0,"f")
#20090=@"loc,{#10000},8,22,8,22"
locations_default(#20090,#10000,8,22,8,22)
hasLocation(#20089,#20090)
regexp_const_value(#20089,"f")
#20091=*
exprs(#20091,84,#20086,0,"f")
hasLocation(#20091,#20074)
enclosing_stmt(#20091,#20086)
expr_containers(#20091,#20064)
exprs(#20089,4,#20087,-1,"""f""")
hasLocation(#20089,#20079)
enclosing_stmt(#20089,#20087)
expr_containers(#20089,#20065)
literals("f","""f""",#20089)
#20090=*
regexpterm(#20090,14,#20089,0,"f")
#20091=@"loc,{#10000},8,22,8,22"
locations_default(#20091,#10000,8,22,8,22)
hasLocation(#20090,#20091)
regexp_const_value(#20090,"f")
#20092=*
exprs(#20092,78,#20091,1,"f")
hasLocation(#20092,#20074)
enclosing_stmt(#20092,#20086)
expr_containers(#20092,#20064)
literals("f","f",#20092)
decl(#20092,#20083)
typedecl(#20092,#20084)
namespacedecl(#20092,#20085)
exprs(#20092,84,#20087,0,"f")
hasLocation(#20092,#20075)
enclosing_stmt(#20092,#20087)
expr_containers(#20092,#20065)
#20093=*
entry_cfg_node(#20093,#20064)
hasLocation(#20093,#20066)
exprs(#20093,78,#20092,1,"f")
hasLocation(#20093,#20075)
enclosing_stmt(#20093,#20087)
expr_containers(#20093,#20065)
literals("f","f",#20093)
decl(#20093,#20084)
typedecl(#20093,#20085)
namespacedecl(#20093,#20086)
#20094=*
exit_cfg_node(#20094,#20064)
hasLocation(#20094,#20080)
successor(#20086,#20094)
successor(#20091,#20086)
successor(#20093,#20091)
entry_cfg_node(#20094,#20065)
hasLocation(#20094,#20067)
#20095=*
toplevel_parent_xml_node(#20064,#20095)
exit_cfg_node(#20095,#20065)
hasLocation(#20095,#20081)
successor(#20087,#20095)
successor(#20092,#20087)
successor(#20094,#20092)
toplevel_parent_xml_node(#20065,#20064)
#20096=*
xmlElements(#20096,"html",#10000,0,#10000)
#20097=@"loc,{#10000},1,1,10,7"
locations_default(#20097,#10000,1,1,10,7)
xmllocations(#20096,#20097)
xmlElements(#20095,"script",#20096,3,#10000)
xmlElements(#20064,"script",#20096,3,#10000)
#20098=@"loc,{#10000},7,5,9,13"
locations_default(#20098,#10000,7,5,9,13)
xmllocations(#20095,#20098)
xmllocations(#20064,#20098)
#20099=*
xmlAttrs(#20099,#20095,"type","text/babel",0,#10000)
xmlAttrs(#20099,#20064,"type","text/babel",0,#10000)
#20100=@"loc,{#10000},7,13,7,29"
locations_default(#20100,#10000,7,13,7,29)
xmllocations(#20099,#20100)
#20101=*
xmlAttrs(#20101,#20095,"data-plugins","transform-es2015-modules-umd",1,#10000)
xmlAttrs(#20101,#20064,"data-plugins","transform-es2015-modules-umd",1,#10000)
#20102=@"loc,{#10000},7,31,7,73"
locations_default(#20102,#10000,7,31,7,73)
xmllocations(#20101,#20102)
xmlElements(#20063,"script",#20096,2,#10000)
xmlElements(#20039,"script",#20096,2,#10000)
#20103=@"loc,{#10000},4,5,6,13"
locations_default(#20103,#10000,4,5,6,13)
xmllocations(#20063,#20103)
xmllocations(#20039,#20103)
#20104=*
xmlAttrs(#20104,#20063,"type","text/babel",0,#10000)
xmlAttrs(#20104,#20039,"type","text/babel",0,#10000)
#20105=@"loc,{#10000},4,13,4,29"
locations_default(#20105,#10000,4,13,4,29)
xmllocations(#20104,#20105)
#20106=*
xmlAttrs(#20106,#20063,"data-plugins","transform-es2015-modules-umd",1,#10000)
xmlAttrs(#20106,#20039,"data-plugins","transform-es2015-modules-umd",1,#10000)
#20107=@"loc,{#10000},4,31,4,73"
locations_default(#20107,#10000,4,31,4,73)
xmllocations(#20106,#20107)
xmlElements(#20038,"script",#20096,1,#10000)
xmlElements(#20020,"script",#20096,1,#10000)
#20108=@"loc,{#10000},3,5,3,47"
locations_default(#20108,#10000,3,5,3,47)
xmllocations(#20038,#20108)
xmllocations(#20020,#20108)
#20109=*
xmlAttrs(#20109,#20038,"type","text/jsx",0,#10000)
xmlAttrs(#20109,#20020,"type","text/jsx",0,#10000)
#20110=@"loc,{#10000},3,13,3,27"
locations_default(#20110,#10000,3,13,3,27)
xmllocations(#20109,#20110)
xmlElements(#20019,"script",#20096,0,#10000)
xmlElements(#20001,"script",#20096,0,#10000)
#20111=@"loc,{#10000},2,5,2,49"
locations_default(#20111,#10000,2,5,2,49)
xmllocations(#20019,#20111)
xmllocations(#20001,#20111)
#20112=*
xmlAttrs(#20112,#20019,"type","text/babel",0,#10000)
xmlAttrs(#20112,#20001,"type","text/babel",0,#10000)
#20113=@"loc,{#10000},2,13,2,29"
locations_default(#20113,#10000,2,13,2,29)
xmllocations(#20112,#20113)

View File

@@ -329,216 +329,216 @@ literals("
<foo [baz]=""expr?.bar"" />
",#20099)
scopes(#20000,0)
#20100=@"script;{#10000},5,15"
#20101=*
lines(#20101,#20100,"expr + expr","")
#20102=@"loc,{#10000},5,15,5,25"
locations_default(#20102,#10000,5,15,5,25)
hasLocation(#20101,#20102)
numlines(#20100,1,1,0)
#20103=*
tokeninfo(#20103,6,#20100,0,"expr")
#20104=@"loc,{#10000},5,15,5,18"
locations_default(#20104,#10000,5,15,5,18)
hasLocation(#20103,#20104)
#20105=*
tokeninfo(#20105,8,#20100,1,"+")
#20106=@"loc,{#10000},5,20,5,20"
locations_default(#20106,#10000,5,20,5,20)
hasLocation(#20105,#20106)
#20107=*
tokeninfo(#20107,6,#20100,2,"expr")
#20108=@"loc,{#10000},5,22,5,25"
locations_default(#20108,#10000,5,22,5,25)
hasLocation(#20107,#20108)
#20109=*
tokeninfo(#20109,0,#20100,3,"")
#20110=@"loc,{#10000},5,26,5,25"
locations_default(#20110,#10000,5,26,5,25)
hasLocation(#20109,#20110)
toplevels(#20100,4)
hasLocation(#20100,#20102)
#20111=@"module;{#10000},5,15"
scopes(#20111,3)
scopenodes(#20100,#20111)
scopenesting(#20111,#20000)
is_module(#20100)
#20112=*
stmts(#20112,2,#20100,0,"expr + expr")
hasLocation(#20112,#20102)
stmt_containers(#20112,#20100)
#20100=*
#20101=@"script;{#10000},5,15"
#20102=*
lines(#20102,#20101,"expr + expr","")
#20103=@"loc,{#10000},5,15,5,25"
locations_default(#20103,#10000,5,15,5,25)
hasLocation(#20102,#20103)
numlines(#20101,1,1,0)
#20104=*
tokeninfo(#20104,6,#20101,0,"expr")
#20105=@"loc,{#10000},5,15,5,18"
locations_default(#20105,#10000,5,15,5,18)
hasLocation(#20104,#20105)
#20106=*
tokeninfo(#20106,8,#20101,1,"+")
#20107=@"loc,{#10000},5,20,5,20"
locations_default(#20107,#10000,5,20,5,20)
hasLocation(#20106,#20107)
#20108=*
tokeninfo(#20108,6,#20101,2,"expr")
#20109=@"loc,{#10000},5,22,5,25"
locations_default(#20109,#10000,5,22,5,25)
hasLocation(#20108,#20109)
#20110=*
tokeninfo(#20110,0,#20101,3,"")
#20111=@"loc,{#10000},5,26,5,25"
locations_default(#20111,#10000,5,26,5,25)
hasLocation(#20110,#20111)
toplevels(#20101,4)
hasLocation(#20101,#20103)
#20112=@"module;{#10000},5,15"
scopes(#20112,3)
scopenodes(#20101,#20112)
scopenesting(#20112,#20000)
is_module(#20101)
#20113=*
exprs(#20113,34,#20112,0,"expr + expr")
hasLocation(#20113,#20102)
enclosing_stmt(#20113,#20112)
expr_containers(#20113,#20100)
stmts(#20113,2,#20101,0,"expr + expr")
hasLocation(#20113,#20103)
stmt_containers(#20113,#20101)
#20114=*
exprs(#20114,79,#20113,0,"expr")
hasLocation(#20114,#20104)
enclosing_stmt(#20114,#20112)
expr_containers(#20114,#20100)
literals("expr","expr",#20114)
#20115=@"var;{expr};{#20111}"
variables(#20115,"expr",#20111)
bind(#20114,#20115)
#20116=*
exprs(#20116,79,#20113,1,"expr")
hasLocation(#20116,#20108)
enclosing_stmt(#20116,#20112)
expr_containers(#20116,#20100)
literals("expr","expr",#20116)
bind(#20116,#20115)
exprs(#20114,34,#20113,0,"expr + expr")
hasLocation(#20114,#20103)
enclosing_stmt(#20114,#20113)
expr_containers(#20114,#20101)
#20115=*
exprs(#20115,79,#20114,0,"expr")
hasLocation(#20115,#20105)
enclosing_stmt(#20115,#20113)
expr_containers(#20115,#20101)
literals("expr","expr",#20115)
#20116=@"var;{expr};{#20112}"
variables(#20116,"expr",#20112)
bind(#20115,#20116)
#20117=*
entry_cfg_node(#20117,#20100)
#20118=@"loc,{#10000},5,15,5,14"
locations_default(#20118,#10000,5,15,5,14)
hasLocation(#20117,#20118)
#20119=*
exit_cfg_node(#20119,#20100)
hasLocation(#20119,#20110)
successor(#20112,#20114)
successor(#20116,#20113)
successor(#20114,#20116)
successor(#20113,#20119)
successor(#20117,#20112)
exprs(#20117,79,#20114,1,"expr")
hasLocation(#20117,#20109)
enclosing_stmt(#20117,#20113)
expr_containers(#20117,#20101)
literals("expr","expr",#20117)
bind(#20117,#20116)
#20118=*
entry_cfg_node(#20118,#20101)
#20119=@"loc,{#10000},5,15,5,14"
locations_default(#20119,#10000,5,15,5,14)
hasLocation(#20118,#20119)
#20120=*
toplevel_parent_xml_node(#20100,#20120)
#20121=@"script;{#10000},6,14"
#20122=*
lines(#20122,#20121,"expr!","")
#20123=@"loc,{#10000},6,14,6,18"
locations_default(#20123,#10000,6,14,6,18)
hasLocation(#20122,#20123)
numlines(#20121,1,1,0)
#20124=*
tokeninfo(#20124,6,#20121,0,"expr")
#20125=@"loc,{#10000},6,14,6,17"
locations_default(#20125,#10000,6,14,6,17)
hasLocation(#20124,#20125)
#20126=*
tokeninfo(#20126,8,#20121,1,"!")
#20127=@"loc,{#10000},6,18,6,18"
locations_default(#20127,#10000,6,18,6,18)
hasLocation(#20126,#20127)
#20128=*
tokeninfo(#20128,0,#20121,2,"")
#20129=@"loc,{#10000},6,19,6,18"
locations_default(#20129,#10000,6,19,6,18)
hasLocation(#20128,#20129)
toplevels(#20121,4)
hasLocation(#20121,#20123)
#20130=@"module;{#10000},6,14"
scopes(#20130,3)
scopenodes(#20121,#20130)
scopenesting(#20130,#20000)
is_module(#20121)
#20131=*
stmts(#20131,2,#20121,0,"expr!")
hasLocation(#20131,#20123)
stmt_containers(#20131,#20121)
exit_cfg_node(#20120,#20101)
hasLocation(#20120,#20111)
successor(#20113,#20115)
successor(#20117,#20114)
successor(#20115,#20117)
successor(#20114,#20120)
successor(#20118,#20113)
toplevel_parent_xml_node(#20101,#20100)
#20121=*
#20122=@"script;{#10000},6,14"
#20123=*
lines(#20123,#20122,"expr!","")
#20124=@"loc,{#10000},6,14,6,18"
locations_default(#20124,#10000,6,14,6,18)
hasLocation(#20123,#20124)
numlines(#20122,1,1,0)
#20125=*
tokeninfo(#20125,6,#20122,0,"expr")
#20126=@"loc,{#10000},6,14,6,17"
locations_default(#20126,#10000,6,14,6,17)
hasLocation(#20125,#20126)
#20127=*
tokeninfo(#20127,8,#20122,1,"!")
#20128=@"loc,{#10000},6,18,6,18"
locations_default(#20128,#10000,6,18,6,18)
hasLocation(#20127,#20128)
#20129=*
tokeninfo(#20129,0,#20122,2,"")
#20130=@"loc,{#10000},6,19,6,18"
locations_default(#20130,#10000,6,19,6,18)
hasLocation(#20129,#20130)
toplevels(#20122,4)
hasLocation(#20122,#20124)
#20131=@"module;{#10000},6,14"
scopes(#20131,3)
scopenodes(#20122,#20131)
scopenesting(#20131,#20000)
is_module(#20122)
#20132=*
exprs(#20132,105,#20131,0,"expr!")
hasLocation(#20132,#20123)
enclosing_stmt(#20132,#20131)
expr_containers(#20132,#20121)
stmts(#20132,2,#20122,0,"expr!")
hasLocation(#20132,#20124)
stmt_containers(#20132,#20122)
#20133=*
exprs(#20133,79,#20132,0,"expr")
hasLocation(#20133,#20125)
enclosing_stmt(#20133,#20131)
expr_containers(#20133,#20121)
literals("expr","expr",#20133)
#20134=@"var;{expr};{#20130}"
variables(#20134,"expr",#20130)
bind(#20133,#20134)
#20135=*
entry_cfg_node(#20135,#20121)
#20136=@"loc,{#10000},6,14,6,13"
locations_default(#20136,#10000,6,14,6,13)
hasLocation(#20135,#20136)
#20137=*
exit_cfg_node(#20137,#20121)
hasLocation(#20137,#20129)
successor(#20131,#20133)
successor(#20133,#20132)
successor(#20132,#20137)
successor(#20135,#20131)
exprs(#20133,105,#20132,0,"expr!")
hasLocation(#20133,#20124)
enclosing_stmt(#20133,#20132)
expr_containers(#20133,#20122)
#20134=*
exprs(#20134,79,#20133,0,"expr")
hasLocation(#20134,#20126)
enclosing_stmt(#20134,#20132)
expr_containers(#20134,#20122)
literals("expr","expr",#20134)
#20135=@"var;{expr};{#20131}"
variables(#20135,"expr",#20131)
bind(#20134,#20135)
#20136=*
entry_cfg_node(#20136,#20122)
#20137=@"loc,{#10000},6,14,6,13"
locations_default(#20137,#10000,6,14,6,13)
hasLocation(#20136,#20137)
#20138=*
toplevel_parent_xml_node(#20121,#20138)
#20139=@"script;{#10000},7,14"
#20140=*
lines(#20140,#20139,"expr?.bar","")
#20141=@"loc,{#10000},7,14,7,22"
locations_default(#20141,#10000,7,14,7,22)
hasLocation(#20140,#20141)
numlines(#20139,1,1,0)
#20142=*
tokeninfo(#20142,6,#20139,0,"expr")
#20143=@"loc,{#10000},7,14,7,17"
locations_default(#20143,#10000,7,14,7,17)
hasLocation(#20142,#20143)
#20144=*
tokeninfo(#20144,8,#20139,1,"?.")
#20145=@"loc,{#10000},7,18,7,19"
locations_default(#20145,#10000,7,18,7,19)
hasLocation(#20144,#20145)
#20146=*
tokeninfo(#20146,6,#20139,2,"bar")
#20147=@"loc,{#10000},7,20,7,22"
locations_default(#20147,#10000,7,20,7,22)
hasLocation(#20146,#20147)
#20148=*
tokeninfo(#20148,0,#20139,3,"")
#20149=@"loc,{#10000},7,23,7,22"
locations_default(#20149,#10000,7,23,7,22)
hasLocation(#20148,#20149)
toplevels(#20139,4)
hasLocation(#20139,#20141)
#20150=@"module;{#10000},7,14"
scopes(#20150,3)
scopenodes(#20139,#20150)
scopenesting(#20150,#20000)
is_module(#20139)
#20151=*
stmts(#20151,2,#20139,0,"expr?.bar")
hasLocation(#20151,#20141)
stmt_containers(#20151,#20139)
exit_cfg_node(#20138,#20122)
hasLocation(#20138,#20130)
successor(#20132,#20134)
successor(#20134,#20133)
successor(#20133,#20138)
successor(#20136,#20132)
toplevel_parent_xml_node(#20122,#20121)
#20139=*
#20140=@"script;{#10000},7,14"
#20141=*
lines(#20141,#20140,"expr?.bar","")
#20142=@"loc,{#10000},7,14,7,22"
locations_default(#20142,#10000,7,14,7,22)
hasLocation(#20141,#20142)
numlines(#20140,1,1,0)
#20143=*
tokeninfo(#20143,6,#20140,0,"expr")
#20144=@"loc,{#10000},7,14,7,17"
locations_default(#20144,#10000,7,14,7,17)
hasLocation(#20143,#20144)
#20145=*
tokeninfo(#20145,8,#20140,1,"?.")
#20146=@"loc,{#10000},7,18,7,19"
locations_default(#20146,#10000,7,18,7,19)
hasLocation(#20145,#20146)
#20147=*
tokeninfo(#20147,6,#20140,2,"bar")
#20148=@"loc,{#10000},7,20,7,22"
locations_default(#20148,#10000,7,20,7,22)
hasLocation(#20147,#20148)
#20149=*
tokeninfo(#20149,0,#20140,3,"")
#20150=@"loc,{#10000},7,23,7,22"
locations_default(#20150,#10000,7,23,7,22)
hasLocation(#20149,#20150)
toplevels(#20140,4)
hasLocation(#20140,#20142)
#20151=@"module;{#10000},7,14"
scopes(#20151,3)
scopenodes(#20140,#20151)
scopenesting(#20151,#20000)
is_module(#20140)
#20152=*
exprs(#20152,14,#20151,0,"expr?.bar")
hasLocation(#20152,#20141)
enclosing_stmt(#20152,#20151)
expr_containers(#20152,#20139)
stmts(#20152,2,#20140,0,"expr?.bar")
hasLocation(#20152,#20142)
stmt_containers(#20152,#20140)
#20153=*
exprs(#20153,79,#20152,0,"expr")
hasLocation(#20153,#20143)
enclosing_stmt(#20153,#20151)
expr_containers(#20153,#20139)
literals("expr","expr",#20153)
#20154=@"var;{expr};{#20150}"
variables(#20154,"expr",#20150)
bind(#20153,#20154)
#20155=*
exprs(#20155,0,#20152,1,"bar")
hasLocation(#20155,#20147)
enclosing_stmt(#20155,#20151)
expr_containers(#20155,#20139)
literals("bar","bar",#20155)
isOptionalChaining(#20152)
exprs(#20153,14,#20152,0,"expr?.bar")
hasLocation(#20153,#20142)
enclosing_stmt(#20153,#20152)
expr_containers(#20153,#20140)
#20154=*
exprs(#20154,79,#20153,0,"expr")
hasLocation(#20154,#20144)
enclosing_stmt(#20154,#20152)
expr_containers(#20154,#20140)
literals("expr","expr",#20154)
#20155=@"var;{expr};{#20151}"
variables(#20155,"expr",#20151)
bind(#20154,#20155)
#20156=*
entry_cfg_node(#20156,#20139)
#20157=@"loc,{#10000},7,14,7,13"
locations_default(#20157,#10000,7,14,7,13)
hasLocation(#20156,#20157)
#20158=*
exit_cfg_node(#20158,#20139)
hasLocation(#20158,#20149)
successor(#20151,#20153)
successor(#20155,#20152)
successor(#20153,#20155)
successor(#20152,#20158)
successor(#20153,#20158)
successor(#20156,#20151)
exprs(#20156,0,#20153,1,"bar")
hasLocation(#20156,#20148)
enclosing_stmt(#20156,#20152)
expr_containers(#20156,#20140)
literals("bar","bar",#20156)
isOptionalChaining(#20153)
#20157=*
entry_cfg_node(#20157,#20140)
#20158=@"loc,{#10000},7,14,7,13"
locations_default(#20158,#10000,7,14,7,13)
hasLocation(#20157,#20158)
#20159=*
toplevel_parent_xml_node(#20139,#20159)
exit_cfg_node(#20159,#20140)
hasLocation(#20159,#20150)
successor(#20152,#20154)
successor(#20156,#20153)
successor(#20154,#20156)
successor(#20153,#20159)
successor(#20154,#20159)
successor(#20157,#20152)
toplevel_parent_xml_node(#20140,#20139)
#20160=*
xmlChars(#20160,"
",#10000,0,0,#10000)
@@ -568,28 +568,28 @@ xmlElements(#20168,"foo",#10000,5,#10000)
#20169=@"loc,{#10000},7,2,7,26"
locations_default(#20169,#10000,7,2,7,26)
xmllocations(#20168,#20169)
xmlAttrs(#20159,#20168,"[baz]","expr?.bar",0,#10000)
xmlAttrs(#20139,#20168,"[baz]","expr?.bar",0,#10000)
#20170=@"loc,{#10000},7,7,7,23"
locations_default(#20170,#10000,7,7,7,23)
xmllocations(#20159,#20170)
xmllocations(#20139,#20170)
#20171=*
xmlElements(#20171,"foo",#10000,3,#10000)
#20172=@"loc,{#10000},6,2,6,22"
locations_default(#20172,#10000,6,2,6,22)
xmllocations(#20171,#20172)
xmlAttrs(#20138,#20171,"[baz]","expr!",0,#10000)
xmlAttrs(#20121,#20171,"[baz]","expr!",0,#10000)
#20173=@"loc,{#10000},6,7,6,19"
locations_default(#20173,#10000,6,7,6,19)
xmllocations(#20138,#20173)
xmllocations(#20121,#20173)
#20174=*
xmlElements(#20174,"foo",#10000,1,#10000)
#20175=@"loc,{#10000},5,2,5,28"
locations_default(#20175,#10000,5,2,5,28)
xmllocations(#20174,#20175)
xmlAttrs(#20120,#20174,"[prop]","expr + expr",0,#10000)
xmlAttrs(#20100,#20174,"[prop]","expr + expr",0,#10000)
#20176=@"loc,{#10000},5,7,5,26"
locations_default(#20176,#10000,5,7,5,26)
xmllocations(#20120,#20176)
xmllocations(#20100,#20176)
xml_element_parent_expression(#20174,#20097,0)
xml_element_parent_expression(#20171,#20097,1)
xml_element_parent_expression(#20168,#20097,2)

View File

@@ -8,86 +8,86 @@ locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},6,13"
#20002=*
lines(#20002,#20001,"var x = 42;","")
#20003=@"loc,{#10000},6,13,6,23"
locations_default(#20003,#10000,6,13,6,23)
hasLocation(#20002,#20003)
numlines(#20001,1,1,0)
#20004=*
tokeninfo(#20004,7,#20001,0,"var")
#20005=@"loc,{#10000},6,13,6,15"
locations_default(#20005,#10000,6,13,6,15)
hasLocation(#20004,#20005)
#20006=*
tokeninfo(#20006,6,#20001,1,"x")
#20007=@"loc,{#10000},6,17,6,17"
locations_default(#20007,#10000,6,17,6,17)
hasLocation(#20006,#20007)
#20008=*
tokeninfo(#20008,8,#20001,2,"=")
#20009=@"loc,{#10000},6,19,6,19"
locations_default(#20009,#10000,6,19,6,19)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,3,#20001,3,"42")
#20011=@"loc,{#10000},6,21,6,22"
locations_default(#20011,#10000,6,21,6,22)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,8,#20001,4,";")
#20013=@"loc,{#10000},6,23,6,23"
locations_default(#20013,#10000,6,23,6,23)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,0,#20001,5,"")
#20015=@"loc,{#10000},6,24,6,23"
locations_default(#20015,#10000,6,24,6,23)
hasLocation(#20014,#20015)
toplevels(#20001,2)
hasLocation(#20001,#20003)
#20016=@"var;{x};{#20000}"
variables(#20016,"x",#20000)
#20017=*
stmts(#20017,18,#20001,0,"var x = 42;")
hasLocation(#20017,#20003)
stmt_containers(#20017,#20001)
#20001=*
#20002=@"script;{#10000},6,13"
#20003=*
lines(#20003,#20002,"var x = 42;","")
#20004=@"loc,{#10000},6,13,6,23"
locations_default(#20004,#10000,6,13,6,23)
hasLocation(#20003,#20004)
numlines(#20002,1,1,0)
#20005=*
tokeninfo(#20005,7,#20002,0,"var")
#20006=@"loc,{#10000},6,13,6,15"
locations_default(#20006,#10000,6,13,6,15)
hasLocation(#20005,#20006)
#20007=*
tokeninfo(#20007,6,#20002,1,"x")
#20008=@"loc,{#10000},6,17,6,17"
locations_default(#20008,#10000,6,17,6,17)
hasLocation(#20007,#20008)
#20009=*
tokeninfo(#20009,8,#20002,2,"=")
#20010=@"loc,{#10000},6,19,6,19"
locations_default(#20010,#10000,6,19,6,19)
hasLocation(#20009,#20010)
#20011=*
tokeninfo(#20011,3,#20002,3,"42")
#20012=@"loc,{#10000},6,21,6,22"
locations_default(#20012,#10000,6,21,6,22)
hasLocation(#20011,#20012)
#20013=*
tokeninfo(#20013,8,#20002,4,";")
#20014=@"loc,{#10000},6,23,6,23"
locations_default(#20014,#10000,6,23,6,23)
hasLocation(#20013,#20014)
#20015=*
tokeninfo(#20015,0,#20002,5,"")
#20016=@"loc,{#10000},6,24,6,23"
locations_default(#20016,#10000,6,24,6,23)
hasLocation(#20015,#20016)
toplevels(#20002,2)
hasLocation(#20002,#20004)
#20017=@"var;{x};{#20000}"
variables(#20017,"x",#20000)
#20018=*
exprs(#20018,64,#20017,0,"x = 42")
#20019=@"loc,{#10000},6,17,6,22"
locations_default(#20019,#10000,6,17,6,22)
hasLocation(#20018,#20019)
enclosing_stmt(#20018,#20017)
expr_containers(#20018,#20001)
#20020=*
exprs(#20020,78,#20018,0,"x")
hasLocation(#20020,#20007)
enclosing_stmt(#20020,#20017)
expr_containers(#20020,#20001)
literals("x","x",#20020)
decl(#20020,#20016)
stmts(#20018,18,#20002,0,"var x = 42;")
hasLocation(#20018,#20004)
stmt_containers(#20018,#20002)
#20019=*
exprs(#20019,64,#20018,0,"x = 42")
#20020=@"loc,{#10000},6,17,6,22"
locations_default(#20020,#10000,6,17,6,22)
hasLocation(#20019,#20020)
enclosing_stmt(#20019,#20018)
expr_containers(#20019,#20002)
#20021=*
exprs(#20021,3,#20018,1,"42")
hasLocation(#20021,#20011)
enclosing_stmt(#20021,#20017)
expr_containers(#20021,#20001)
literals("42","42",#20021)
exprs(#20021,78,#20019,0,"x")
hasLocation(#20021,#20008)
enclosing_stmt(#20021,#20018)
expr_containers(#20021,#20002)
literals("x","x",#20021)
decl(#20021,#20017)
#20022=*
entry_cfg_node(#20022,#20001)
#20023=@"loc,{#10000},6,13,6,12"
locations_default(#20023,#10000,6,13,6,12)
hasLocation(#20022,#20023)
#20024=*
exit_cfg_node(#20024,#20001)
hasLocation(#20024,#20015)
successor(#20017,#20020)
successor(#20021,#20018)
successor(#20020,#20021)
successor(#20018,#20024)
successor(#20022,#20017)
exprs(#20022,3,#20019,1,"42")
hasLocation(#20022,#20012)
enclosing_stmt(#20022,#20018)
expr_containers(#20022,#20002)
literals("42","42",#20022)
#20023=*
entry_cfg_node(#20023,#20002)
#20024=@"loc,{#10000},6,13,6,12"
locations_default(#20024,#10000,6,13,6,12)
hasLocation(#20023,#20024)
#20025=*
toplevel_parent_xml_node(#20001,#20025)
exit_cfg_node(#20025,#20002)
hasLocation(#20025,#20016)
successor(#20018,#20021)
successor(#20022,#20019)
successor(#20021,#20022)
successor(#20019,#20025)
successor(#20023,#20018)
toplevel_parent_xml_node(#20002,#20001)
#20026=*
xmlElements(#20026,"html",#10000,0,#10000)
#20027=@"loc,{#10000},1,1,8,7"
@@ -103,10 +103,10 @@ xmlElements(#20030,"a",#20028,0,#10000)
#20031=@"loc,{#10000},6,1,6,29"
locations_default(#20031,#10000,6,1,6,29)
xmllocations(#20030,#20031)
xmlAttrs(#20025,#20030,"onclick","var x = 42;",0,#10000)
xmlAttrs(#20001,#20030,"onclick","var x = 42;",0,#10000)
#20032=@"loc,{#10000},6,4,6,24"
locations_default(#20032,#10000,6,4,6,24)
xmllocations(#20025,#20032)
xmllocations(#20001,#20032)
#20033=*
xmlElements(#20033,"head",#20026,0,#10000)
#20034=@"loc,{#10000},2,1,4,7"

View File

@@ -8,43 +8,43 @@ locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},3,17"
toplevels(#20001,1)
#20002=@"loc,{#10000},3,17,3,17"
locations_default(#20002,#10000,3,17,3,17)
hasLocation(#20001,#20002)
#20003=*
js_parse_errors(#20003,#20001,"Error: Unexpected token","#!/usr/bin/node
#20001=*
#20002=@"script;{#10000},3,17"
toplevels(#20002,1)
#20003=@"loc,{#10000},3,17,3,17"
locations_default(#20003,#10000,3,17,3,17)
hasLocation(#20002,#20003)
#20004=*
js_parse_errors(#20004,#20002,"Error: Unexpected token","#!/usr/bin/node
")
#20004=@"loc,{#10000},4,1,4,1"
locations_default(#20004,#10000,4,1,4,1)
hasLocation(#20003,#20004)
#20005=*
lines(#20005,#20001,"","
#20005=@"loc,{#10000},4,1,4,1"
locations_default(#20005,#10000,4,1,4,1)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20002,"","
")
#20006=@"loc,{#10000},3,17,3,16"
locations_default(#20006,#10000,3,17,3,16)
hasLocation(#20005,#20006)
#20007=*
lines(#20007,#20001,"#!/usr/bin/node","
#20007=@"loc,{#10000},3,17,3,16"
locations_default(#20007,#10000,3,17,3,16)
hasLocation(#20006,#20007)
#20008=*
lines(#20008,#20002,"#!/usr/bin/node","
")
#20008=@"loc,{#10000},4,1,4,15"
locations_default(#20008,#10000,4,1,4,15)
hasLocation(#20007,#20008)
#20009=*
lines(#20009,#20001,"// shebang in HTML is not OK","
#20009=@"loc,{#10000},4,1,4,15"
locations_default(#20009,#10000,4,1,4,15)
hasLocation(#20008,#20009)
#20010=*
lines(#20010,#20002,"// shebang in HTML is not OK","
")
#20010=@"loc,{#10000},5,1,5,28"
locations_default(#20010,#10000,5,1,5,28)
hasLocation(#20009,#20010)
#20011=*
lines(#20011,#20001," ","")
#20012=@"loc,{#10000},6,1,6,8"
locations_default(#20012,#10000,6,1,6,8)
hasLocation(#20011,#20012)
numlines(#20001,4,0,0)
#20013=*
toplevel_parent_xml_node(#20001,#20013)
#20011=@"loc,{#10000},5,1,5,28"
locations_default(#20011,#10000,5,1,5,28)
hasLocation(#20010,#20011)
#20012=*
lines(#20012,#20002," ","")
#20013=@"loc,{#10000},6,1,6,8"
locations_default(#20013,#10000,6,1,6,8)
hasLocation(#20012,#20013)
numlines(#20002,4,0,0)
toplevel_parent_xml_node(#20002,#20001)
#20014=*
xmlElements(#20014,"html",#10000,0,#10000)
#20015=@"loc,{#10000},1,1,10,7"
@@ -60,9 +60,9 @@ xmlElements(#20018,"head",#20014,0,#10000)
#20019=@"loc,{#10000},2,5,7,11"
locations_default(#20019,#10000,2,5,7,11)
xmllocations(#20018,#20019)
xmlElements(#20013,"script",#20018,0,#10000)
xmlElements(#20001,"script",#20018,0,#10000)
#20020=@"loc,{#10000},3,9,6,17"
locations_default(#20020,#10000,3,9,6,17)
xmllocations(#20013,#20020)
xmllocations(#20001,#20020)
numlines(#10000,10,0,0)
filetype(#10000,"html")

View File

@@ -167,7 +167,7 @@ predicate whitelisted(UnusedLocal v) {
vd.isAmbient()
)
or
exists(DirectEval eval |
exists(Expr eval | eval instanceof DirectEval or eval instanceof GeneratedCodeExpr |
// eval nearby
eval.getEnclosingFunction() = v.getADeclaration().getEnclosingFunction() and
// ... but not on the RHS

View File

@@ -308,7 +308,7 @@ class CodeInAttribute extends TopLevel {
CodeInAttribute() {
this instanceof @event_handler or
this instanceof @javascript_url or
this instanceof @angular_template_toplevel
this instanceof @template_toplevel
}
}

View File

@@ -2873,3 +2873,28 @@ class ImportMetaExpr extends @import_meta_expr, Expr {
override string getAPrimaryQlClass() { result = "ImportMetaExpr" }
}
/**
* A placeholder for some code generated by a templating engine,
* speculatively parsed as an expression.
*
* For example, the right-hand side of the following assignments will each be parsed
* as `GeneratedNodeExpr` nodes:
* ```js
* let data1 = {{ user_data1 }};
* let data2 = {{{ user_data2 }}};
* ```
*
* Note that templating placeholders occuring inside strings literals are not parsed,
* and are simply seen as being part of the string literal.
* For example, following snippet does not contain any `GeneratedCodeExpr` nodes:
* ```js
* let data1 = "{{ user_data }}";
* ```
*/
class GeneratedCodeExpr extends @generated_code_expr, Expr {
/** Gets the placeholder tag that was parsed as an expression. */
Templating::TemplatePlaceholderTag getPlaceholderTag() { this = result.getEnclosingExpr() }
override string getAPrimaryQlClass() { result = "GeneratedCodeExpr" }
}

View File

@@ -25,6 +25,8 @@ class JsonStringifyCall extends DataFlow::CallNode {
callee = DataFlow::moduleMember("util", "inspect") or
callee = DataFlow::moduleImport(["pretty-format", "object-inspect"])
)
or
this = Templating::getAPipeCall(["json", "dump"])
}
/**

View File

@@ -1268,6 +1268,22 @@ module DataFlow {
override string toString() { result = variable.getName() }
}
/** A data flow node representing the value plugged into a template tag. */
class TemplatePlaceholderTagNode extends Node, TTemplatePlaceholderTag {
/** Gets the template tag represented by this data flow node. */
Templating::TemplatePlaceholderTag getTag() { this = TTemplatePlaceholderTag(result) }
override BasicBlock getBasicBlock() { none() }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
getTag().getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
override string toString() { result = getTag().toString() }
}
/**
* INTERNAL. DO NOT USE.
*
@@ -1664,6 +1680,9 @@ module DataFlow {
or
(e instanceof AwaitExpr or e instanceof DynamicImportExpr) and
cause = "await"
or
e instanceof GeneratedCodeExpr and
cause = "eval" // we use 'eval' here to represent code generation more broadly
)
or
nd instanceof TExceptionalInvocationReturnNode and cause = "call"

View File

@@ -374,7 +374,8 @@ DataFlow::SourceNode globalObjectRef() {
// top-level `this`
exists(StmtContainer sc |
sc = result.(ThisNode).getBindingContainer() and
not sc instanceof Function
not sc instanceof Function and
not sc instanceof Templating::TemplateTopLevel
)
or
// DOM

View File

@@ -320,8 +320,8 @@ module SourceNode {
astNode instanceof ImportSpecifier or
astNode instanceof ImportMetaExpr or
astNode instanceof TaggedTemplateExpr or
astNode instanceof Angular2::PipeRefExpr or
astNode instanceof Angular2::TemplateVarRefExpr or
astNode instanceof Templating::PipeRefExpr or
astNode instanceof Templating::TemplateVarRefExpr or
astNode instanceof StringLiteral
)
or

View File

@@ -30,4 +30,5 @@ newtype TNode =
TFunctionReturnNode(Function f) or
TExceptionalFunctionReturnNode(Function f) or
TExceptionalInvocationReturnNode(InvokeExpr e) or
TGlobalAccessPathRoot()
TGlobalAccessPathRoot() or
TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag)

View File

@@ -230,46 +230,11 @@ module Angular2 {
DomAdapterLocation() { this = domAdapter().getAMethodCall("getLocation") }
}
/**
* A reference to a pipe function, occurring in an Angular pipe expression
* that has been desugared to a function call.
*
* For example, the expression `x | f: y` is desugared to `f(x, y)` where
* `f` is a `PipeRefExpr`.
*/
class PipeRefExpr extends Expr, @angular_pipe_ref {
/** Gets the identifier node naming the pipe. */
Identifier getIdentifier() { result = getChildExpr(0) }
class PipeRefExpr = Templating::PipeRefExpr;
/** Gets the name of the pipe being referenced. */
string getName() { result = getIdentifier().getName() }
class TemplateVarRefExpr = Templating::TemplateVarRefExpr;
override string getAPrimaryQlClass() { result = "Angular2::PipeRefExpr" }
}
/**
* A reference to a variable in a template expression, corresponding
* to a property on the component class.
*/
class TemplateVarRefExpr extends Expr {
TemplateVarRefExpr() { this = any(TemplateTopLevel tl).getScope().getAVariable().getAnAccess() }
}
/** The top-level containing an Angular expression. */
class TemplateTopLevel extends TopLevel, @angular_template_toplevel {
/** Gets the expression in this top-level. */
Expr getExpression() { result = getChildStmt(0).(ExprStmt).getExpr() }
/** Gets the data flow node representing the initialization of the given variable in this scope. */
DataFlow::Node getVariableInit(string name) {
result = DataFlow::ssaDefinitionNode(SSA::implicitInit(getScope().getVariable(name)))
}
/** Gets a data flow node corresponding to a use of the given template variable within this top-level. */
DataFlow::SourceNode getAVariableUse(string name) {
result = getScope().getVariable(name).getAnAccess().flow()
}
}
class TemplateTopLevel = Templating::TemplateTopLevel;
/** The RHS of a `templateUrl` property, seen as a path expression. */
private class TemplateUrlPath extends PathExpr {
@@ -493,19 +458,10 @@ module Angular2 {
}
}
/**
* Gets an invocation of the pipe of the given name.
*
* For example, the call generated from `items | async` would be found by `getAPipeCall("async")`.
*/
DataFlow::CallNode getAPipeCall(string name) {
result.getCalleeNode().asExpr().(PipeRefExpr).getName() = name
}
private class BuiltinPipeStep extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::CallNode call, string name |
call = getAPipeCall(name) and
call = Templating::getAPipeCall(name) and
succ = call
|
exists(int i | pred = call.getArgument(i) |

View File

@@ -841,3 +841,37 @@ class NgDataFlowNode extends TNode {
)
}
}
/** Holds if everything in the given file should be considered part of an AngularJS app. */
private predicate fileIsImplicitlyAngularJS(HTML::HtmlFile file) {
// The file contains ng-* attributes.
exists(HTML::Attribute attrib |
attrib.getName().regexpMatch("ng-.*") and
attrib.getFile() = file
) and
// But does not contain the ng-app root element, implying that file is
// included from elsewhere.
not exists(HTML::Attribute attrib |
attrib.getName() = "ng-app" and
attrib.getFile() = file
)
}
/** Holds if `element` is under a `ng-non-bindable` directive, disabling interpretation by AngularJS. */
private predicate isNonBindable(HTML::Element element) {
exists(element.getParent*().getAttributeByName("ng-non-bindable"))
}
/**
* Holds if the contents and attribute values of the given element are interpreted by AngularJS,
* that is, any placeholder expressions therein, such as `{{x}}`, are evaluated and inserted in the output.
*/
predicate isInterpretedByAngularJS(HTML::Element element) {
(
fileIsImplicitlyAngularJS(element.getFile())
or
exists(element.getParent*().getAttributeByName("ng-app"))
) and
not isNonBindable(element) and
not element.getName() = "script" // script tags are never interpreted
}

View File

@@ -972,4 +972,20 @@ module Express {
.getParameter(0)
}
}
/**
* A call to the Express `res.render()` method, seen as a template instantiation.
*/
private class RenderCallAsTemplateInstantiation extends Templating::TemplateInstantiation::Range,
DataFlow::CallNode {
RenderCallAsTemplateInstantiation() {
this = any(ResponseSource res).ref().getAMethodCall("render")
}
override DataFlow::Node getTemplateFileNode() { result = getArgument(0) }
override DataFlow::Node getTemplateParamsNode() { result = getArgument(1) }
override DataFlow::SourceNode getOutput() { result = getCallback(2).getParameter(1) }
}
}

View File

@@ -288,4 +288,19 @@ module Fastify {
)
}
}
/**
* A call to `rep.view('file', { ... })`, seen as a template instantiation.
*
* Assumes the presense of a plugin that provides the `view` method, such as the `point-of-view` plugin.
*/
private class ViewCall extends Templating::TemplateInstantiation::Range, DataFlow::CallNode {
ViewCall() { this = any(ReplySource rep).ref().getAMethodCall("view") }
override DataFlow::SourceNode getOutput() { result = getCallback(2).getParameter(1) }
override DataFlow::Node getTemplateFileNode() { result = getArgument(0) }
override DataFlow::Node getTemplateParamsNode() { result = getArgument(1) }
}
}

View File

@@ -31,6 +31,17 @@ module Hapi {
* Gets the parameter of the route handler that contains the request object.
*/
Parameter getRequestParameter() { result = function.getParameter(0) }
/**
* Gets the parameter of the route handler that contains the "request toolkit",
* usually named `h`.
*/
Parameter getRequestToolkitParameter() { result = function.getParameter(1) }
/**
* Gets a source node referring to the request toolkit parameter, usually named `h`.
*/
DataFlow::SourceNode getRequestToolkit() { result = getRequestToolkitParameter().flow() }
}
/**
@@ -237,4 +248,17 @@ module Hapi {
HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() }
}
/**
* A call to `h.view('file', { ... })` seen as a template instantiation.
*/
private class ViewCall extends Templating::TemplateInstantiation::Range, DataFlow::CallNode {
ViewCall() { this = any(RouteHandler rh).getRequestToolkit().getAMethodCall("view") }
override DataFlow::SourceNode getOutput() { none() }
override DataFlow::Node getTemplateFileNode() { result = getArgument(0) }
override DataFlow::Node getTemplateParamsNode() { result = getArgument(1) }
}
}

View File

@@ -112,7 +112,7 @@ module Koa {
*/
RouteHandler getRouteHandler() { result = rh }
predicate flowsTo(DataFlow::Node nd) { ref(DataFlow::TypeTracker::end()).flowsTo(nd) }
predicate flowsTo(DataFlow::Node nd) { ref().flowsTo(nd) }
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
t.start() and
@@ -120,6 +120,9 @@ module Koa {
or
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
}
/** Gets a source node that refers to this context object. */
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
}
/**
@@ -424,4 +427,23 @@ module Koa {
override RouteHandler getRouteHandler() { result = rh }
}
/**
* A call to `ctx.render('file', { ... })`, seen as a template instantiation.
*/
private class RenderCall extends Templating::TemplateInstantiation::Range, DataFlow::CallNode {
ContextSource ctx;
RenderCall() { this = ctx.ref().getAMethodCall("render") }
override DataFlow::SourceNode getOutput() { none() }
override DataFlow::Node getTemplateFileNode() { result = getArgument(0) }
override DataFlow::Node getTemplateParamsNode() {
result = getArgument(1)
or
result = ctx.ref().getAPropertyReference("state")
}
}
}

View File

@@ -48,4 +48,664 @@ module Templating {
string getDelimiterMatchingRegexpWithPrefix(string prefix) {
result = "(?s)" + prefix + "(" + concat("\\Q" + getADelimiter() + "\\E", "|") + ").*"
}
/** A placeholder tag for a templating engine. */
class TemplatePlaceholderTag extends @template_placeholder_tag, Locatable {
override Location getLocation() { hasLocation(this, result) }
override string toString() { template_placeholder_tag_info(this, _, result) }
/** Gets the full text of the template tag, including delimiters. */
string getRawText() { template_placeholder_tag_info(this, _, result) }
/** Gets the enclosing HTML element, attribute, or file. */
Locatable getParent() { template_placeholder_tag_info(this, result, _) }
/** Gets a data flow node representing the value plugged into this placeholder. */
DataFlow::TemplatePlaceholderTagNode asDataFlowNode() { result.getTag() = this }
/** Gets the top-level containing the template expression to be inserted at this placeholder. */
TemplateTopLevel getInnerTopLevel() { toplevel_parent_xml_node(result, this) }
/**
* Holds if this performs raw interpolation, that is, inserts its result
* in the output without escaping it.
*/
predicate isRawInterpolation() {
getRawText().regexpMatch(getLikelyTemplateSyntax(getFile()).getRawInterpolationRegexp())
}
/**
* Holds if this performs HTML escaping on the result before inserting it in the template.
*/
predicate isEscapingInterpolation() {
getRawText().regexpMatch(getLikelyTemplateSyntax(getFile()).getEscapingInterpolationRegexp())
}
/** Holds if this occurs in a `script` tag. */
predicate isInScriptTag() {
// We want to exclude non-code scripts like JSON.
toplevel_parent_xml_node(any(InlineScript scr), getParent())
}
/**
* Holds if this occurs in an attribute value that is interepted as JavaScript.
*
* Unlike in script tags, HTML entities in attributes are expanded prior to JS parsing,
* which cancels out the benefit of HTML escaping.
*/
predicate isInCodeAttribute() {
exists(TopLevel code | code = getParent().(HTML::Attribute).getCodeInAttribute() |
code instanceof EventHandlerCode or
code instanceof JavaScriptURL
)
}
/** Holds if this placeholder occurs in JS code. */
predicate isInCodeContext() { isInScriptTag() or isInCodeAttribute() }
/**
* Holds if this placeholder occurs in the definition of another template, which means the output
* is susceptible to code injection.
*/
predicate isInNestedTemplateContext(string templateType) {
templateType = "AngularJS" and
AngularJS::isInterpretedByAngularJS(getParent()) and
// Exclude delimiters that coincide with those of AngularJS's own template engine.
// It's too unlikely to happen, more likely is that one of our heuristics got it wrong.
not getRawText().regexpMatch("(?s)\\{\\{.*\\}\\}")
}
/**
* Gets the innermost JavaScript expression containing this template tag, if any.
*/
pragma[nomagic]
Expr getEnclosingExpr() { expr_contains_template_tag_location(result, getLocation()) }
}
/**
* A reference to a pipe function, occurring in a pipe expression
* that has been desugared to a function call.
*
* For example, the expression `x | f: y` is desugared to `f(x, y)` where
* `f` is a `PipeRefExpr`.
*/
class PipeRefExpr extends Expr, @template_pipe_ref {
/** Gets the identifier node naming the pipe. */
Identifier getIdentifier() { result = getChildExpr(0) }
/** Gets the name of the pipe being referenced. */
string getName() { result = getIdentifier().getName() }
override string getAPrimaryQlClass() { result = "Templating::PipeRefExpr" }
}
/**
* Gets an invocation of the pipe of the given name.
*
* For example, the call generated from `items | async` would be found by `getAPipeCall("async")`.
*/
DataFlow::CallNode getAPipeCall(string name) {
result.getCalleeNode().asExpr().(PipeRefExpr).getName() = name
}
/**
* A reference to a variable in a template expression, corresponding
* to a value plugged into the template.
*/
class TemplateVarRefExpr extends Expr {
TemplateVarRefExpr() { this = any(TemplateTopLevel tl).getScope().getAVariable().getAnAccess() }
}
/** The top-level containing the expression in a template placeholder. */
class TemplateTopLevel extends TopLevel, @template_toplevel {
/** Gets the expression in this top-level. */
Expr getExpression() { result = getChildStmt(0).(ExprStmt).getExpr() }
/** Gets the data flow node representing the initialization of the given variable in this scope. */
DataFlow::Node getVariableInit(string name) {
result = DataFlow::ssaDefinitionNode(SSA::implicitInit(getScope().getVariable(name)))
}
/** Gets a data flow node corresponding to a use of the given template variable within this top-level. */
DataFlow::SourceNode getAVariableUse(string name) {
result = getScope().getVariable(name).getAnAccess().flow()
}
}
/**
* A place where a template is instantiated or rendered.
*/
class TemplateInstantiation extends DataFlow::Node {
TemplateInstantiation::Range range;
TemplateInstantiation() { this = range }
/** Gets a data flow node that refers to the instantiated template string, if any. */
DataFlow::SourceNode getOutput() { result = range.getOutput() }
/** Gets a data flow node that refers a template file to be instantiated, if any. */
DataFlow::Node getTemplateFileNode() { result = range.getTemplateFileNode() }
/** Gets a data flow node that refers to an object whose properties become variables in the template. */
DataFlow::Node getTemplateParamsNode() { result = range.getTemplateParamsNode() }
/** Gets the template file instantiated here, if any. */
TemplateFile getTemplateFile() {
result = getTemplateFileNode().(TemplateFileReference).getTemplateFile()
}
/**
* Gets the template syntax used by this template instantiation, if known.
*
* If not known, the relevant syntax will be determined by a heuristic.
*/
TemplateSyntax getTemplateSyntax() { result = range.getTemplateSyntax() }
}
/** Companion module to the `TemplateInstantiation` class. */
module TemplateInstantiation {
abstract class Range extends DataFlow::Node {
/** Gets a data flow node that refers to the instantiated template, if any. */
abstract DataFlow::SourceNode getOutput();
/** Gets a data flow node that refers a template file to be instantiated, if any. */
abstract DataFlow::Node getTemplateFileNode();
/** Gets a data flow node that refers to an object whose properties become variables in the template. */
abstract DataFlow::Node getTemplateParamsNode();
/**
* Gets the template syntax used by this template instantiation, if known.
*
* If not known, the relevant syntax will be determined by a heuristic.
*/
TemplateSyntax getTemplateSyntax() { none() }
}
}
/** Gets an API node that may flow to `succ` through a template instantiation. */
private API::Node getTemplateInput(DataFlow::SourceNode succ) {
exists(TemplateInstantiation inst, API::Node base, string name |
base.getARhs() = inst.getTemplateParamsNode() and
result = base.getMember(name) and
succ =
inst.getTemplateFile()
.getAnImportedFile*()
.getAPlaceholder()
.getInnerTopLevel()
.getAVariableUse(name)
)
or
exists(string prop, DataFlow::SourceNode prev |
result = getTemplateInput(prev).getMember(prop) and
succ = prev.getAPropertyRead(prop)
)
}
private class TemplateInputStep extends DataFlow::SharedFlowStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
getTemplateInput(succ).getARhs() = pred
}
}
/**
* A data flow step from the expression in a placeholder tag to the tag itself,
* representing the value plugged into the template.
*/
private class TemplatePlaceholderStep extends DataFlow::SharedFlowStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(TemplatePlaceholderTag tag |
pred = tag.getInnerTopLevel().getExpression().flow() and
succ = tag.asDataFlowNode()
)
}
}
/**
* A taint step from a `TemplatePlaceholderTag` to the enclosing expression in the
* surrounding JavaScript program.
*/
private class PlaceholderToGeneratedCodeStep extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(TemplatePlaceholderTag tag |
pred = tag.asDataFlowNode() and
succ = tag.getEnclosingExpr().flow()
)
}
}
/** A file that can be referenced by a template instantiation. */
abstract class TemplateFile extends File {
/** Gets a placeholder tag in this file. */
final TemplatePlaceholderTag getAPlaceholder() { result.getFile() = this }
/** Gets a template file referenced by this one via a template inclusion tag, such as `{% include foo %}` */
TemplateFile getAnImportedFile() {
result = getAPlaceholder().(TemplateInclusionTag).getImportedFile()
}
}
/** Any HTML file, seen as a possible target for template instantiation. */
private class TemplateFileByExtension extends TemplateFile {
TemplateFileByExtension() { getFileType().isHtml() }
}
/**
* A data flow node whose string value refers to a template file.
*
* This is similar to `PathExpr` with two main differences:
* - It is not used for import resolution, and so can be computed in a later stage.
* - The root folder is considered unknown, and so a heuristic is used to guess the most
* likely template file being referenced.
*/
abstract class TemplateFileReference extends DataFlow::Node {
/** Gets the value that identifies the template. */
string getValue() {
result = getStringValue()
or
exists(API::Node node |
this = node.getARhs() and
result = node.getAValueReachingRhs().getStringValue()
)
}
pragma[nomagic]
private Folder getFolder() { result = getFile().getParentContainer() }
/** Gets the template file referenced by this node. */
final TemplateFile getTemplateFile() {
result = this.getValue().(TemplateFileReferenceString).getTemplateFile(getFolder())
}
}
/** Get file argument of a template instantiation, seen as a template file reference. */
private class DefaultTemplateFileReference extends TemplateFileReference {
DefaultTemplateFileReference() { this = any(TemplateInstantiation inst).getTemplateFileNode() }
}
/**
* A string that refers to a template file, and should be resolved as such.
*
* The string must be normalized, with backslashes replaced by forward slashes.
*
* This is automatically populated for instances of `TemplateFileReference`, but additional subclasses
* may be added if other strings need to be resolved.
*
* This is similar to `PathString` with two main differences:
* - It is not used for import resolution, and so can be computed in a later stage.
* - The root folder is considered unknown, and so a heuristic is used to guess the most
* likely template file being referenced.
*/
abstract class TemplateFileReferenceString extends string {
bindingset[this]
TemplateFileReferenceString() { this = this }
/** Gets the folder in which this string occurs, used to determine which file it could refer to. */
abstract Folder getContextFolder();
/**
* Gets the base name of the string, similar to `Container.getBaseName`.
*/
string getBaseName() { result = this.regexpReplaceAll(".*/", "") }
/**
* Gets the stem, similar to `Container.getStem`.
*/
string getStem() { result = getBaseName().regexpCapture("(.*?)(?:\\.([^.]*))?", 1) }
/** Gets the template file referenced by this string when resolved from `baseFolder`. */
final TemplateFile getTemplateFile(Folder baseFolder) {
result = getBestMatchingTarget(baseFolder, this)
or
exists(UpwardTraversalSuffix up |
this = up.getOriginal() and
result = up.(TemplateFileReferenceString).getTemplateFile(baseFolder.getParentContainer()) and
baseFolder = getContextFolder()
)
}
}
/** The value of a template reference node, as a template reference string. */
private class DefaultTemplateReferenceString extends TemplateFileReferenceString {
TemplateFileReference r;
DefaultTemplateReferenceString() { this = r.getValue().replaceAll("\\", "/") }
// Stop optimizer from trying to share the 'getParentContainer' join
pragma[nomagic]
private Folder getFileReferenceFolder() {
result = pragma[only_bind_out](r).getFile().getParentContainer()
}
override Folder getContextFolder() { result = getFileReferenceFolder() }
}
/** The `X` in a path of form `../X`, treated as a separate path string with a different context folder. */
private class UpwardTraversalSuffix extends TemplateFileReferenceString {
TemplateFileReferenceString original;
UpwardTraversalSuffix() { original = "../" + this }
override Folder getContextFolder() { result = original.getContextFolder().getParentContainer() }
/** Gets the original string including the `../` prefix. */
TemplateFileReferenceString getOriginal() { result = original }
}
/**
* Gets a "fingerprint" for the given template file, which is used to references
* that might refer to it (for pruning purposes only).
*/
pragma[nomagic]
private string getTemplateFileFingerprint(TemplateFile file) {
result = file.getStem()
or
file.getStem() = "index" and
result = file.getParentContainer().getBaseName()
}
/**
* Gets a "fingerprint" for the given string, which must match one of the fingerprints of
* the referenced file (for pruning purposes only).
*/
pragma[nomagic]
private string getTemplateRefFingerprint(TemplateFileReferenceString ref) {
result = ref.getStem() and not result = ["index", ""]
or
ref.getStem() = ["index", ""] and
result = ref.regexpCapture("(?:.*)?/([^/]*)/(?:index|)(?:\\.[^.]*)?", 1)
or
// If the reference is just 'index', it could potentially refer to any template file
// called 'index' -- we can't use the parent directory to prune candidates early.
ref = "index" and result = "index"
}
/**
* Gets a template file that could potentially be the target of `ref`, based on
* them having the same fingerprint.
*
* This is only used to speed up `getAMatchingTarget` by pruning out pairs that can't match.
*/
pragma[nomagic]
private TemplateFile getAPotentialTarget(TemplateFileReferenceString ref) {
getTemplateFileFingerprint(result) = getTemplateRefFingerprint(ref)
}
/**
* Gets a template file whose path matches the given `ref`.
*
* A file matches if all path components of `ref` are part of the suffix of the file path,
* and in case a file extension is mentioned in `ref`, this must match that of the file.
*
* For example, a file at `src/foo/views/bar/baz.html` would be matched by the following:
* - `bar.html`
* - `bar/baz.html`
* - `views/bar/baz.html`
* - `baz` (extension can be omitted)
* - `bar/baz`
*
* But would not be matched by:
* - `foo/baz.html` (folder does not match)
* - `baz.ejs` (extension does not match)
*
* Additionally, a file whose stem is `index` matches if `ref` would match the parent folder by
* the above rules. For example: `bar` matches `src/bar/index.html`.
*/
pragma[nomagic]
private TemplateFile getAMatchingTarget(TemplateFileReferenceString ref) {
result = getAPotentialTarget(ref) and
result.getAbsolutePath() =
any(string s) + ref + ["", "/index"] + ["", "." + result.getExtension()]
}
/**
* Gets the length of the longest common prefix between `file` and the `baseFolder` of `ref`.
*
* This is used to rank all the possible files that `ref` could refer to.
* Picking the one with the highest rank ensures that the file most closely related
* in the file hierarchy is picked.
*
* For example, given the files:
* ```
* A/components/foo.js
* A/views/list.html
* B/components/foo.js
* B/views/list.html
* ```
* The string `list` in `A/components/foo.js` will resolve to `A/views/list.html`,
* and vice versa in `B/components/foo.js`.
*/
pragma[nomagic]
private int getRankOfMatchingTarget(
TemplateFile file, Folder baseFolder, TemplateFileReferenceString ref
) {
file = getAMatchingTarget(ref) and
baseFolder = ref.getContextFolder() and
exists(string filePath, string refPath |
// Pad each file name to ensure they differ at some index, in case one was a prefix of the other
filePath = file.getRelativePath() + "!" and
refPath = baseFolder.getRelativePath() + "@" and
result = min(int i | filePath.charAt(i) != refPath.charAt(i))
)
}
/**
* Gets the template file referred to by `ref` when resolved from `baseFolder`.
*/
private TemplateFile getBestMatchingTarget(Folder baseFolder, TemplateFileReferenceString ref) {
result = max(getAMatchingTarget(ref) as f order by getRankOfMatchingTarget(f, baseFolder, ref))
}
/**
* A syntax type implemented by one or more supported templating engines.
*
* The syntax type determines which templating tags perform implicit escaping.
*
* Since this varies between templating engines, it is important to recognize the
* templating engine correctly.
*/
abstract class TemplateSyntax extends string {
bindingset[this]
TemplateSyntax() { this = this }
/**
* Gets a regular expression matching the full text of a placeholder tag
* using raw interpolation, that is, without HTML escaping.
*/
abstract string getRawInterpolationRegexp();
/**
* Gets a regular expression matching the full text of a placeholder tag
* that performs HTML escaping on its output.
*/
abstract string getEscapingInterpolationRegexp();
/** Gets a file extension that is specific to this templating engine. */
abstract string getAFileExtension();
/** Gets the name of an NPM package providing this templating syntax. */
abstract string getAPackageName();
}
/**
* Mustache-style syntax, using `{{ }}` for safe interpolation, and (in some dialects)
* `{{{ x }}}` for raw interpolation.
*/
private class MustacheStyleSyntax extends TemplateSyntax {
MustacheStyleSyntax() { this = "mustache" }
override string getRawInterpolationRegexp() { result = "(?s)\\{\\{\\{(.*?)\\}\\}\\}" }
override string getEscapingInterpolationRegexp() { result = "(?s)\\{\\{[^{](.*?)\\}\\}" }
override string getAFileExtension() { result = ["hbs", "njk"] }
override string getAPackageName() {
result =
[
"mustache", "handlebars", "hbs", "express-hbs", "swig", "swig-templates", "hogan",
"hogan.js", "nunjucks"
]
}
}
/**
* EJS-style syntax, using `<%= x %>` for safe interpolation, and `<%- x %>` for
* unsafe interpolation.
*/
private class EjsStyleSyntax extends TemplateSyntax {
EjsStyleSyntax() { this = "ejs" }
override string getRawInterpolationRegexp() { result = "(?s)<%-(.*?)%>" }
override string getEscapingInterpolationRegexp() { result = "(?s)<%=(.*?)%>" }
override string getAFileExtension() { result = "ejs" }
override string getAPackageName() { result = "ejs" }
}
private TemplateSyntax getOwnTemplateSyntaxInFolder(Folder f) {
exists(PackageDependencies deps |
deps.getADependency(result.getAPackageName(), _) and
f = deps.getFile().getParentContainer()
)
}
private TemplateSyntax getTemplateSyntaxInFolder(Folder f) {
result = getOwnTemplateSyntaxInFolder(f)
or
not exists(getOwnTemplateSyntaxInFolder(f)) and
result = getTemplateSyntaxInFolder(f.getParentContainer())
}
private TemplateSyntax getTemplateSyntaxFromInstantiation(TemplateFile file) {
result = any(TemplateInstantiation inst | inst.getTemplateFile() = file).getTemplateSyntax()
}
/**
* Gets a template syntax likely to be used in the given file.
*/
TemplateSyntax getLikelyTemplateSyntax(TemplateFile file) {
result = getTemplateSyntaxFromInstantiation(file)
or
not exists(getTemplateSyntaxFromInstantiation(file)) and
result.getAFileExtension() = file.getExtension()
or
not exists(getTemplateSyntaxFromInstantiation(file)) and
not file.getExtension() = any(TemplateSyntax s).getAFileExtension() and
result = getTemplateSyntaxInFolder(file.getParentContainer())
}
/** A step through the `safe` pipe, which bypasses HTML escaping. */
private class SafePipeStep extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::CallNode call |
call = getAPipeCall("safe") and
pred = call.getArgument(0) and
succ = call
)
}
}
/**
* An EJS-style `include` call within a template tag, such as `<%- include(file, { params }) %>`.
*/
private class EjsIncludeCallInTemplate extends TemplateInstantiation::Range, DataFlow::CallNode {
EjsIncludeCallInTemplate() {
exists(TemplatePlaceholderTag tag |
tag.getRawText().regexpMatch("(?s)<%-.*") and
this = tag.getInnerTopLevel().getAVariableUse("include").getACall()
)
}
/** Gets a data flow node that refers to the instantiated template, if any. */
override DataFlow::SourceNode getOutput() { result = this }
/** Gets a data flow node that refers a template file to be instantiated, if any. */
override DataFlow::Node getTemplateFileNode() { result = getArgument(0) }
/** Gets a data flow node that refers to an object whose properties become variables in the template. */
override DataFlow::Node getTemplateParamsNode() { result = getArgument(1) }
}
/**
* The `include` function, seen as an API node, so we can treat it as a template instantiation
* in `EjsIncludeCallInTemplate`.
*
* These API nodes are used in the `getTemplateInput` predicate.
*/
private class IncludeFunctionAsEntryPoint extends API::EntryPoint {
IncludeFunctionAsEntryPoint() { this = "IncludeFunctionAsEntryPoint" }
override DataFlow::SourceNode getAUse() {
result = any(TemplatePlaceholderTag tag).getInnerTopLevel().getAVariableUse("include")
}
override DataFlow::Node getARhs() { none() }
}
/**
* A template tag which causes another template file to be instantiated using the same variables as the current one.
*
* Examples:
* - `{% include foo/bar %}`
* - `{% include "../foo/bar.html" %}`
* - `<% include foo/bar %>`
* - `{{!< foo/bar }}`
* - `{{> foo/bar }}`
*/
class TemplateInclusionTag extends TemplatePlaceholderTag {
string rawPath;
TemplateInclusionTag() {
rawPath =
getRawText()
.regexpCapture("[{<]% *(?:import|include|extend|require)s? *(?:[(] *)?['\"]?(.*?)['\"]? *(?:[)] *)?%[}>]",
1)
or
rawPath = getRawText().regexpCapture("\\{\\{!?[<>](.*?)\\}\\}", 1)
}
/** Gets the imported path (normalized). */
string getPath() { result = rawPath.trim().replaceAll("\\", "/").regexpReplaceAll("^\\./", "") }
/** Gets the file referenced by this inclusion tag. */
TemplateFile getImportedFile() {
result =
getPath().(TemplateFileReferenceString).getTemplateFile(getFile().getParentContainer())
}
}
/** The imported string from a template inclusion tag. */
private class TemplateInclusionPathString extends TemplateFileReferenceString {
TemplateInclusionTag tag;
TemplateInclusionPathString() { this = tag.getPath() }
override Folder getContextFolder() { result = tag.getFile().getParentContainer() }
}
/**
* A call to a member of the `consolidate` library, seen as a template instantiation.
*/
private class ConsolidateCall extends TemplateInstantiation::Range, API::CallNode {
string engine;
ConsolidateCall() { this = API::moduleImport("consolidate").getMember(engine).getACall() }
override TemplateSyntax getTemplateSyntax() { result.getAPackageName() = engine }
override DataFlow::SourceNode getOutput() {
result = getParameter([1, 2]).getParameter(1).getAnImmediateUse()
or
not exists(getParameter([1, 2]).getParameter(1)) and
result = this
}
override DataFlow::Node getTemplateFileNode() { result = getArgument(0) }
override DataFlow::Node getTemplateParamsNode() { result = getArgument(1) }
}
}

View File

@@ -51,6 +51,73 @@ module CodeInjection {
}
}
/**
* A template tag occuring in JS code, viewed as a code injection sink.
*/
class TemplateTagInScriptSink extends Sink {
TemplateTagInScriptSink() {
exists(Templating::TemplatePlaceholderTag tag |
this = tag.asDataFlowNode() and
tag.isEscapingInterpolation() // to avoid double reporting, raw interpolation is only flagged by the XSS query
|
// In an attribute, HTML entities are expanded prior to JS parsing, so the escaping performed by the
// templating engine has no effect against code injection.
tag.isInCodeAttribute()
or
// In a script tag, HTML entities are not expanded.
// To reduce noise, we filter out a common pattern where a template tag occurs in a string literal,
// since HTML escaping prevents breaking out of the string literal.
//
// var foo = "<%= foo %>";
//
// However, we still flag the special case where multiple such strings occur on the same line, as injection can sometimes
// we obtained by injecting a backslash character at the end of the first one:
//
// init("<%= foo %">, "<%= bar %>");
//
// For example, setting foo to `\` and bar to `, alert(1));//`, code injection is obtained.
tag.isInScriptTag() and
not tag.getEnclosingExpr() =
getLastStringWithPlaceholderOnLine(tag.getLocation().getFile(),
tag.getLocation().getStartLine())
)
}
}
/** Gets the last string literal containing a template placeholder on the given line. */
pragma[nomagic]
private StringLiteral getLastStringWithPlaceholderOnLine(File file, int line) {
result =
max(StringLiteral lit, Location loc |
loc = lit.getLocation() and
loc.getFile() = file and
loc.getStartLine() = line and
lit =
any(Templating::TemplatePlaceholderTag tag | tag.isEscapingInterpolation())
.getEnclosingExpr()
|
lit order by loc.getStartColumn()
)
}
/**
* A server-side template tag occurring in the context of another template language.
*/
class TemplateTagInNestedTemplateContext extends Sink {
string templateType;
TemplateTagInNestedTemplateContext() {
exists(Templating::TemplatePlaceholderTag tag |
tag.isInNestedTemplateContext(templateType) and
this = tag.asDataFlowNode()
)
}
override string getMessageSuffix() {
result = "here and is interpreted by " + templateType + ", which may evaluate it as code"
}
}
/**
* Gets a reference to a `<script />` tag created using `document.createElement`.
*/

View File

@@ -43,4 +43,19 @@ module FileAccessToHttp {
)
}
}
/**
* A property access to `length`, seen as a sanitizer as it likely contains a number.
*/
private class LengthAccessAsSanitizer extends Sanitizer {
LengthAccessAsSanitizer() { this.(DataFlow::PropRead).getPropertyName() = "length" }
}
/**
* A generated code expression, seen as a sanitizer, to block flow from a file
* sent to the client via a template.
*/
private class GeneratedCodeAsSanitizer extends Sanitizer {
GeneratedCodeAsSanitizer() { this.asExpr() instanceof GeneratedCodeExpr }
}
}

View File

@@ -369,6 +369,26 @@ module DomBasedXss {
*/
class VHtmlSink extends Vue::VHtmlAttribute, DomBasedXss::Sink { }
/**
* A raw interpolation tag in a template file, viewed as an XSS sink.
*/
class TemplateSink extends DomBasedXss::Sink {
TemplateSink() {
exists(Templating::TemplatePlaceholderTag tag |
tag.isRawInterpolation() and
this = tag.asDataFlowNode()
)
}
}
/**
* A value being piped into the `safe` pipe in a template file,
* disabling subsequent HTML escaping.
*/
class SafePipe extends DomBasedXss::Sink {
SafePipe() { this = Templating::getAPipeCall("safe").getArgument(0) }
}
/**
* A property read from a safe property is considered a sanitizer.
*/

View File

@@ -125,14 +125,14 @@ case @toplevel.kind of
| 1 = @inline_script
| 2 = @event_handler
| 3 = @javascript_url
| 4 = @angular_template_toplevel;
| 4 = @template_toplevel;
is_module (int tl: @toplevel ref);
is_nodejs (int tl: @toplevel ref);
is_es2015_module (int tl: @toplevel ref);
is_closure_module (int tl: @toplevel ref);
@xml_node_with_code = @xmlelement | @xmlattribute;
@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag;
toplevel_parent_xml_node(
unique int toplevel: @toplevel ref,
int xmlnode: @xml_node_with_code ref);
@@ -365,7 +365,8 @@ case @expr.kind of
| 116 = @assignlogandexpr
| 117 = @assignlogorexpr
| 118 = @assignnullishcoalescingexpr
| 119 = @angular_pipe_ref
| 119 = @template_pipe_ref
| 120 = @generated_code_expr
;
@varaccess = @proper_varaccess | @export_varaccess;
@@ -416,6 +417,19 @@ case @expr.kind of
@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector;
@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident;
expr_contains_template_tag_location(
int expr: @expr ref,
int location: @location ref
);
@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file;
template_placeholder_tag_info(
unique int node: @template_placeholder_tag,
int parentNode: @template_placeholder_tag_parent ref,
varchar(900) raw: string ref
);
// scopes
scopes (unique int id: @scope,
int kind: int ref);
@@ -979,7 +993,8 @@ case @json_value.kind of
| @jsdoc | @jsdoc_type_expr | @jsdoc_tag
| @yaml_locatable
| @xmllocatable
| @configLocatable;
| @configLocatable
| @template_placeholder_tag;
hasLocation (unique int locatable: @locatable ref,
int location: @location ref);

View File

@@ -50,7 +50,7 @@
<v>3</v>
</e>
<e>
<k>@angular_template_toplevel</k>
<k>@template_toplevel</k>
<v>100</v>
</e>
<e>
@@ -438,7 +438,15 @@
<v>1</v>
</e>
<e>
<k>@angular_pipe_ref</k>
<k>@template_placeholder_tag</k>
<v>100</v>
</e>
<e>
<k>@template_pipe_ref</k>
<v>100</v>
</e>
<e>
<k>@generated_code_expr</k>
<v>100</v>
</e>
<e>
@@ -11658,6 +11666,295 @@
<dependencies/>
</relation>
<relation>
<name>expr_contains_template_tag_location</name>
<cardinality>31</cardinality>
<columnsizes>
<e>
<k>expr</k>
<v>31</v>
</e>
<e>
<k>location</k>
<v>31</v>
</e>
</columnsizes>
<dependencies>
<dep>
<src>expr</src>
<trg>location</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>31</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>location</src>
<trg>expr</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>31</v>
</b>
</bs>
</hist>
</val>
</dep>
</dependencies>
</relation>
<relation>
<name>template_placeholder_tag_info</name>
<cardinality>283</cardinality>
<columnsizes>
<e>
<k>node</k>
<v>283</v>
</e>
<e>
<k>parentNode</k>
<v>92</v>
</e>
<e>
<k>raw</k>
<v>24</v>
</e>
</columnsizes>
<dependencies>
<dep>
<src>node</src>
<trg>parentNode</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>283</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>node</src>
<trg>raw</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>283</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>parentNode</src>
<trg>node</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>49</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>4</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>9</v>
</b>
<b>
<a>5</a>
<b>6</b>
<v>9</v>
</b>
<b>
<a>6</a>
<b>7</b>
<v>4</v>
</b>
<b>
<a>7</a>
<b>8</b>
<v>13</v>
</b>
<b>
<a>9</a>
<b>11</b>
<v>4</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>parentNode</src>
<trg>raw</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>49</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>4</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>9</v>
</b>
<b>
<a>4</a>
<b>5</b>
<v>11</v>
</b>
<b>
<a>5</a>
<b>6</b>
<v>13</v>
</b>
<b>
<a>6</a>
<b>11</b>
<v>6</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>raw</src>
<trg>node</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>2</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>4</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>9</v>
</b>
<b>
<a>4</a>
<b>6</b>
<v>2</v>
</b>
<b>
<a>16</a>
<b>17</b>
<v>2</v>
</b>
<b>
<a>20</a>
<b>26</b>
<v>2</v>
</b>
<b>
<a>34</a>
<b>45</b>
<v>2</v>
</b>
<b>
<a>82</a>
<b>83</b>
<v>1</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>raw</src>
<trg>parentNode</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>2</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>4</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>9</v>
</b>
<b>
<a>4</a>
<b>6</b>
<v>2</v>
</b>
<b>
<a>16</a>
<b>17</b>
<v>2</v>
</b>
<b>
<a>20</a>
<b>26</b>
<v>2</v>
</b>
<b>
<a>34</a>
<b>41</b>
<v>2</v>
</b>
<b>
<a>44</a>
<b>45</b>
<v>1</v>
</b>
</bs>
</hist>
</val>
</dep>
</dependencies>
</relation>
<relation>
<name>scopes</name>
<key>id</key>
<cardinality>118172</cardinality>

View File

@@ -0,0 +1 @@
semmle-extractor-options: --tolerate-parse-errors

View File

@@ -0,0 +1 @@
semmle-extractor-options: --tolerate-parse-errors

View File

@@ -0,0 +1,167 @@
nodes
| app.js:15:30:15:58 | req.que ... tedCode |
| app.js:15:30:15:58 | req.que ... tedCode |
| app.js:17:25:17:48 | req.que ... shSink1 |
| app.js:17:25:17:48 | req.que ... shSink1 |
| app.js:19:35:19:68 | req.que ... rString |
| app.js:19:35:19:68 | req.que ... rString |
| app.js:34:30:34:58 | req.que ... tedCode |
| app.js:34:30:34:58 | req.que ... tedCode |
| app.js:36:25:36:48 | req.que ... shSink1 |
| app.js:36:25:36:48 | req.que ... shSink1 |
| app.js:38:35:38:68 | req.que ... rString |
| app.js:38:35:38:68 | req.que ... rString |
| app.js:53:30:53:58 | req.que ... tedCode |
| app.js:53:30:53:58 | req.que ... tedCode |
| app.js:54:33:54:64 | req.que ... CodeRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw |
| app.js:56:25:56:48 | req.que ... shSink1 |
| app.js:56:25:56:48 | req.que ... shSink1 |
| app.js:58:35:58:68 | req.que ... rString |
| app.js:58:35:58:68 | req.que ... rString |
| app.js:59:38:59:74 | req.que ... ringRaw |
| app.js:59:38:59:74 | req.que ... ringRaw |
| app.js:65:22:65:42 | req.que ... pedHtml |
| app.js:65:22:65:42 | req.que ... pedHtml |
| app.js:66:18:66:34 | req.query.rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml |
| views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> |
| views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> |
| views/angularjs_include.ejs:2:9:2:19 | escapedHtml |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_include.ejs:3:9:3:15 | rawHtml |
| views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> |
| views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> |
| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> |
| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> |
| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode |
| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> |
| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> |
| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 |
| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString |
| views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode |
| views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
| views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
| views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 |
| views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
| views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
| views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString |
| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode |
| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} |
| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} |
| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe |
| views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} |
| views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} |
| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw |
| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json |
| views/njk_sinks.njk:15:49:15:88 | dataInG ... \| safe |
| views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} |
| views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} |
| views/njk_sinks.njk:17:22:17:35 | backslashSink1 |
| views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} |
| views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} |
| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString |
| views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} |
| views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} |
| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe |
edges
| app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode |
| app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode |
| app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 |
| app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 |
| app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString |
| app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString |
| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode |
| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode |
| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 |
| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 |
| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString |
| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString |
| app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode |
| app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode |
| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw |
| app.js:56:25:56:48 | req.que ... shSink1 | views/njk_sinks.njk:17:22:17:35 | backslashSink1 |
| app.js:56:25:56:48 | req.que ... shSink1 | views/njk_sinks.njk:17:22:17:35 | backslashSink1 |
| app.js:58:35:58:68 | req.que ... rString | views/njk_sinks.njk:22:42:22:65 | dataInE ... rString |
| app.js:58:35:58:68 | req.que ... rString | views/njk_sinks.njk:22:42:22:65 | dataInE ... rString |
| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:9:2:19 | escapedHtml |
| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:9:2:19 | escapedHtml |
| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml |
| app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
| views/angularjs_include.ejs:2:9:2:19 | escapedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> |
| views/angularjs_include.ejs:2:9:2:19 | escapedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> |
| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> |
| views/angularjs_sinks.ejs:3:13:3:23 | escapedHtml | views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> |
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> |
| views/ejs_sinks.ejs:13:43:13:61 | dataInGeneratedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> |
| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> |
| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> |
| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
| views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode | views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode | views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 | views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
| views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 | views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
| views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString | views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
| views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString | views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe |
| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} |
| views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} |
| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json |
| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | views/njk_sinks.njk:15:49:15:88 | dataInG ... \| safe |
| views/njk_sinks.njk:15:49:15:88 | dataInG ... \| safe | views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} |
| views/njk_sinks.njk:15:49:15:88 | dataInG ... \| safe | views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} |
| views/njk_sinks.njk:17:22:17:35 | backslashSink1 | views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} |
| views/njk_sinks.njk:17:22:17:35 | backslashSink1 | views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} |
| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} |
| views/njk_sinks.njk:22:42:22:65 | dataInE ... rString | views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} |
| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe |
| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} |
| views/njk_sinks.njk:23:42:23:75 | dataInE ... \| safe | views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} |
#select
| views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> | $@ flows to here and is interpreted by AngularJS, which may evaluate it as code. | app.js:65:22:65:42 | req.que ... pedHtml | User-provided value |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | $@ flows to here and is interpreted by AngularJS, which may evaluate it as code. | app.js:66:18:66:34 | req.query.rawHtml | User-provided value |
| views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | app.js:65:22:65:42 | req.que ... pedHtml | views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> | $@ flows to here and is interpreted by AngularJS, which may evaluate it as code. | app.js:65:22:65:42 | req.que ... pedHtml | User-provided value |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | $@ flows to here and is interpreted by AngularJS, which may evaluate it as code. | app.js:66:18:66:34 | req.query.rawHtml | User-provided value |
| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | $@ flows to here and is interpreted as code. | app.js:15:30:15:58 | req.que ... tedCode | User-provided value |
| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | $@ flows to here and is interpreted as code. | app.js:17:25:17:48 | req.que ... shSink1 | User-provided value |
| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | $@ flows to here and is interpreted as code. | app.js:19:35:19:68 | req.que ... rString | User-provided value |
| views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} | app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} | $@ flows to here and is interpreted as code. | app.js:34:30:34:58 | req.que ... tedCode | User-provided value |
| views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} | app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} | $@ flows to here and is interpreted as code. | app.js:36:25:36:48 | req.que ... shSink1 | User-provided value |
| views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} | app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} | $@ flows to here and is interpreted as code. | app.js:38:35:38:68 | req.que ... rString | User-provided value |
| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | $@ flows to here and is interpreted as code. | app.js:53:30:53:58 | req.que ... tedCode | User-provided value |
| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | $@ flows to here and is interpreted as code. | app.js:54:33:54:64 | req.que ... CodeRaw | User-provided value |
| views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} | app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} | $@ flows to here and is interpreted as code. | app.js:55:37:55:72 | req.que ... JsonRaw | User-provided value |
| views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | app.js:56:25:56:48 | req.que ... shSink1 | views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} | $@ flows to here and is interpreted as code. | app.js:56:25:56:48 | req.que ... shSink1 | User-provided value |
| views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | app.js:58:35:58:68 | req.que ... rString | views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} | $@ flows to here and is interpreted as code. | app.js:58:35:58:68 | req.que ... rString | User-provided value |
| views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} | $@ flows to here and is interpreted as code. | app.js:59:38:59:74 | req.que ... ringRaw | User-provided value |

View File

@@ -0,0 +1 @@
Security/CWE-094/CodeInjection.ql

View File

@@ -0,0 +1,284 @@
nodes
| app.js:8:18:8:34 | req.query.rawHtml |
| app.js:8:18:8:34 | req.query.rawHtml |
| app.js:11:26:11:46 | req.que ... tmlProp |
| app.js:11:26:11:46 | req.que ... tmlProp |
| app.js:14:33:14:64 | req.que ... eralRaw |
| app.js:14:33:14:64 | req.que ... eralRaw |
| app.js:16:33:16:64 | req.que ... CodeRaw |
| app.js:16:33:16:64 | req.que ... CodeRaw |
| app.js:20:38:20:74 | req.que ... ringRaw |
| app.js:20:38:20:74 | req.que ... ringRaw |
| app.js:27:18:27:34 | req.query.rawHtml |
| app.js:27:18:27:34 | req.query.rawHtml |
| app.js:30:26:30:46 | req.que ... tmlProp |
| app.js:30:26:30:46 | req.que ... tmlProp |
| app.js:33:33:33:64 | req.que ... eralRaw |
| app.js:33:33:33:64 | req.que ... eralRaw |
| app.js:35:33:35:64 | req.que ... CodeRaw |
| app.js:35:33:35:64 | req.que ... CodeRaw |
| app.js:39:38:39:74 | req.que ... ringRaw |
| app.js:39:38:39:74 | req.que ... ringRaw |
| app.js:46:18:46:34 | req.query.rawHtml |
| app.js:46:18:46:34 | req.query.rawHtml |
| app.js:49:26:49:46 | req.que ... tmlProp |
| app.js:49:26:49:46 | req.que ... tmlProp |
| app.js:52:33:52:64 | req.que ... eralRaw |
| app.js:52:33:52:64 | req.que ... eralRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw |
| app.js:59:38:59:74 | req.que ... ringRaw |
| app.js:59:38:59:74 | req.que ... ringRaw |
| app.js:66:18:66:34 | req.query.rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml |
| projectA/src/index.js:7:16:7:30 | req.query.sinkA |
| projectA/src/index.js:7:16:7:30 | req.query.sinkA |
| projectA/src/index.js:12:16:12:30 | req.query.sinkA |
| projectA/src/index.js:12:16:12:30 | req.query.sinkA |
| projectA/src/index.js:17:16:17:30 | req.query.sinkA |
| projectA/src/index.js:17:16:17:30 | req.query.sinkA |
| projectA/src/index.js:32:16:32:30 | req.query.sinkA |
| projectA/src/index.js:32:16:32:30 | req.query.sinkA |
| projectA/src/index.js:37:16:37:30 | req.query.sinkA |
| projectA/src/index.js:37:16:37:30 | req.query.sinkA |
| projectA/src/index.js:42:16:42:30 | req.query.sinkA |
| projectA/src/index.js:42:16:42:30 | req.query.sinkA |
| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/main.ejs:2:5:2:9 | sinkA |
| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA |
| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA |
| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> |
| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> |
| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA |
| projectB/src/index.js:8:16:8:30 | req.query.sinkB |
| projectB/src/index.js:8:16:8:30 | req.query.sinkB |
| projectB/src/index.js:13:16:13:30 | req.query.sinkB |
| projectB/src/index.js:13:16:13:30 | req.query.sinkB |
| projectB/src/index.js:18:16:18:30 | req.query.sinkB |
| projectB/src/index.js:18:16:18:30 | req.query.sinkB |
| projectB/src/index.js:33:16:33:30 | req.query.sinkB |
| projectB/src/index.js:33:16:33:30 | req.query.sinkB |
| projectB/src/index.js:38:16:38:30 | req.query.sinkB |
| projectB/src/index.js:38:16:38:30 | req.query.sinkB |
| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/main.ejs:3:5:3:9 | sinkB |
| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB |
| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_include.ejs:3:9:3:15 | rawHtml |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
| views/ejs_include1.ejs:1:5:1:7 | foo |
| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> |
| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> |
| views/ejs_include2.ejs:1:5:1:11 | rawHtml |
| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_sinks.ejs:4:13:4:19 | rawHtml |
| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> |
| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> |
| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp |
| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> |
| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> |
| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw |
| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> |
| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> |
| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw |
| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> |
| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> |
| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw |
| views/ejs_sinks.ejs:24:44:24:50 | rawHtml |
| views/hbs_sinks.hbs:4:9:4:23 | {{{ rawHtml }}} |
| views/hbs_sinks.hbs:4:9:4:23 | {{{ rawHtml }}} |
| views/hbs_sinks.hbs:4:13:4:19 | rawHtml |
| views/hbs_sinks.hbs:7:9:7:34 | {{{ object.rawHtmlProp }}} |
| views/hbs_sinks.hbs:7:9:7:34 | {{{ object.rawHtmlProp }}} |
| views/hbs_sinks.hbs:7:13:7:30 | object.rawHtmlProp |
| views/hbs_sinks.hbs:11:43:11:72 | {{{ dataInStringLiteralRaw }}} |
| views/hbs_sinks.hbs:11:43:11:72 | {{{ dataInStringLiteralRaw }}} |
| views/hbs_sinks.hbs:11:47:11:68 | dataInS ... eralRaw |
| views/hbs_sinks.hbs:14:42:14:71 | {{{ dataInGeneratedCodeRaw }}} |
| views/hbs_sinks.hbs:14:42:14:71 | {{{ dataInGeneratedCodeRaw }}} |
| views/hbs_sinks.hbs:14:46:14:67 | dataInG ... CodeRaw |
| views/hbs_sinks.hbs:22:39:22:73 | {{{ dataInEventHandlerStringRaw }}} |
| views/hbs_sinks.hbs:22:39:22:73 | {{{ dataInEventHandlerStringRaw }}} |
| views/hbs_sinks.hbs:22:43:22:69 | dataInE ... ringRaw |
| views/njk_sinks.njk:4:12:4:18 | rawHtml |
| views/njk_sinks.njk:4:12:4:18 | rawHtml |
| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp |
| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp |
| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw |
| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw |
| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw |
| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json |
| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json |
| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
edges
| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:5:1:11 | rawHtml |
| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:5:1:11 | rawHtml |
| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:13:4:19 | rawHtml |
| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:13:4:19 | rawHtml |
| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:24:44:24:50 | rawHtml |
| app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:24:44:24:50 | rawHtml |
| app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp |
| app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp |
| app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw |
| app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw |
| app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw |
| app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw |
| app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw |
| app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw |
| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:4:13:4:19 | rawHtml |
| app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:4:13:4:19 | rawHtml |
| app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:7:13:7:30 | object.rawHtmlProp |
| app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:7:13:7:30 | object.rawHtmlProp |
| app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:11:47:11:68 | dataInS ... eralRaw |
| app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:11:47:11:68 | dataInS ... eralRaw |
| app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:14:46:14:67 | dataInG ... CodeRaw |
| app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:14:46:14:67 | dataInG ... CodeRaw |
| app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:22:43:22:69 | dataInE ... ringRaw |
| app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:22:43:22:69 | dataInE ... ringRaw |
| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml |
| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml |
| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml |
| app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml |
| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp |
| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp |
| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp |
| app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp |
| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw |
| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw |
| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw |
| app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw |
| app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw |
| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:9:3:15 | rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
| projectA/src/index.js:7:16:7:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:7:16:7:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:32:16:32:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:32:16:32:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA |
| projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA |
| projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA |
| projectA/views/main.ejs:2:5:2:9 | sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/main.ejs:2:5:2:9 | sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/index.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/other.ejs:2:5:2:9 | sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> |
| projectA/views/upward_traversal.ejs:1:5:1:9 | sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> |
| projectB/src/index.js:8:16:8:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:8:16:8:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:33:16:33:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:33:16:33:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB |
| projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB |
| projectB/views/main.ejs:3:5:3:9 | sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/main.ejs:3:5:3:9 | sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/index.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/other.ejs:3:5:3:9 | sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> |
| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_include.ejs:3:9:3:15 | rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
| views/ejs_include2.ejs:1:5:1:11 | rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> |
| views/ejs_include2.ejs:1:5:1:11 | rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> |
| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_sinks.ejs:4:13:4:19 | rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> |
| views/ejs_sinks.ejs:7:13:7:30 | object.rawHtmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> |
| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> |
| views/ejs_sinks.ejs:11:47:11:68 | dataInS ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> |
| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> |
| views/ejs_sinks.ejs:14:46:14:67 | dataInG ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> |
| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> |
| views/ejs_sinks.ejs:22:43:22:69 | dataInE ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> |
| views/ejs_sinks.ejs:24:44:24:50 | rawHtml | views/ejs_include1.ejs:1:5:1:7 | foo |
| views/hbs_sinks.hbs:4:13:4:19 | rawHtml | views/hbs_sinks.hbs:4:9:4:23 | {{{ rawHtml }}} |
| views/hbs_sinks.hbs:4:13:4:19 | rawHtml | views/hbs_sinks.hbs:4:9:4:23 | {{{ rawHtml }}} |
| views/hbs_sinks.hbs:7:13:7:30 | object.rawHtmlProp | views/hbs_sinks.hbs:7:9:7:34 | {{{ object.rawHtmlProp }}} |
| views/hbs_sinks.hbs:7:13:7:30 | object.rawHtmlProp | views/hbs_sinks.hbs:7:9:7:34 | {{{ object.rawHtmlProp }}} |
| views/hbs_sinks.hbs:11:47:11:68 | dataInS ... eralRaw | views/hbs_sinks.hbs:11:43:11:72 | {{{ dataInStringLiteralRaw }}} |
| views/hbs_sinks.hbs:11:47:11:68 | dataInS ... eralRaw | views/hbs_sinks.hbs:11:43:11:72 | {{{ dataInStringLiteralRaw }}} |
| views/hbs_sinks.hbs:14:46:14:67 | dataInG ... CodeRaw | views/hbs_sinks.hbs:14:42:14:71 | {{{ dataInGeneratedCodeRaw }}} |
| views/hbs_sinks.hbs:14:46:14:67 | dataInG ... CodeRaw | views/hbs_sinks.hbs:14:42:14:71 | {{{ dataInGeneratedCodeRaw }}} |
| views/hbs_sinks.hbs:22:43:22:69 | dataInE ... ringRaw | views/hbs_sinks.hbs:22:39:22:73 | {{{ dataInEventHandlerStringRaw }}} |
| views/hbs_sinks.hbs:22:43:22:69 | dataInE ... ringRaw | views/hbs_sinks.hbs:22:39:22:73 | {{{ dataInEventHandlerStringRaw }}} |
| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json |
| views/njk_sinks.njk:15:49:15:74 | dataInG ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json |
#select
| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:7:16:7:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:7:16:7:30 | req.query.sinkA | user-provided value |
| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:12:16:12:30 | req.query.sinkA | projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:12:16:12:30 | req.query.sinkA | user-provided value |
| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:17:16:17:30 | req.query.sinkA | projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:17:16:17:30 | req.query.sinkA | user-provided value |
| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:32:16:32:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:32:16:32:30 | req.query.sinkA | user-provided value |
| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | projectA/src/index.js:37:16:37:30 | req.query.sinkA | projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:37:16:37:30 | req.query.sinkA | user-provided value |
| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | projectA/src/index.js:42:16:42:30 | req.query.sinkA | projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> | Cross-site scripting vulnerability due to $@. | projectA/src/index.js:42:16:42:30 | req.query.sinkA | user-provided value |
| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:8:16:8:30 | req.query.sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:8:16:8:30 | req.query.sinkB | user-provided value |
| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:13:16:13:30 | req.query.sinkB | projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:13:16:13:30 | req.query.sinkB | user-provided value |
| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:18:16:18:30 | req.query.sinkB | projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:18:16:18:30 | req.query.sinkB | user-provided value |
| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:33:16:33:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:33:16:33:30 | req.query.sinkB | user-provided value |
| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:38:16:38:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:38:16:38:30 | req.query.sinkB | user-provided value |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:66:18:66:34 | req.query.rawHtml | user-provided value |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:66:18:66:34 | req.query.rawHtml | user-provided value |
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value |
| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value |
| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value |
| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | app.js:11:26:11:46 | req.que ... tmlProp | views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> | Cross-site scripting vulnerability due to $@. | app.js:11:26:11:46 | req.que ... tmlProp | user-provided value |
| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | app.js:14:33:14:64 | req.que ... eralRaw | views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> | Cross-site scripting vulnerability due to $@. | app.js:14:33:14:64 | req.que ... eralRaw | user-provided value |
| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | app.js:16:33:16:64 | req.que ... CodeRaw | views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> | Cross-site scripting vulnerability due to $@. | app.js:16:33:16:64 | req.que ... CodeRaw | user-provided value |
| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | app.js:20:38:20:74 | req.que ... ringRaw | views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> | Cross-site scripting vulnerability due to $@. | app.js:20:38:20:74 | req.que ... ringRaw | user-provided value |
| views/hbs_sinks.hbs:4:9:4:23 | {{{ rawHtml }}} | app.js:27:18:27:34 | req.query.rawHtml | views/hbs_sinks.hbs:4:9:4:23 | {{{ rawHtml }}} | Cross-site scripting vulnerability due to $@. | app.js:27:18:27:34 | req.query.rawHtml | user-provided value |
| views/hbs_sinks.hbs:7:9:7:34 | {{{ object.rawHtmlProp }}} | app.js:30:26:30:46 | req.que ... tmlProp | views/hbs_sinks.hbs:7:9:7:34 | {{{ object.rawHtmlProp }}} | Cross-site scripting vulnerability due to $@. | app.js:30:26:30:46 | req.que ... tmlProp | user-provided value |
| views/hbs_sinks.hbs:11:43:11:72 | {{{ dataInStringLiteralRaw }}} | app.js:33:33:33:64 | req.que ... eralRaw | views/hbs_sinks.hbs:11:43:11:72 | {{{ dataInStringLiteralRaw }}} | Cross-site scripting vulnerability due to $@. | app.js:33:33:33:64 | req.que ... eralRaw | user-provided value |
| views/hbs_sinks.hbs:14:42:14:71 | {{{ dataInGeneratedCodeRaw }}} | app.js:35:33:35:64 | req.que ... CodeRaw | views/hbs_sinks.hbs:14:42:14:71 | {{{ dataInGeneratedCodeRaw }}} | Cross-site scripting vulnerability due to $@. | app.js:35:33:35:64 | req.que ... CodeRaw | user-provided value |
| views/hbs_sinks.hbs:22:39:22:73 | {{{ dataInEventHandlerStringRaw }}} | app.js:39:38:39:74 | req.que ... ringRaw | views/hbs_sinks.hbs:22:39:22:73 | {{{ dataInEventHandlerStringRaw }}} | Cross-site scripting vulnerability due to $@. | app.js:39:38:39:74 | req.que ... ringRaw | user-provided value |
| views/njk_sinks.njk:4:12:4:18 | rawHtml | app.js:46:18:46:34 | req.query.rawHtml | views/njk_sinks.njk:4:12:4:18 | rawHtml | Cross-site scripting vulnerability due to $@. | app.js:46:18:46:34 | req.query.rawHtml | user-provided value |
| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | app.js:49:26:49:46 | req.que ... tmlProp | views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp | Cross-site scripting vulnerability due to $@. | app.js:49:26:49:46 | req.que ... tmlProp | user-provided value |
| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | app.js:52:33:52:64 | req.que ... eralRaw | views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw | Cross-site scripting vulnerability due to $@. | app.js:52:33:52:64 | req.que ... eralRaw | user-provided value |
| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | Cross-site scripting vulnerability due to $@. | app.js:54:33:54:64 | req.que ... CodeRaw | user-provided value |
| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json | Cross-site scripting vulnerability due to $@. | app.js:55:37:55:72 | req.que ... JsonRaw | user-provided value |
| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | app.js:59:38:59:74 | req.que ... ringRaw | views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw | Cross-site scripting vulnerability due to $@. | app.js:59:38:59:74 | req.que ... ringRaw | user-provided value |

View File

@@ -0,0 +1 @@
Security/CWE-079/Xss.ql

View File

@@ -0,0 +1,68 @@
const express = require('express');
let app = express();
app.get('/ejs', (req, res) => {
res.render('ejs_sinks', {
escapedHtml: req.query.escapedHtml,
rawHtml: req.query.rawHtml,
rawHtmlSafeValue: 'safe',
object: {
rawHtmlProp: req.query.rawHtmlProp
},
dataInStringLiteral: req.query.dataInStringLiteral,
dataInStringLiteralRaw: req.query.dataInStringLiteralRaw,
dataInGeneratedCode: req.query.dataInGeneratedCode,
dataInGeneratedCodeRaw: req.query.dataInGeneratedCodeRaw,
backslashSink1: req.query.backslashSink1,
backslashSink2: req.query.backslashSink2,
dataInEventHandlerString: req.query.dataInEventHandlerString,
dataInEventHandlerStringRaw: req.query.dataInEventHandlerStringRaw,
});
});
app.get('/hbs', (req, res) => {
res.render('hbs_sinks', {
escapedHtml: req.query.escapedHtml,
rawHtml: req.query.rawHtml,
rawHtmlSafeValue: 'safe',
object: {
rawHtmlProp: req.query.rawHtmlProp
},
dataInStringLiteral: req.query.dataInStringLiteral,
dataInStringLiteralRaw: req.query.dataInStringLiteralRaw,
dataInGeneratedCode: req.query.dataInGeneratedCode,
dataInGeneratedCodeRaw: req.query.dataInGeneratedCodeRaw,
backslashSink1: req.query.backslashSink1,
backslashSink2: req.query.backslashSink2,
dataInEventHandlerString: req.query.dataInEventHandlerString,
dataInEventHandlerStringRaw: req.query.dataInEventHandlerStringRaw,
});
});
app.get('/njk', (req, res) => {
res.render('njk_sinks', {
escapedHtml: req.query.escapedHtml,
rawHtml: req.query.rawHtml,
rawHtmlSafeValue: 'safe',
object: {
rawHtmlProp: req.query.rawHtmlProp
},
dataInStringLiteral: req.query.dataInStringLiteral,
dataInStringLiteralRaw: req.query.dataInStringLiteralRaw,
dataInGeneratedCode: req.query.dataInGeneratedCode,
dataInGeneratedCodeRaw: req.query.dataInGeneratedCodeRaw,
dataInGeneratedCodeJsonRaw: req.query.dataInGeneratedCodeJsonRaw,
backslashSink1: req.query.backslashSink1,
backslashSink2: req.query.backslashSink2,
dataInEventHandlerString: req.query.dataInEventHandlerString,
dataInEventHandlerStringRaw: req.query.dataInEventHandlerStringRaw,
});
});
app.get('/angularjs', (req, res) => {
res.render('angularjs_sinks', {
escapedHtml: req.query.escapedHtml,
rawHtml: req.query.rawHtml,
});
});

View File

@@ -0,0 +1,4 @@
import * as consolidate from 'consolidate';
consolidate.ejs('views/instantiated_as_ejs.html', { data: 123 }, (err, html) => {});
consolidate.handlebars('views/instantiated_as_hbs.html', { data: 123 }, (err, html) => {});

View File

@@ -0,0 +1,45 @@
const express = require('express');
const app = express();
app.get('/fooA', (req, res) => {
res.render('main', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('main.ejs', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/index', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/index.ejs', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/other', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/other.ejs', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/subsub', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
});

View File

@@ -0,0 +1,3 @@
Project A
<%- sinkA %>
<%= sinkB %>

View File

@@ -0,0 +1,3 @@
Subfolder/index
<%- sinkA %>
<%= sinkB %>

View File

@@ -0,0 +1,3 @@
Subfolder/other
<%- sinkA %>
<%= sinkB %>

View File

@@ -0,0 +1 @@
<% include ../../upward_traversal %>

View File

@@ -0,0 +1,2 @@
<%- sinkA %>
<%= sinkB %>

View File

@@ -0,0 +1,40 @@
const express = require('express');
const app = express();
app.get('/fooA', (req, res) => {
res.render('main', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('main.ejs', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/index', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/index.ejs', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/other', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
res.render('subfolder/other.ejs', {
sinkA: req.query.sinkA,
sinkB: req.query.sinkB,
});
});

View File

@@ -0,0 +1,3 @@
Project B
<%= sinkA %>
<%- sinkB %>

View File

@@ -0,0 +1,3 @@
Subfolder/index
<%= sinkA %>
<%- sinkB %>

View File

@@ -0,0 +1,3 @@
Subfolder/other
<%= sinkA %>
<%- sinkB %>

View File

@@ -0,0 +1,92 @@
getTemplateInstantiationSyntax
| consolidate.js:3:1:3:83 | consoli ... => {}) | ejs |
| consolidate.js:4:1:4:90 | consoli ... => {}) | mustache |
getLikelyTemplateSyntax
| projectA/views/main.ejs:0:0:0:0 | projectA/views/main.ejs | ejs |
| projectA/views/subfolder/index.ejs:0:0:0:0 | projectA/views/subfolder/index.ejs | ejs |
| projectA/views/subfolder/other.ejs:0:0:0:0 | projectA/views/subfolder/other.ejs | ejs |
| projectA/views/subfolder/subsub/index.ejs:0:0:0:0 | projectA/views/subfolder/subsub/index.ejs | ejs |
| projectA/views/upward_traversal.ejs:0:0:0:0 | projectA/views/upward_traversal.ejs | ejs |
| projectB/views/main.ejs:0:0:0:0 | projectB/views/main.ejs | ejs |
| projectB/views/subfolder/index.ejs:0:0:0:0 | projectB/views/subfolder/index.ejs | ejs |
| projectB/views/subfolder/other.ejs:0:0:0:0 | projectB/views/subfolder/other.ejs | ejs |
| views/angularjs_include.ejs:0:0:0:0 | views/angularjs_include.ejs | ejs |
| views/angularjs_sinks.ejs:0:0:0:0 | views/angularjs_sinks.ejs | ejs |
| views/ejs_include1.ejs:0:0:0:0 | views/ejs_include1.ejs | ejs |
| views/ejs_include2.ejs:0:0:0:0 | views/ejs_include2.ejs | ejs |
| views/ejs_sinks.ejs:0:0:0:0 | views/ejs_sinks.ejs | ejs |
| views/hbs_sinks.hbs:0:0:0:0 | views/hbs_sinks.hbs | mustache |
| views/instantiated_as_ejs.html:0:0:0:0 | views/instantiated_as_ejs.html | ejs |
| views/instantiated_as_hbs.html:0:0:0:0 | views/instantiated_as_hbs.html | mustache |
| views/njk_sinks.njk:0:0:0:0 | views/njk_sinks.njk | mustache |
getTargetFile
| app.js:6:5:21:6 | res.ren ... \\n }) | views/ejs_sinks.ejs:0:0:0:0 | views/ejs_sinks.ejs |
| app.js:25:5:40:6 | res.ren ... \\n }) | views/hbs_sinks.hbs:0:0:0:0 | views/hbs_sinks.hbs |
| app.js:44:5:60:6 | res.ren ... \\n }) | views/njk_sinks.njk:0:0:0:0 | views/njk_sinks.njk |
| app.js:64:5:67:6 | res.ren ... \\n }) | views/angularjs_sinks.ejs:0:0:0:0 | views/angularjs_sinks.ejs |
| consolidate.js:3:1:3:83 | consoli ... => {}) | views/instantiated_as_ejs.html:0:0:0:0 | views/instantiated_as_ejs.html |
| consolidate.js:4:1:4:90 | consoli ... => {}) | views/instantiated_as_hbs.html:0:0:0:0 | views/instantiated_as_hbs.html |
| projectA/src/index.js:6:5:9:6 | res.ren ... \\n }) | projectA/views/main.ejs:0:0:0:0 | projectA/views/main.ejs |
| projectA/src/index.js:11:5:14:6 | res.ren ... \\n }) | projectA/views/main.ejs:0:0:0:0 | projectA/views/main.ejs |
| projectA/src/index.js:16:5:19:6 | res.ren ... \\n }) | projectA/views/subfolder/index.ejs:0:0:0:0 | projectA/views/subfolder/index.ejs |
| projectA/src/index.js:31:5:34:6 | res.ren ... \\n }) | projectA/views/subfolder/other.ejs:0:0:0:0 | projectA/views/subfolder/other.ejs |
| projectA/src/index.js:36:5:39:6 | res.ren ... \\n }) | projectA/views/subfolder/other.ejs:0:0:0:0 | projectA/views/subfolder/other.ejs |
| projectA/src/index.js:41:5:44:6 | res.ren ... \\n }) | projectA/views/subfolder/subsub/index.ejs:0:0:0:0 | projectA/views/subfolder/subsub/index.ejs |
| projectB/src/index.js:6:5:9:6 | res.ren ... \\n }) | projectB/views/main.ejs:0:0:0:0 | projectB/views/main.ejs |
| projectB/src/index.js:11:5:14:6 | res.ren ... \\n }) | projectB/views/main.ejs:0:0:0:0 | projectB/views/main.ejs |
| projectB/src/index.js:16:5:19:6 | res.ren ... \\n }) | projectB/views/subfolder/index.ejs:0:0:0:0 | projectB/views/subfolder/index.ejs |
| projectB/src/index.js:31:5:34:6 | res.ren ... \\n }) | projectB/views/subfolder/other.ejs:0:0:0:0 | projectB/views/subfolder/other.ejs |
| projectB/src/index.js:36:5:39:6 | res.ren ... \\n }) | projectB/views/subfolder/other.ejs:0:0:0:0 | projectB/views/subfolder/other.ejs |
| views/ejs_sinks.ejs:24:13:24:53 | include ... Html }) | views/ejs_include1.ejs:0:0:0:0 | views/ejs_include1.ejs |
xssSink
| projectA/views/main.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/index.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/subfolder/other.ejs:2:1:2:12 | <%- sinkA %> |
| projectA/views/upward_traversal.ejs:1:1:1:12 | <%- sinkA %> |
| projectB/views/main.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/index.ejs:3:1:3:12 | <%- sinkB %> |
| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> |
| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/ejs_sinks.ejs:5:9:5:31 | <%- rawHtmlSafeValue %> |
| views/ejs_sinks.ejs:7:9:7:33 | <%- object.rawHtmlProp %> |
| views/ejs_sinks.ejs:11:43:11:71 | <%- dataInStringLiteralRaw %> |
| views/ejs_sinks.ejs:14:42:14:70 | <%- dataInGeneratedCodeRaw %> |
| views/ejs_sinks.ejs:22:39:22:72 | <%- dataInEventHandlerStringRaw %> |
| views/ejs_sinks.ejs:24:9:24:57 | <%- include('ejs_include1', { foo: rawHtml }) _%> |
| views/hbs_sinks.hbs:4:9:4:23 | {{{ rawHtml }}} |
| views/hbs_sinks.hbs:5:9:5:32 | {{{ rawHtmlSafeValue }}} |
| views/hbs_sinks.hbs:7:9:7:34 | {{{ object.rawHtmlProp }}} |
| views/hbs_sinks.hbs:11:43:11:72 | {{{ dataInStringLiteralRaw }}} |
| views/hbs_sinks.hbs:14:42:14:71 | {{{ dataInGeneratedCodeRaw }}} |
| views/hbs_sinks.hbs:22:39:22:73 | {{{ dataInEventHandlerStringRaw }}} |
| views/instantiated_as_ejs.html:4:9:4:23 | <%- xss_sink %> |
| views/instantiated_as_hbs.html:7:9:7:24 | {{{ xss_sink }}} |
| views/njk_sinks.njk:4:12:4:18 | rawHtml |
| views/njk_sinks.njk:5:12:5:27 | rawHtmlSafeValue |
| views/njk_sinks.njk:7:12:7:29 | object.rawHtmlProp |
| views/njk_sinks.njk:11:46:11:67 | dataInS ... eralRaw |
| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
| views/njk_sinks.njk:15:49:15:81 | dataInG ... \| json |
| views/njk_sinks.njk:23:42:23:68 | dataInE ... ringRaw |
codeInjectionSink
| views/angularjs_include.ejs:2:5:2:22 | <%= escapedHtml %> |
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:3:9:3:26 | <%= escapedHtml %> |
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
| views/angularjs_sinks.ejs:6:9:6:39 | <% include angularjs_include %> |
| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> |
| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> |
| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
| views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
| views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} |
| views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} |
| views/njk_sinks.njk:17:19:17:38 | {{ backslashSink1 }} |
| views/njk_sinks.njk:22:39:22:68 | {{ dataInEventHandlerString }} |
| views/njk_sinks.njk:23:39:23:78 | {{ dataInEventHandlerStringRaw \| safe }} |

View File

@@ -0,0 +1,21 @@
import javascript
import semmle.javascript.security.dataflow.Xss
import semmle.javascript.security.dataflow.CodeInjectionCustomizations
query Templating::TemplateSyntax getTemplateInstantiationSyntax(
Templating::TemplateInstantiation inst
) {
result = inst.getTemplateSyntax()
}
query Templating::TemplateSyntax getLikelyTemplateSyntax(Templating::TemplateFile file) {
result = Templating::getLikelyTemplateSyntax(file)
}
query Templating::TemplateFile getTargetFile(Templating::TemplateInstantiation inst) {
result = inst.getTemplateFile()
}
query DomBasedXss::Sink xssSink() { any() }
query CodeInjection::Sink codeInjectionSink() { any() }

View File

@@ -0,0 +1,5 @@
<div>
<%= escapedHtml %>
<%- rawHtml %>
</div>
<div ng-click="blah()"></div>

View File

@@ -0,0 +1,8 @@
<html>
<body ng-app="foo">
<%= escapedHtml %>
<%- rawHtml %>
<% include angularjs_include %>
</body>
</html>

View File

@@ -0,0 +1 @@
<%- foo %>

View File

@@ -0,0 +1 @@
<%- rawHtml %>

View File

@@ -0,0 +1,27 @@
<html>
<body>
<%= escapedHtml %>
<%- rawHtml %>
<%- rawHtmlSafeValue %>
<%- object.rawHtmlProp %>
<script>
var dataInStringLiteral = "<%= dataInStringLiteral %>";
var dataInStringLiteralRaw = "<%- dataInStringLiteralRaw %>";
var dataInGeneratedCode = <%= dataInGeneratedCode %>;
var dataInGeneratedCodeRaw = <%- dataInGeneratedCodeRaw %>;
init("<%= backslashSink1 %>", "<%= backslashSink2 %>");
var mustache = "{{ rawHtml }}";
</script>
<button onclick="doSomething('<%= dataInEventHandlerString %>')">Click me</button>
<button onclick="doSomething('<%- dataInEventHandlerStringRaw %>')">Click me</button>
<%- include('ejs_include1', { foo: rawHtml }) _%>
<% include ejs_include2 %>
</body>
</html>

View File

@@ -0,0 +1,24 @@
<html>
<body>
{{ escapedHtml }}
{{{ rawHtml }}}
{{{ rawHtmlSafeValue }}}
{{{ object.rawHtmlProp }}}
<script>
var dataInStringLiteral = "{{ dataInStringLiteral }}";
var dataInStringLiteralRaw = "{{{ dataInStringLiteralRaw }}}";
var dataInGeneratedCode = {{ dataInGeneratedCode }};
var dataInGeneratedCodeRaw = {{{ dataInGeneratedCodeRaw }}};
init("{{ backslashSink1 }}", "{{ backslashSink2 }}");
var ejs = "<%= rawHtml %>";
</script>
<button onclick="doSomething('{{ dataInEventHandlerString }}')">Click me</button>
<button onclick="doSomething('{{{ dataInEventHandlerStringRaw }}}')">Click me</button>
</body>
</html>

View File

@@ -0,0 +1,9 @@
<html>
<body>
<%= safe %>
<%- xss_sink %>
{{ safe }}
{{{ safe }}}
</body>
</html>

View File

@@ -0,0 +1,9 @@
<html>
<body>
<%= safe %>
<%- safe %>
{{ safe }}
{{{ xss_sink }}}
</body>
</html>

View File

@@ -0,0 +1,25 @@
<html>
<body>
{{ escapedHtml }}
{{ rawHtml | safe }}
{{ rawHtmlSafeValue | safe }}
{{ object.rawHtmlProp | safe }}
<script>
var dataInStringLiteral = "{{ dataInStringLiteral }}";
var dataInStringLiteralRaw = "{{ dataInStringLiteralRaw | safe }}";
var dataInGeneratedCode = {{ dataInGeneratedCode }};
var dataInGeneratedCodeRaw = {{ dataInGeneratedCodeRaw | safe }};
var dataInGeneratedCodeJsonRaw = {{ dataInGeneratedCodeJsonRaw | json | safe }};
init("{{ backslashSink1 }}", "{{ backslashSink2 }}");
var ejs = "<%= rawHtml %>";
</script>
<button onclick="doSomething('{{ dataInEventHandlerString }}')">Click me</button>
<button onclick="doSomething('{{ dataInEventHandlerStringRaw | safe }}')">Click me</button>
</body>
</html>

View File

@@ -1 +1 @@
semmle-extractor-options: --html elements
semmle-extractor-options: --html elements --tolerate-parse-errors

View File

@@ -0,0 +1 @@
semmle-extractor-options: --tolerate-parse-errors

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: add support for templating langauges
compatibility: backwards