JavaScript: Factor out HTML extractor

This commit is contained in:
Sauyon Lee
2020-11-27 09:33:57 -08:00
parent bc340e210b
commit 17e450f227
12 changed files with 499 additions and 718 deletions

View File

@@ -9,6 +9,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import com.semmle.extractor.html.HtmlPopulator;
import com.semmle.js.parser.JcornWrapper;
import com.semmle.util.data.StringUtil;
import com.semmle.util.exception.UserError;
@@ -146,42 +147,6 @@ public class ExtractorConfig {
}
}
/** How to handle HTML files. */
public static enum HTMLHandling {
/** Only extract embedded scripts, not the HTML itself. */
SCRIPTS(false, false),
/** Only extract elements and embedded scripts, not text. */
ELEMENTS(true, false),
/** Extract elements, embedded scripts, and text. */
ALL(true, true);
private final boolean extractElements;
private final boolean extractText;
private HTMLHandling(boolean extractElements, boolean extractText) {
this.extractElements = extractElements;
this.extractText = extractText;
}
public boolean extractElements() {
return extractElements;
}
public boolean extractText() {
return extractText;
}
public boolean extractComments() {
return extractElements;
}
@Override
public String toString() {
return StringUtil.lc(name());
}
}
/** Which language version is the source code parsed as? */
private ECMAVersion ecmaVersion;
@@ -213,7 +178,7 @@ public class ExtractorConfig {
private boolean tolerateParseErrors;
/** How should HTML files be extracted? */
private HTMLHandling htmlHandling;
private HtmlPopulator.Config htmlHandling;
/**
* Which {@link FileExtractor.FileType} should this code be parsed as?
@@ -244,7 +209,7 @@ public class ExtractorConfig {
this.platform = Platform.AUTO;
this.jsx = true;
this.sourceType = SourceType.AUTO;
this.htmlHandling = HTMLHandling.ELEMENTS;
this.htmlHandling = HtmlPopulator.Config.ELEMENTS;
this.tolerateParseErrors = true;
if (experimental) {
this.mozExtensions = true;
@@ -403,11 +368,11 @@ public class ExtractorConfig {
return res;
}
public HTMLHandling getHtmlHandling() {
public HtmlPopulator.Config getHtmlHandling() {
return htmlHandling;
}
public ExtractorConfig withHtmlHandling(HTMLHandling htmlHandling) {
public ExtractorConfig withHtmlHandling(HtmlPopulator.Config htmlHandling) {
ExtractorConfig res = new ExtractorConfig(this);
res.htmlHandling = htmlHandling;
return res;

View File

@@ -4,423 +4,239 @@ import java.io.File;
import java.nio.file.Path;
import java.util.regex.Pattern;
import com.semmle.extractor.html.HtmlPopulator;
import com.semmle.js.extractor.ExtractorConfig.Platform;
import com.semmle.js.extractor.ExtractorConfig.SourceType;
import com.semmle.js.parser.ParseError;
import com.semmle.util.data.Option;
import com.semmle.util.data.StringUtil;
import com.semmle.util.io.WholeIO;
import com.semmle.util.trap.TrapWriter;
import com.semmle.util.trap.TrapWriter.Label;
import net.htmlparser.jericho.Attribute;
import net.htmlparser.jericho.Attributes;
import net.htmlparser.jericho.CharacterReference;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.RowColumnVector;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;
import net.htmlparser.jericho.StartTagType;
/** Extractor for handling HTML and XHTML files. */
public class HTMLExtractor implements IExtractor {
/** List of HTML attributes whose value is interpreted as JavaScript. */
private static final Pattern JS_ATTRIBUTE =
Pattern.compile(
"^on(abort|blur|change|(dbl)?click|error|focus|key(down|press|up)|load|mouse(down|move|out|over|up)|re(set|size)|select|submit|unload)$",
Pattern.CASE_INSENSITIVE);
private class JavaScriptHTMLElementHandler implements HtmlPopulator.ElementHandler {
private final ScopeManager scopeManager;
private final TextualExtractor textualExtractor;
private LoCInfo locInfo;
private final ExtractorConfig config;
private final ExtractorState state;
public JavaScriptHTMLElementHandler(TextualExtractor textualExtractor) {
this.textualExtractor = textualExtractor;
public HTMLExtractor(ExtractorConfig config, ExtractorState state) {
this.config = config.withPlatform(Platform.WEB);
this.state = state;
}
this.locInfo = new LoCInfo(0, 0);
@Override
public LoCInfo extract(TextualExtractor textualExtractor) {
LoCInfo result = new LoCInfo(0, 0);
this.scopeManager = new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion());
}
Source src = new Source(textualExtractor.getSource());
src.setLogger(null);
ScopeManager scopeManager =
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion());
/*
* Extract all JavaScript snippets appearing in (in-line) script elements and as
* attribute values.
*/
@Override
public void handleElement(Element elt) {
LoCInfo snippetLoC = null;
if (elt.getName().equals(HTMLElementName.SCRIPT)) {
SourceType sourceType = getScriptSourceType(elt, textualExtractor.getExtractedFile());
if (sourceType != null) {
// Jericho sometimes misparses empty elements, which will show up as start tags
// ending in "/"; we manually exclude these cases to avoid spurious syntax
// errors
if (elt.getStartTag().getTagContent().toString().trim().endsWith("/"))
return;
LocationManager locationManager = textualExtractor.getLocationManager();
Segment content = elt.getContent();
String source = content.toString();
boolean isTypeScript = isTypeScriptTag(elt);
/*
* Extract all JavaScript snippets appearing in (in-line) script elements and
* as attribute values.
*/
for (Element elt : src.getAllElements()) {
LoCInfo snippetLoC = null;
if (elt.getName().equals(HTMLElementName.SCRIPT)) {
SourceType sourceType = getScriptSourceType(elt, textualExtractor.getExtractedFile());
if (sourceType != null) {
// Jericho sometimes misparses empty elements, which will show up as start tags
// ending in "/"; we manually exclude these cases to avoid spurious syntax errors
if (elt.getStartTag().getTagContent().toString().trim().endsWith("/")) continue;
/*
* Script blocks in XHTML files may wrap (parts of) their code inside CDATA
* sections. We need to unwrap them in order not to confuse the JavaScript
* parser.
*
* Note that CDATA sections do not nest, so they can be detected by a regular
* expression.
*
* In order to preserve position information, we replace the CDATA section
* markers with an equivalent number of whitespace characters. This will yield
* surprising results for CDATA sections inside string literals, but those are
* likely to be rare.
*/
source = source.replace("<![CDATA[", " ").replace("]]>", " ");
if (!source.trim().isEmpty()) {
RowColumnVector contentStart = content.getRowColumnVector();
snippetLoC = extractSnippet(1, config.withSourceType(sourceType), scopeManager,
textualExtractor, source, contentStart.getRow(), contentStart.getColumn(),
isTypeScript);
}
}
} else {
Attributes attributes = elt.getAttributes();
// attributes can be null for directives
if (attributes != null)
for (Attribute attr : attributes) {
// ignore empty attributes
if (attr.getValue() == null || attr.getValue().isEmpty())
continue;
Segment content = elt.getContent();
String source = content.toString();
boolean isTypeScript = isTypeScriptTag(elt);
String source = attr.getValue();
RowColumnVector valueStart = attr.getValueSegment().getRowColumnVector();
if (JS_ATTRIBUTE.matcher(attr.getName()).matches()) {
snippetLoC = extractSnippet(2, config, scopeManager, textualExtractor, source,
valueStart.getRow(), valueStart.getColumn(), false /* isTypeScript */);
} else if (source.startsWith("javascript:")) {
source = source.substring(11);
snippetLoC = extractSnippet(3, config, scopeManager, textualExtractor, source,
valueStart.getRow(), valueStart.getColumn() + 11, false /* isTypeScript */);
}
}
}
/*
* Script blocks in XHTML files may wrap (parts of) their code inside CDATA sections.
* We need to unwrap them in order not to confuse the JavaScript parser.
*
* Note that CDATA sections do not nest, so they can be detected by a regular expression.
*
* In order to preserve position information, we replace the CDATA section markers with
* an equivalent number of whitespace characters. This will yield surprising results
* for CDATA sections inside string literals, but those are likely to be rare.
*/
source = source.replace("<![CDATA[", " ").replace("]]>", " ");
if (!source.trim().isEmpty()) {
RowColumnVector contentStart = content.getRowColumnVector();
snippetLoC =
extractSnippet(
1,
config.withSourceType(sourceType),
scopeManager,
textualExtractor,
source,
contentStart.getRow(),
contentStart.getColumn(),
isTypeScript);
}
}
} else {
Attributes attributes = elt.getAttributes();
// attributes can be null for directives
if (attributes != null)
for (Attribute attr : attributes) {
// ignore empty attributes
if (attr.getValue() == null || attr.getValue().isEmpty()) continue;
if (snippetLoC != null)
locInfo.add(snippetLoC);
}
String source = attr.getValue();
RowColumnVector valueStart = attr.getValueSegment().getRowColumnVector();
if (JS_ATTRIBUTE.matcher(attr.getName()).matches()) {
snippetLoC =
extractSnippet(
2,
config,
scopeManager,
textualExtractor,
source,
valueStart.getRow(),
valueStart.getColumn(),
false /* isTypeScript */);
} else if (source.startsWith("javascript:")) {
source = source.substring(11);
snippetLoC =
extractSnippet(
3,
config,
scopeManager,
textualExtractor,
source,
valueStart.getRow(),
valueStart.getColumn() + 11,
false /* isTypeScript */);
}
}
}
public LoCInfo getLoCInfo() {
return this.locInfo;
}
}
if (snippetLoC != null) result.add(snippetLoC);
}
/** List of HTML attributes whose value is interpreted as JavaScript. */
private static final Pattern JS_ATTRIBUTE = Pattern.compile(
"^on(abort|blur|change|(dbl)?click|error|focus|key(down|press|up)|load|mouse(down|move|out|over|up)|re(set|size)|select|submit|unload)$",
Pattern.CASE_INSENSITIVE);
// extract HTML elements if necessary.
if (config.getHtmlHandling().extractElements()) {
extractChildElements(src, locationManager);
private final ExtractorConfig config;
private final ExtractorState state;
for (Element elt : src.getAllElements()) {
if (isPlainElement(elt)) {
extractChildElements(elt, locationManager);
extractAttributes(elt, locationManager);
}
}
}
public HTMLExtractor(ExtractorConfig config, ExtractorState state) {
this.config = config.withPlatform(Platform.WEB);
this.state = state;
}
return result;
}
@Override
public LoCInfo extract(TextualExtractor textualExtractor) {
JavaScriptHTMLElementHandler eltHandler = new JavaScriptHTMLElementHandler(textualExtractor);
/**
* Deduce the {@link SourceType} with which the given <code>script</code> element should be
* extracted, returning <code>null</code> if it cannot be determined.
*/
private SourceType getScriptSourceType(Element script, File file) {
String scriptType = getAttributeValueLC(script, "type");
String scriptLanguage = getScriptLanguage(script);
SourceType fallbackSourceType = config.getSourceType();
if (file.getName().endsWith(".vue")) {
fallbackSourceType = SourceType.MODULE;
}
HtmlPopulator extractor = new HtmlPopulator(this.config.getHtmlHandling(), textualExtractor.getSource(),
textualExtractor.getTrapwriter(), textualExtractor.getLocationManager().getFileLabel());
if (isTypeScriptTag(script)) return fallbackSourceType;
extractor.doit(Option.some(eltHandler));
// if `type` and `language` are both either missing, contain the
// string "javascript", or if `type` is the string "text/jsx", this is a plain script
if ((scriptType == null || scriptType.contains("javascript") || "text/jsx".equals(scriptType))
&& (scriptLanguage == null || scriptLanguage.contains("javascript")))
// use default source type
return fallbackSourceType;
return eltHandler.getLoCInfo();
}
// if `type` is "text/babel", the source type depends on the `data-plugins` attribute
if ("text/babel".equals(scriptType)) {
String plugins = getAttributeValueLC(script, "data-plugins");
if (plugins != null && plugins.contains("transform-es2015-modules-umd")) {
return SourceType.MODULE;
}
return fallbackSourceType;
}
/**
* Deduce the {@link SourceType} with which the given <code>script</code>
* element should be extracted, returning <code>null</code> if it cannot be
* determined.
*/
private SourceType getScriptSourceType(Element script, File file) {
String scriptType = getAttributeValueLC(script, "type");
String scriptLanguage = getScriptLanguage(script);
// if `type` is "module", extract as module
if ("module".equals(scriptType)) return SourceType.MODULE;
SourceType fallbackSourceType = config.getSourceType();
if (file.getName().endsWith(".vue")) {
fallbackSourceType = SourceType.MODULE;
}
return null;
}
if (isTypeScriptTag(script))
return fallbackSourceType;
private String getScriptLanguage(Element script) {
String scriptLanguage = getAttributeValueLC(script, "language");
// if `type` and `language` are both either missing, contain the
// string "javascript", or if `type` is the string "text/jsx", this is a plain
// script
if ((scriptType == null || scriptType.contains("javascript") || "text/jsx".equals(scriptType))
&& (scriptLanguage == null || scriptLanguage.contains("javascript")))
// use default source type
return fallbackSourceType;
if (scriptLanguage == null) { // Vue templates use 'lang' instead of 'language'.
scriptLanguage = getAttributeValueLC(script, "lang");
}
return scriptLanguage;
}
// if `type` is "text/babel", the source type depends on the `data-plugins`
// attribute
if ("text/babel".equals(scriptType)) {
String plugins = getAttributeValueLC(script, "data-plugins");
if (plugins != null && plugins.contains("transform-es2015-modules-umd")) {
return SourceType.MODULE;
}
return fallbackSourceType;
}
private boolean isTypeScriptTag(Element script) {
String language = getScriptLanguage(script);
if ("ts".equals(language) || "typescript".equals(language)) return true;
String type = getAttributeValueLC(script, "type");
if (type != null && type.contains("typescript")) return true;
return false;
}
// if `type` is "module", extract as module
if ("module".equals(scriptType))
return SourceType.MODULE;
/**
* Get the value of attribute <code>attr</code> of element <code>elt</code> in lower case; if the
* attribute has no value, <code>null</code> is returned.
*/
private String getAttributeValueLC(Element elt, String attr) {
String val = elt.getAttributeValue(attr);
return val == null ? val : StringUtil.lc(val);
}
return null;
}
private LoCInfo extractSnippet(
int toplevelKind,
ExtractorConfig config,
ScopeManager scopeManager,
TextualExtractor textualExtractor,
String source,
int line,
int column,
boolean isTypeScript) {
if (isTypeScript) {
Path file = textualExtractor.getExtractedFile().toPath();
FileSnippet snippet = new FileSnippet(file, line, column, 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.
// For .vue files we omit the usual snippet decoration to ensure the TypeScript compiler can find it.
Path virtualFile =
file.getFileName().toString().endsWith(".vue")
? vroot.toVirtualFile(file.resolveSibling(file.getFileName() + ".ts"))
: vroot.getVirtualFileForSnippet(snippet, ".ts");
if (virtualFile != null) {
virtualFile = virtualFile.toAbsolutePath().normalize();
synchronized(vroot.getLock()) {
new WholeIO().strictwrite(virtualFile, source);
}
state.getSnippets().put(virtualFile, snippet);
}
return null; // LoC info is accounted for later
}
TrapWriter trapwriter = textualExtractor.getTrapwriter();
LocationManager locationManager = textualExtractor.getLocationManager();
LocationManager scriptLocationManager =
new LocationManager(
locationManager.getSourceFile(), trapwriter, locationManager.getFileLabel());
scriptLocationManager.setStart(line, column);
JSExtractor extractor = new JSExtractor(config);
try {
TextualExtractor tx =
new TextualExtractor(
trapwriter,
scriptLocationManager,
source,
config.getExtractLines(),
textualExtractor.getMetrics(),
textualExtractor.getExtractedFile());
return extractor.extract(tx, source, toplevelKind, scopeManager).snd();
} catch (ParseError e) {
e.setPosition(scriptLocationManager.translatePosition(e.getPosition()));
throw e.asUserError();
}
}
private String getScriptLanguage(Element script) {
String scriptLanguage = getAttributeValueLC(script, "language");
/**
* Is {@code elt} a plain HTML element (as opposed to a doctype declaration, comment, processing
* instruction, etc.)?
*/
private boolean isPlainElement(Element elt) {
return elt.getStartTag().getTagType() == StartTagType.NORMAL;
}
if (scriptLanguage == null) { // Vue templates use 'lang' instead of 'language'.
scriptLanguage = getAttributeValueLC(script, "lang");
}
return scriptLanguage;
}
/** Is {@code elt} a CDATA element ? */
private boolean isCDataElement(Element elt) {
return elt.getStartTag().getTagType() == StartTagType.CDATA_SECTION;
}
private boolean isTypeScriptTag(Element script) {
String language = getScriptLanguage(script);
if ("ts".equals(language) || "typescript".equals(language))
return true;
String type = getAttributeValueLC(script, "type");
if (type != null && type.contains("typescript"))
return true;
return false;
}
/** Is {@code elt} an HTML comment? */
private boolean isComment(Element elt) {
return elt.getStartTag().getTagType() == StartTagType.COMMENT;
}
/**
* Get the value of attribute <code>attr</code> of element <code>elt</code> in
* lower case; if the attribute has no value, <code>null</code> is returned.
*/
private String getAttributeValueLC(Element elt, String attr) {
String val = elt.getAttributeValue(attr);
return val == null ? val : StringUtil.lc(val);
}
/**
* Populate the {@code xmlElements} relation recording information about all child elements of
* {@code parent}, which is either an {@link Element} or a {@link Source} (representing the HTML
* file itself).
*/
private void extractChildElements(Segment parent, LocationManager locationManager) {
TrapWriter trapWriter = locationManager.getTrapWriter();
Label fileLabel = locationManager.getFileLabel();
Label parentLabel = parent instanceof Source ? fileLabel : trapWriter.localID(parent);
int childIndex = 0;
Source source = parent.getSource();
int contentStart =
parent instanceof Element ? ((Element) parent).getStartTag().getEnd() : parent.getBegin();
int contentEnd;
if (parent instanceof Element && ((Element) parent).getEndTag() != null)
contentEnd = ((Element) parent).getEndTag().getBegin();
else contentEnd = parent.getEnd();
int prevChildEnd = contentStart;
for (Element child : parent.getChildElements()) {
childIndex +=
emitXmlChars(
source,
prevChildEnd,
child.getBegin(),
parentLabel,
childIndex,
false,
fileLabel,
locationManager);
if (isCDataElement(child)) {
// treat CDATA sections as text
childIndex +=
emitXmlChars(
source,
child.getBegin() + "<![CDATA[".length(),
child.getEnd() - "]]>".length(),
parentLabel,
childIndex,
true,
fileLabel,
locationManager);
}
if (isPlainElement(child)) {
String childName = child.getName();
Label childLabel = trapWriter.localID(child);
trapWriter.addTuple(
"xmlElements", childLabel, childName, parentLabel, childIndex++, fileLabel);
emitLocation(child, childLabel, locationManager);
}
if (config.getHtmlHandling().extractComments() && isComment(child)) {
Label childLabel = trapWriter.localID(child);
trapWriter.addTuple("xmlComments", childLabel, child.toString(), parentLabel, fileLabel);
emitLocation(child, childLabel, locationManager);
}
prevChildEnd = child.getEnd();
}
emitXmlChars(
source,
prevChildEnd,
contentEnd,
parentLabel,
childIndex,
false,
fileLabel,
locationManager);
}
/**
* Populate the {@code xmlAttrs} relation recording information about all attributes of {@code
* elt}.
*/
private void extractAttributes(Element elt, LocationManager locationManager) {
TrapWriter trapWriter = locationManager.getTrapWriter();
Label fileLabel = locationManager.getFileLabel();
Label eltLabel = trapWriter.localID(elt);
Attributes attributes = elt.getAttributes();
// attributes can be null for directives
if (attributes == null) return;
int i = 0;
for (Attribute attr : attributes) {
String attrName = attr.getName();
String attrValue = attr.getValue() == null ? "" : attr.getValue();
Label attrLabel = trapWriter.localID(attr);
trapWriter.addTuple("xmlAttrs", attrLabel, eltLabel, attrName, attrValue, i++, fileLabel);
emitLocation(attr, attrLabel, locationManager);
}
}
/**
* Record the location of {@code s}, which is either an {@link Element} or an {@code Attribute}.
*/
private void emitLocation(Segment s, Label label, LocationManager locationManager) {
TrapWriter trapWriter = locationManager.getTrapWriter();
Source src = s.getSource();
int so = s.getBegin(), eo = s.getEnd() - 1;
int sl = src.getRow(so), sc = src.getColumn(so);
int el = src.getRow(eo), ec = src.getColumn(eo);
Label loc = locationManager.emitLocationsDefault(sl, sc, el, ec);
trapWriter.addTuple("xmllocations", label, loc);
}
/**
* If {@code textEnd} is greater than {@code textBegin}, extract all characters in that range as
* HTML text, populating {@code xmlChars} and make it the {@code i}th child of {@code
* parentLabel}.
*
* @return 1 if text was extractod, 0 otherwise
*/
private int emitXmlChars(
Source src,
int textBegin,
int textEnd,
Label parentLabel,
int id,
boolean isCData,
Label fileLabel,
LocationManager locationManager) {
if (!config.getHtmlHandling().extractText()) {
return 0;
}
if (textBegin >= textEnd) {
return 0;
}
TrapWriter trapWriter = locationManager.getTrapWriter();
Segment s = new Segment(src, textBegin, textEnd);
int so = s.getBegin(), eo = s.getEnd() - 1;
String rawText = s.toString();
if (!isCData) {
// expand entities. Note that `rawText` no longer spans the start/end region.
rawText = CharacterReference.decode(rawText, false);
}
Label label = trapWriter.freshLabel();
trapWriter.addTuple("xmlChars", label, rawText, parentLabel, id, isCData ? 1 : 0, fileLabel);
int sl = src.getRow(so), sc = src.getColumn(so);
int el = src.getRow(eo), ec = src.getColumn(eo);
Label loc = locationManager.emitLocationsDefault(sl, sc, el, ec);
trapWriter.addTuple("xmllocations", label, loc);
return 1;
}
private LoCInfo extractSnippet(int toplevelKind, ExtractorConfig config, ScopeManager scopeManager,
TextualExtractor textualExtractor, String source, int line, int column, boolean isTypeScript) {
if (isTypeScript) {
Path file = textualExtractor.getExtractedFile().toPath();
FileSnippet snippet = new FileSnippet(file, line, column, 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.
// For .vue files we omit the usual snippet decoration to ensure the TypeScript
// compiler can find it.
Path virtualFile = file.getFileName().toString().endsWith(".vue")
? vroot.toVirtualFile(file.resolveSibling(file.getFileName() + ".ts"))
: vroot.getVirtualFileForSnippet(snippet, ".ts");
if (virtualFile != null) {
virtualFile = virtualFile.toAbsolutePath().normalize();
synchronized (vroot.getLock()) {
new WholeIO().strictwrite(virtualFile, source);
}
state.getSnippets().put(virtualFile, snippet);
}
return null; // LoC info is accounted for later
}
TrapWriter trapwriter = textualExtractor.getTrapwriter();
LocationManager locationManager = textualExtractor.getLocationManager();
LocationManager scriptLocationManager = new LocationManager(locationManager.getSourceFile(), trapwriter,
locationManager.getFileLabel());
scriptLocationManager.setStart(line, column);
JSExtractor extractor = new JSExtractor(config);
try {
TextualExtractor tx = new TextualExtractor(trapwriter, scriptLocationManager, source,
config.getExtractLines(), textualExtractor.getMetrics(), textualExtractor.getExtractedFile());
return extractor.extract(tx, source, toplevelKind, scopeManager).snd();
} catch (ParseError e) {
e.setPosition(scriptLocationManager.translatePosition(e.getPosition()));
throw e.asUserError();
}
}
}

View File

@@ -11,7 +11,7 @@ import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.semmle.js.extractor.ExtractorConfig.HTMLHandling;
import com.semmle.extractor.html.HtmlPopulator;
import com.semmle.js.extractor.ExtractorConfig.Platform;
import com.semmle.js.extractor.ExtractorConfig.SourceType;
import com.semmle.js.extractor.FileExtractor.FileType;
@@ -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 = "2020-11-11";
public static final String EXTRACTOR_VERSION = "2020-12-05";
public static final Pattern NEWLINE = Pattern.compile("\n");
@@ -486,8 +486,8 @@ public class Main {
.withHtmlHandling(
ap.getEnum(
P_HTML,
HTMLHandling.class,
ap.has(P_EXPERIMENTAL) ? HTMLHandling.ALL : HTMLHandling.ELEMENTS))
HtmlPopulator.Config.class,
ap.has(P_EXPERIMENTAL) ? HtmlPopulator.Config.ALL : HtmlPopulator.Config.ELEMENTS))
.withFileType(getFileType(ap))
.withSourceType(ap.getEnum(P_SOURCE_TYPE, SourceType.class, SourceType.AUTO))
.withExtractLines(ap.has(P_EXTRACT_PROGRAM_TEXT))

View File

@@ -9,152 +9,157 @@ hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=*
xmlElements(#20001,"html",#10000,0,#10000)
#20002=@"loc,{#10000},1,1,25,7"
locations_default(#20002,#10000,1,1,25,7)
xmlChars(#20001,"
",#10000,1,0,#10000)
#20002=@"loc,{#10000},25,8,25,8"
locations_default(#20002,#10000,25,8,25,8)
xmllocations(#20001,#20002)
#20003=*
xmlChars(#20003,"
",#10000,1,0,#10000)
#20004=@"loc,{#10000},25,8,25,8"
locations_default(#20004,#10000,25,8,25,8)
xmlElements(#20003,"html",#10000,0,#10000)
#20004=@"loc,{#10000},1,1,25,7"
locations_default(#20004,#10000,1,1,25,7)
xmllocations(#20003,#20004)
#20005=*
xmlChars(#20005,"
",#20001,0,0,#10000)
",#20003,0,0,#10000)
#20006=@"loc,{#10000},1,7,2,3"
locations_default(#20006,#10000,1,7,2,3)
xmllocations(#20005,#20006)
#20007=*
xmlElements(#20007,"head",#20001,1,#10000)
#20008=@"loc,{#10000},2,4,4,10"
locations_default(#20008,#10000,2,4,4,10)
xmlChars(#20007,"
",#20003,2,0,#10000)
#20008=@"loc,{#10000},4,11,5,3"
locations_default(#20008,#10000,4,11,5,3)
xmllocations(#20007,#20008)
#20009=*
xmlChars(#20009,"
",#20001,2,0,#10000)
#20010=@"loc,{#10000},4,11,5,3"
locations_default(#20010,#10000,4,11,5,3)
",#20003,4,0,#10000)
#20010=@"loc,{#10000},24,11,24,11"
locations_default(#20010,#10000,24,11,24,11)
xmllocations(#20009,#20010)
#20011=*
xmlElements(#20011,"body",#20001,3,#10000)
xmlElements(#20011,"body",#20003,3,#10000)
#20012=@"loc,{#10000},5,4,24,10"
locations_default(#20012,#10000,5,4,24,10)
xmllocations(#20011,#20012)
#20013=*
xmlChars(#20013,"
",#20001,4,0,#10000)
#20014=@"loc,{#10000},24,11,24,11"
locations_default(#20014,#10000,24,11,24,11)
text1
",#20011,0,0,#10000)
#20014=@"loc,{#10000},5,10,7,6"
locations_default(#20014,#10000,5,10,7,6)
xmllocations(#20013,#20014)
#20015=*
xmlChars(#20015,"
",#20007,0,0,#10000)
#20016=@"loc,{#10000},2,10,3,6"
locations_default(#20016,#10000,2,10,3,6)
text2
",#20011,2,0,#10000)
#20016=@"loc,{#10000},7,13,9,6"
locations_default(#20016,#10000,7,13,9,6)
xmllocations(#20015,#20016)
#20017=*
xmlElements(#20017,"title",#20007,1,#10000)
#20018=@"loc,{#10000},3,7,3,21"
locations_default(#20018,#10000,3,7,3,21)
xmlChars(#20017,"
text3
",#20011,4,0,#10000)
#20018=@"loc,{#10000},9,12,11,6"
locations_default(#20018,#10000,9,12,11,6)
xmllocations(#20017,#20018)
#20019=*
xmlChars(#20019,"
",#20007,2,0,#10000)
#20020=@"loc,{#10000},3,22,4,3"
locations_default(#20020,#10000,3,22,4,3)
text5
",#20011,6,0,#10000)
#20020=@"loc,{#10000},11,23,13,6"
locations_default(#20020,#10000,11,23,13,6)
xmllocations(#20019,#20020)
#20021=*
xmlChars(#20021,"
text1
",#20011,0,0,#10000)
#20022=@"loc,{#10000},5,10,7,6"
locations_default(#20022,#10000,5,10,7,6)
text6
",#20011,8,0,#10000)
#20022=@"loc,{#10000},13,13,15,6"
locations_default(#20022,#10000,13,13,15,6)
xmllocations(#20021,#20022)
#20023=*
xmlElements(#20023,"div",#20011,1,#10000)
#20024=@"loc,{#10000},7,7,7,12"
locations_default(#20024,#10000,7,7,7,12)
xmlChars(#20023,"
text8",#20011,10,0,#10000)
#20024=@"loc,{#10000},15,24,16,11"
locations_default(#20024,#10000,15,24,16,11)
xmllocations(#20023,#20024)
#20025=*
xmlChars(#20025,"
text2
",#20011,2,0,#10000)
#20026=@"loc,{#10000},7,13,9,6"
locations_default(#20026,#10000,7,13,9,6)
xmlChars(#20025,"text10",#20011,12,0,#10000)
#20026=@"loc,{#10000},16,29,16,34"
locations_default(#20026,#10000,16,29,16,34)
xmllocations(#20025,#20026)
#20027=*
xmlElements(#20027,"div",#20011,3,#10000)
#20028=@"loc,{#10000},9,7,9,11"
locations_default(#20028,#10000,9,7,9,11)
xmlChars(#20027,"text13
",#20011,15,0,#10000)
#20028=@"loc,{#10000},16,71,17,6"
locations_default(#20028,#10000,16,71,17,6)
xmllocations(#20027,#20028)
#20029=*
xmlChars(#20029,"
text3
",#20011,4,0,#10000)
#20030=@"loc,{#10000},9,12,11,6"
locations_default(#20030,#10000,9,12,11,6)
",#20011,17,0,#10000)
#20030=@"loc,{#10000},17,13,18,6"
locations_default(#20030,#10000,17,13,18,6)
xmllocations(#20029,#20030)
#20031=*
xmlElements(#20031,"div",#20011,5,#10000)
#20032=@"loc,{#10000},11,7,11,22"
locations_default(#20032,#10000,11,7,11,22)
xmlChars(#20031,"
",#20011,19,0,#10000)
#20032=@"loc,{#10000},18,13,19,6"
locations_default(#20032,#10000,18,13,19,6)
xmllocations(#20031,#20032)
#20033=*
xmlChars(#20033,"
text5
",#20011,6,0,#10000)
#20034=@"loc,{#10000},11,23,13,6"
locations_default(#20034,#10000,11,23,13,6)
",#20011,20,0,#10000)
#20034=@"loc,{#10000},19,33,20,6"
locations_default(#20034,#10000,19,33,20,6)
xmllocations(#20033,#20034)
#20035=*
xmlElements(#20035,"div",#20011,7,#10000)
#20036=@"loc,{#10000},13,7,13,12"
locations_default(#20036,#10000,13,7,13,12)
xmlChars(#20035,"
text14
",#20011,22,0,#10000)
#20036=@"loc,{#10000},20,13,22,6"
locations_default(#20036,#10000,20,13,22,6)
xmllocations(#20035,#20036)
#20037=*
xmlChars(#20037,"
text6
",#20011,8,0,#10000)
#20038=@"loc,{#10000},13,13,15,6"
locations_default(#20038,#10000,13,13,15,6)
",#20011,24,0,#10000)
#20038=@"loc,{#10000},22,105,23,6"
locations_default(#20038,#10000,22,105,23,6)
xmllocations(#20037,#20038)
#20039=*
xmlElements(#20039,"div",#20011,9,#10000)
#20040=@"loc,{#10000},15,7,15,23"
locations_default(#20040,#10000,15,7,15,23)
xmlChars(#20039,"
",#20011,26,0,#10000)
#20040=@"loc,{#10000},23,73,24,3"
locations_default(#20040,#10000,23,73,24,3)
xmllocations(#20039,#20040)
#20041=*
xmlChars(#20041,"
text8",#20011,10,0,#10000)
#20042=@"loc,{#10000},15,24,16,11"
locations_default(#20042,#10000,15,24,16,11)
xmlChars(#20041,"non-entity1: &amp; non-entity2: &gt; non-entity3: &lt;",#20011,25,1,#10000)
#20042=@"loc,{#10000},23,16,23,69"
locations_default(#20042,#10000,23,16,23,69)
xmllocations(#20041,#20042)
#20043=*
xmlChars(#20043,"text9",#20011,11,1,#10000)
#20044=@"loc,{#10000},16,21,16,25"
locations_default(#20044,#10000,16,21,16,25)
xmlElements(#20043,"div",#20011,23,#10000)
#20044=@"loc,{#10000},22,7,22,104"
locations_default(#20044,#10000,22,7,22,104)
xmllocations(#20043,#20044)
#20045=*
xmlChars(#20045,"text10",#20011,12,0,#10000)
#20046=@"loc,{#10000},16,29,16,34"
locations_default(#20046,#10000,16,29,16,34)
xmlChars(#20045,"entity1: & entity2: > entity3: < entity4: & entity5: > entity6: <",#20043,0,0,#10000)
#20046=@"loc,{#10000},22,12,22,98"
locations_default(#20046,#10000,22,12,22,98)
xmllocations(#20045,#20046)
#20047=*
xmlChars(#20047,"text11",#20011,13,1,#10000)
#20048=@"loc,{#10000},16,44,16,49"
locations_default(#20048,#10000,16,44,16,49)
xmlElements(#20047,"div",#20011,21,#10000)
#20048=@"loc,{#10000},20,7,20,12"
locations_default(#20048,#10000,20,7,20,12)
xmllocations(#20047,#20048)
#20049=*
xmlChars(#20049,"text12",#20011,14,1,#10000)
#20050=@"loc,{#10000},16,62,16,67"
locations_default(#20050,#10000,16,62,16,67)
xmlComments(#20049,"<!-- This is a comment -->",#20011,#10000)
#20050=@"loc,{#10000},19,7,19,32"
locations_default(#20050,#10000,19,7,19,32)
xmllocations(#20049,#20050)
#20051=*
xmlChars(#20051,"text13
",#20011,15,0,#10000)
#20052=@"loc,{#10000},16,71,17,6"
locations_default(#20052,#10000,16,71,17,6)
xmlElements(#20051,"div",#20011,18,#10000)
#20052=@"loc,{#10000},18,7,18,12"
locations_default(#20052,#10000,18,7,18,12)
xmllocations(#20051,#20052)
#20053=*
xmlElements(#20053,"div",#20011,16,#10000)
@@ -162,81 +167,76 @@ xmlElements(#20053,"div",#20011,16,#10000)
locations_default(#20054,#10000,17,7,17,12)
xmllocations(#20053,#20054)
#20055=*
xmlChars(#20055,"
",#20011,17,0,#10000)
#20056=@"loc,{#10000},17,13,18,6"
locations_default(#20056,#10000,17,13,18,6)
xmlChars(#20055,"text12",#20011,14,1,#10000)
#20056=@"loc,{#10000},16,62,16,67"
locations_default(#20056,#10000,16,62,16,67)
xmllocations(#20055,#20056)
#20057=*
xmlElements(#20057,"div",#20011,18,#10000)
#20058=@"loc,{#10000},18,7,18,12"
locations_default(#20058,#10000,18,7,18,12)
xmlChars(#20057,"text11",#20011,13,1,#10000)
#20058=@"loc,{#10000},16,44,16,49"
locations_default(#20058,#10000,16,44,16,49)
xmllocations(#20057,#20058)
#20059=*
xmlChars(#20059,"
",#20011,19,0,#10000)
#20060=@"loc,{#10000},18,13,19,6"
locations_default(#20060,#10000,18,13,19,6)
xmlChars(#20059,"text9",#20011,11,1,#10000)
#20060=@"loc,{#10000},16,21,16,25"
locations_default(#20060,#10000,16,21,16,25)
xmllocations(#20059,#20060)
#20061=*
xmlComments(#20061,"<!-- This is a comment -->",#20011,#10000)
#20062=@"loc,{#10000},19,7,19,32"
locations_default(#20062,#10000,19,7,19,32)
xmlElements(#20061,"div",#20011,9,#10000)
#20062=@"loc,{#10000},15,7,15,23"
locations_default(#20062,#10000,15,7,15,23)
xmllocations(#20061,#20062)
#20063=*
xmlChars(#20063,"
",#20011,20,0,#10000)
#20064=@"loc,{#10000},19,33,20,6"
locations_default(#20064,#10000,19,33,20,6)
xmlChars(#20063,"text7",#20061,0,0,#10000)
#20064=@"loc,{#10000},15,13,15,17"
locations_default(#20064,#10000,15,13,15,17)
xmllocations(#20063,#20064)
#20065=*
xmlElements(#20065,"div",#20011,21,#10000)
#20066=@"loc,{#10000},20,7,20,12"
locations_default(#20066,#10000,20,7,20,12)
xmlElements(#20065,"div",#20011,7,#10000)
#20066=@"loc,{#10000},13,7,13,12"
locations_default(#20066,#10000,13,7,13,12)
xmllocations(#20065,#20066)
#20067=*
xmlChars(#20067,"
text14
",#20011,22,0,#10000)
#20068=@"loc,{#10000},20,13,22,6"
locations_default(#20068,#10000,20,13,22,6)
xmlElements(#20067,"div",#20011,5,#10000)
#20068=@"loc,{#10000},11,7,11,22"
locations_default(#20068,#10000,11,7,11,22)
xmllocations(#20067,#20068)
#20069=*
xmlElements(#20069,"div",#20011,23,#10000)
#20070=@"loc,{#10000},22,7,22,104"
locations_default(#20070,#10000,22,7,22,104)
xmlChars(#20069,"text4",#20067,0,0,#10000)
#20070=@"loc,{#10000},11,12,11,16"
locations_default(#20070,#10000,11,12,11,16)
xmllocations(#20069,#20070)
#20071=*
xmlChars(#20071,"
",#20011,24,0,#10000)
#20072=@"loc,{#10000},22,105,23,6"
locations_default(#20072,#10000,22,105,23,6)
xmlElements(#20071,"div",#20011,3,#10000)
#20072=@"loc,{#10000},9,7,9,11"
locations_default(#20072,#10000,9,7,9,11)
xmllocations(#20071,#20072)
#20073=*
xmlChars(#20073,"non-entity1: &amp; non-entity2: &gt; non-entity3: &lt;",#20011,25,1,#10000)
#20074=@"loc,{#10000},23,16,23,69"
locations_default(#20074,#10000,23,16,23,69)
xmlElements(#20073,"div",#20011,1,#10000)
#20074=@"loc,{#10000},7,7,7,12"
locations_default(#20074,#10000,7,7,7,12)
xmllocations(#20073,#20074)
#20075=*
xmlChars(#20075,"
",#20011,26,0,#10000)
#20076=@"loc,{#10000},23,73,24,3"
locations_default(#20076,#10000,23,73,24,3)
xmlElements(#20075,"head",#20003,1,#10000)
#20076=@"loc,{#10000},2,4,4,10"
locations_default(#20076,#10000,2,4,4,10)
xmllocations(#20075,#20076)
#20077=*
xmlChars(#20077,"text4",#20031,0,0,#10000)
#20078=@"loc,{#10000},11,12,11,16"
locations_default(#20078,#10000,11,12,11,16)
xmlChars(#20077,"
",#20075,0,0,#10000)
#20078=@"loc,{#10000},2,10,3,6"
locations_default(#20078,#10000,2,10,3,6)
xmllocations(#20077,#20078)
#20079=*
xmlChars(#20079,"text7",#20039,0,0,#10000)
#20080=@"loc,{#10000},15,13,15,17"
locations_default(#20080,#10000,15,13,15,17)
xmlChars(#20079,"
",#20075,2,0,#10000)
#20080=@"loc,{#10000},3,22,4,3"
locations_default(#20080,#10000,3,22,4,3)
xmllocations(#20079,#20080)
#20081=*
xmlChars(#20081,"entity1: & entity2: > entity3: < entity4: & entity5: > entity6: <",#20069,0,0,#10000)
#20082=@"loc,{#10000},22,12,22,98"
locations_default(#20082,#10000,22,12,22,98)
xmlElements(#20081,"title",#20075,1,#10000)
#20082=@"loc,{#10000},3,7,3,21"
locations_default(#20082,#10000,3,7,3,21)
xmllocations(#20081,#20082)
numlines(#10000,25,0,0)
filetype(#10000,"html")

View File

@@ -122,29 +122,29 @@ xmlElements(#20034,"html",#10000,0,#10000)
locations_default(#20035,#10000,1,1,8,7)
xmllocations(#20034,#20035)
#20036=*
xmlElements(#20036,"head",#20034,0,#10000)
#20037=@"loc,{#10000},2,5,4,11"
locations_default(#20037,#10000,2,5,4,11)
xmlElements(#20036,"body",#20034,1,#10000)
#20037=@"loc,{#10000},5,5,7,11"
locations_default(#20037,#10000,5,5,7,11)
xmllocations(#20036,#20037)
#20038=*
xmlElements(#20038,"body",#20034,1,#10000)
#20039=@"loc,{#10000},5,5,7,11"
locations_default(#20039,#10000,5,5,7,11)
xmlElements(#20038,"a",#20036,0,#10000)
#20039=@"loc,{#10000},6,9,6,80"
locations_default(#20039,#10000,6,9,6,80)
xmllocations(#20038,#20039)
#20040=*
xmlElements(#20040,"title",#20036,0,#10000)
#20041=@"loc,{#10000},3,9,3,32"
locations_default(#20041,#10000,3,9,3,32)
xmlAttrs(#20040,#20038,"href","javascript:void(alert(""Nope!""))",0,#10000)
#20041=@"loc,{#10000},6,12,6,65"
locations_default(#20041,#10000,6,12,6,65)
xmllocations(#20040,#20041)
#20042=*
xmlElements(#20042,"a",#20038,0,#10000)
#20043=@"loc,{#10000},6,9,6,80"
locations_default(#20043,#10000,6,9,6,80)
xmlElements(#20042,"head",#20034,0,#10000)
#20043=@"loc,{#10000},2,5,4,11"
locations_default(#20043,#10000,2,5,4,11)
xmllocations(#20042,#20043)
#20044=*
xmlAttrs(#20044,#20042,"href","javascript:void(alert(""Nope!""))",0,#10000)
#20045=@"loc,{#10000},6,12,6,65"
locations_default(#20045,#10000,6,12,6,65)
xmlElements(#20044,"title",#20042,0,#10000)
#20045=@"loc,{#10000},3,9,3,32"
locations_default(#20045,#10000,3,9,3,32)
xmllocations(#20044,#20045)
numlines(#10000,8,1,0)
filetype(#10000,"html")

View File

@@ -199,29 +199,29 @@ xmlElements(#20056,"html",#10000,0,#10000)
locations_default(#20057,#10000,1,1,11,7)
xmllocations(#20056,#20057)
#20058=*
xmlElements(#20058,"head",#20056,0,#10000)
#20059=@"loc,{#10000},2,5,8,11"
locations_default(#20059,#10000,2,5,8,11)
xmlElements(#20058,"body",#20056,1,#10000)
#20059=@"loc,{#10000},9,5,10,11"
locations_default(#20059,#10000,9,5,10,11)
xmllocations(#20058,#20059)
#20060=*
xmlElements(#20060,"body",#20056,1,#10000)
#20061=@"loc,{#10000},9,5,10,11"
locations_default(#20061,#10000,9,5,10,11)
xmlElements(#20060,"head",#20056,0,#10000)
#20061=@"loc,{#10000},2,5,8,11"
locations_default(#20061,#10000,2,5,8,11)
xmllocations(#20060,#20061)
#20062=*
xmlElements(#20062,"title",#20058,0,#10000)
#20063=@"loc,{#10000},3,9,3,32"
locations_default(#20063,#10000,3,9,3,32)
xmlElements(#20062,"script",#20060,1,#10000)
#20063=@"loc,{#10000},4,9,7,17"
locations_default(#20063,#10000,4,9,7,17)
xmllocations(#20062,#20063)
#20064=*
xmlElements(#20064,"script",#20058,1,#10000)
#20065=@"loc,{#10000},4,9,7,17"
locations_default(#20065,#10000,4,9,7,17)
xmlAttrs(#20064,#20062,"type","module",0,#10000)
#20065=@"loc,{#10000},4,17,4,29"
locations_default(#20065,#10000,4,17,4,29)
xmllocations(#20064,#20065)
#20066=*
xmlAttrs(#20066,#20064,"type","module",0,#10000)
#20067=@"loc,{#10000},4,17,4,29"
locations_default(#20067,#10000,4,17,4,29)
xmlElements(#20066,"title",#20060,0,#10000)
#20067=@"loc,{#10000},3,9,3,32"
locations_default(#20067,#10000,3,9,3,32)
xmllocations(#20066,#20067)
numlines(#10000,11,2,0)
filetype(#10000,"html")

View File

@@ -375,99 +375,99 @@ xmlElements(#20112,"html",#10000,0,#10000)
locations_default(#20113,#10000,1,1,18,7)
xmllocations(#20112,#20113)
#20114=*
xmlElements(#20114,"head",#20112,0,#10000)
#20115=@"loc,{#10000},2,5,9,11"
locations_default(#20115,#10000,2,5,9,11)
xmlElements(#20114,"script",#20112,4,#10000)
#20115=@"loc,{#10000},17,5,17,29"
locations_default(#20115,#10000,17,5,17,29)
xmllocations(#20114,#20115)
#20116=*
xmlElements(#20116,"body",#20112,1,#10000)
#20117=@"loc,{#10000},10,5,14,11"
locations_default(#20117,#10000,10,5,14,11)
xmlAttrs(#20116,#20114,"type","",0,#10000)
#20117=@"loc,{#10000},17,13,17,19"
locations_default(#20117,#10000,17,13,17,19)
xmllocations(#20116,#20117)
#20118=*
xmlElements(#20118,"script",#20112,2,#10000)
#20119=@"loc,{#10000},15,5,15,71"
locations_default(#20119,#10000,15,5,15,71)
xmlElements(#20118,"script",#20112,3,#10000)
#20119=@"loc,{#10000},16,5,16,71"
locations_default(#20119,#10000,16,5,16,71)
xmllocations(#20118,#20119)
#20120=*
xmlElements(#20120,"script",#20112,3,#10000)
#20121=@"loc,{#10000},16,5,16,71"
locations_default(#20121,#10000,16,5,16,71)
xmlAttrs(#20120,#20118,"TYPE","text/x-handlebars-template",0,#10000)
#20121=@"loc,{#10000},16,13,16,45"
locations_default(#20121,#10000,16,13,16,45)
xmllocations(#20120,#20121)
#20122=*
xmlElements(#20122,"script",#20112,4,#10000)
#20123=@"loc,{#10000},17,5,17,29"
locations_default(#20123,#10000,17,5,17,29)
xmlElements(#20122,"script",#20112,2,#10000)
#20123=@"loc,{#10000},15,5,15,71"
locations_default(#20123,#10000,15,5,15,71)
xmllocations(#20122,#20123)
#20124=*
xmlElements(#20124,"title",#20114,0,#10000)
#20125=@"loc,{#10000},3,9,3,32"
locations_default(#20125,#10000,3,9,3,32)
xmlAttrs(#20124,#20122,"type","text/x-handlebars-template",0,#10000)
#20125=@"loc,{#10000},15,13,15,45"
locations_default(#20125,#10000,15,13,15,45)
xmllocations(#20124,#20125)
#20126=*
xmlElements(#20126,"script",#20114,1,#10000)
#20127=@"loc,{#10000},4,9,4,43"
locations_default(#20127,#10000,4,9,4,43)
xmlElements(#20126,"body",#20112,1,#10000)
#20127=@"loc,{#10000},10,5,14,11"
locations_default(#20127,#10000,10,5,14,11)
xmllocations(#20126,#20127)
#20128=*
xmlElements(#20128,"script",#20114,2,#10000)
#20129=@"loc,{#10000},5,9,7,17"
locations_default(#20129,#10000,5,9,7,17)
xmlElements(#20128,"a",#20126,2,#10000)
#20129=@"loc,{#10000},13,9,13,59"
locations_default(#20129,#10000,13,9,13,59)
xmllocations(#20128,#20129)
#20130=*
xmlElements(#20130,"script",#20114,3,#10000)
#20131=@"loc,{#10000},8,9,8,26"
locations_default(#20131,#10000,8,9,8,26)
xmlAttrs(#20130,#20128,"onclick","return false;",0,#10000)
#20131=@"loc,{#10000},13,12,13,34"
locations_default(#20131,#10000,13,12,13,34)
xmllocations(#20130,#20131)
#20132=*
xmlAttrs(#20132,#20126,"src","external.js",0,#10000)
#20133=@"loc,{#10000},4,17,4,33"
locations_default(#20133,#10000,4,17,4,33)
xmlElements(#20132,"div",#20126,1,#10000)
#20133=@"loc,{#10000},12,9,12,75"
locations_default(#20133,#10000,12,9,12,75)
xmllocations(#20132,#20133)
#20134=*
xmlElements(#20134,"a",#20116,0,#10000)
#20135=@"loc,{#10000},11,9,11,64"
locations_default(#20135,#10000,11,9,11,64)
xmlAttrs(#20134,#20132,"onclick","alert('I said don\'t click!')",0,#10000)
#20135=@"loc,{#10000},12,14,12,52"
locations_default(#20135,#10000,12,14,12,52)
xmllocations(#20134,#20135)
#20136=*
xmlElements(#20136,"div",#20116,1,#10000)
#20137=@"loc,{#10000},12,9,12,75"
locations_default(#20137,#10000,12,9,12,75)
xmlElements(#20136,"a",#20126,0,#10000)
#20137=@"loc,{#10000},11,9,11,64"
locations_default(#20137,#10000,11,9,11,64)
xmllocations(#20136,#20137)
#20138=*
xmlElements(#20138,"a",#20116,2,#10000)
#20139=@"loc,{#10000},13,9,13,59"
locations_default(#20139,#10000,13,9,13,59)
xmlAttrs(#20138,#20136,"href","javascript:void(alert('Nope!'))",0,#10000)
#20139=@"loc,{#10000},11,12,11,49"
locations_default(#20139,#10000,11,12,11,49)
xmllocations(#20138,#20139)
#20140=*
xmlAttrs(#20140,#20134,"href","javascript:void(alert('Nope!'))",0,#10000)
#20141=@"loc,{#10000},11,12,11,49"
locations_default(#20141,#10000,11,12,11,49)
xmlElements(#20140,"head",#20112,0,#10000)
#20141=@"loc,{#10000},2,5,9,11"
locations_default(#20141,#10000,2,5,9,11)
xmllocations(#20140,#20141)
#20142=*
xmlAttrs(#20142,#20136,"onclick","alert('I said don\'t click!')",0,#10000)
#20143=@"loc,{#10000},12,14,12,52"
locations_default(#20143,#10000,12,14,12,52)
xmlElements(#20142,"script",#20140,3,#10000)
#20143=@"loc,{#10000},8,9,8,26"
locations_default(#20143,#10000,8,9,8,26)
xmllocations(#20142,#20143)
#20144=*
xmlAttrs(#20144,#20138,"onclick","return false;",0,#10000)
#20145=@"loc,{#10000},13,12,13,34"
locations_default(#20145,#10000,13,12,13,34)
xmlElements(#20144,"script",#20140,2,#10000)
#20145=@"loc,{#10000},5,9,7,17"
locations_default(#20145,#10000,5,9,7,17)
xmllocations(#20144,#20145)
#20146=*
xmlAttrs(#20146,#20118,"type","text/x-handlebars-template",0,#10000)
#20147=@"loc,{#10000},15,13,15,45"
locations_default(#20147,#10000,15,13,15,45)
xmlElements(#20146,"script",#20140,1,#10000)
#20147=@"loc,{#10000},4,9,4,43"
locations_default(#20147,#10000,4,9,4,43)
xmllocations(#20146,#20147)
#20148=*
xmlAttrs(#20148,#20120,"TYPE","text/x-handlebars-template",0,#10000)
#20149=@"loc,{#10000},16,13,16,45"
locations_default(#20149,#10000,16,13,16,45)
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=*
xmlAttrs(#20150,#20122,"type","",0,#10000)
#20151=@"loc,{#10000},17,13,17,19"
locations_default(#20151,#10000,17,13,17,19)
xmlElements(#20150,"title",#20140,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)
filetype(#10000,"html")

View File

@@ -80,39 +80,39 @@ xmlElements(#20022,"html",#10000,0,#10000)
locations_default(#20023,#10000,2,1,12,7)
xmllocations(#20022,#20023)
#20024=*
xmlElements(#20024,"head",#20022,0,#10000)
#20025=@"loc,{#10000},3,1,5,7"
locations_default(#20025,#10000,3,1,5,7)
xmlAttrs(#20024,#20022,"xmlns","http://www.w3.org/1999/xhtml",0,#10000)
#20025=@"loc,{#10000},2,7,2,42"
locations_default(#20025,#10000,2,7,2,42)
xmllocations(#20024,#20025)
#20026=*
xmlElements(#20026,"body",#20022,1,#10000)
#20027=@"loc,{#10000},6,1,11,7"
locations_default(#20027,#10000,6,1,11,7)
xmlAttrs(#20026,#20022,"xml:lang","en",1,#10000)
#20027=@"loc,{#10000},2,44,2,56"
locations_default(#20027,#10000,2,44,2,56)
xmllocations(#20026,#20027)
#20028=*
xmlAttrs(#20028,#20022,"xmlns","http://www.w3.org/1999/xhtml",0,#10000)
#20029=@"loc,{#10000},2,7,2,42"
locations_default(#20029,#10000,2,7,2,42)
xmlElements(#20028,"body",#20022,1,#10000)
#20029=@"loc,{#10000},6,1,11,7"
locations_default(#20029,#10000,6,1,11,7)
xmllocations(#20028,#20029)
#20030=*
xmlAttrs(#20030,#20022,"xml:lang","en",1,#10000)
#20031=@"loc,{#10000},2,44,2,56"
locations_default(#20031,#10000,2,44,2,56)
xmlElements(#20030,"script",#20028,0,#10000)
#20031=@"loc,{#10000},7,5,10,16"
locations_default(#20031,#10000,7,5,10,16)
xmllocations(#20030,#20031)
#20032=*
xmlElements(#20032,"title",#20024,0,#10000)
#20033=@"loc,{#10000},4,5,4,31"
locations_default(#20033,#10000,4,5,4,31)
xmlAttrs(#20032,#20030,"type","application/javascript",0,#10000)
#20033=@"loc,{#10000},7,13,7,41"
locations_default(#20033,#10000,7,13,7,41)
xmllocations(#20032,#20033)
#20034=*
xmlElements(#20034,"script",#20026,0,#10000)
#20035=@"loc,{#10000},7,5,10,16"
locations_default(#20035,#10000,7,5,10,16)
xmlElements(#20034,"head",#20022,0,#10000)
#20035=@"loc,{#10000},3,1,5,7"
locations_default(#20035,#10000,3,1,5,7)
xmllocations(#20034,#20035)
#20036=*
xmlAttrs(#20036,#20034,"type","application/javascript",0,#10000)
#20037=@"loc,{#10000},7,13,7,41"
locations_default(#20037,#10000,7,13,7,41)
xmlElements(#20036,"title",#20034,0,#10000)
#20037=@"loc,{#10000},4,5,4,31"
locations_default(#20037,#10000,4,5,4,31)
xmllocations(#20036,#20037)
numlines(#10000,12,1,0)
filetype(#10000,"html")

View File

@@ -317,54 +317,54 @@ xmlElements(#20092,"html",#10000,0,#10000)
locations_default(#20093,#10000,1,1,10,7)
xmllocations(#20092,#20093)
#20094=*
xmlElements(#20094,"script",#20092,0,#10000)
#20095=@"loc,{#10000},2,5,2,49"
locations_default(#20095,#10000,2,5,2,49)
xmlElements(#20094,"script",#20092,3,#10000)
#20095=@"loc,{#10000},7,5,9,13"
locations_default(#20095,#10000,7,5,9,13)
xmllocations(#20094,#20095)
#20096=*
xmlElements(#20096,"script",#20092,1,#10000)
#20097=@"loc,{#10000},3,5,3,47"
locations_default(#20097,#10000,3,5,3,47)
xmlAttrs(#20096,#20094,"type","text/babel",0,#10000)
#20097=@"loc,{#10000},7,13,7,29"
locations_default(#20097,#10000,7,13,7,29)
xmllocations(#20096,#20097)
#20098=*
xmlElements(#20098,"script",#20092,2,#10000)
#20099=@"loc,{#10000},4,5,6,13"
locations_default(#20099,#10000,4,5,6,13)
xmlAttrs(#20098,#20094,"data-plugins","transform-es2015-modules-umd",1,#10000)
#20099=@"loc,{#10000},7,31,7,73"
locations_default(#20099,#10000,7,31,7,73)
xmllocations(#20098,#20099)
#20100=*
xmlElements(#20100,"script",#20092,3,#10000)
#20101=@"loc,{#10000},7,5,9,13"
locations_default(#20101,#10000,7,5,9,13)
xmlElements(#20100,"script",#20092,2,#10000)
#20101=@"loc,{#10000},4,5,6,13"
locations_default(#20101,#10000,4,5,6,13)
xmllocations(#20100,#20101)
#20102=*
xmlAttrs(#20102,#20094,"type","text/babel",0,#10000)
#20103=@"loc,{#10000},2,13,2,29"
locations_default(#20103,#10000,2,13,2,29)
xmlAttrs(#20102,#20100,"type","text/babel",0,#10000)
#20103=@"loc,{#10000},4,13,4,29"
locations_default(#20103,#10000,4,13,4,29)
xmllocations(#20102,#20103)
#20104=*
xmlAttrs(#20104,#20096,"type","text/jsx",0,#10000)
#20105=@"loc,{#10000},3,13,3,27"
locations_default(#20105,#10000,3,13,3,27)
xmlAttrs(#20104,#20100,"data-plugins","transform-es2015-modules-umd",1,#10000)
#20105=@"loc,{#10000},4,31,4,73"
locations_default(#20105,#10000,4,31,4,73)
xmllocations(#20104,#20105)
#20106=*
xmlAttrs(#20106,#20098,"type","text/babel",0,#10000)
#20107=@"loc,{#10000},4,13,4,29"
locations_default(#20107,#10000,4,13,4,29)
xmlElements(#20106,"script",#20092,1,#10000)
#20107=@"loc,{#10000},3,5,3,47"
locations_default(#20107,#10000,3,5,3,47)
xmllocations(#20106,#20107)
#20108=*
xmlAttrs(#20108,#20098,"data-plugins","transform-es2015-modules-umd",1,#10000)
#20109=@"loc,{#10000},4,31,4,73"
locations_default(#20109,#10000,4,31,4,73)
xmlAttrs(#20108,#20106,"type","text/jsx",0,#10000)
#20109=@"loc,{#10000},3,13,3,27"
locations_default(#20109,#10000,3,13,3,27)
xmllocations(#20108,#20109)
#20110=*
xmlAttrs(#20110,#20100,"type","text/babel",0,#10000)
#20111=@"loc,{#10000},7,13,7,29"
locations_default(#20111,#10000,7,13,7,29)
xmlElements(#20110,"script",#20092,0,#10000)
#20111=@"loc,{#10000},2,5,2,49"
locations_default(#20111,#10000,2,5,2,49)
xmllocations(#20110,#20111)
#20112=*
xmlAttrs(#20112,#20100,"data-plugins","transform-es2015-modules-umd",1,#10000)
#20113=@"loc,{#10000},7,31,7,73"
locations_default(#20113,#10000,7,31,7,73)
xmlAttrs(#20112,#20110,"type","text/babel",0,#10000)
#20113=@"loc,{#10000},2,13,2,29"
locations_default(#20113,#10000,2,13,2,29)
xmllocations(#20112,#20113)
numlines(#10000,10,4,0)
filetype(#10000,"html")

View File

@@ -14,17 +14,17 @@ xmlElements(#20001,"html",#10000,0,#10000)
locations_default(#20002,#10000,2,1,8,7)
xmllocations(#20001,#20002)
#20003=*
xmlElements(#20003,"head",#20001,0,#10000)
#20004=@"loc,{#10000},3,3,6,9"
locations_default(#20004,#10000,3,3,6,9)
xmlElements(#20003,"body",#20001,1,#10000)
#20004=@"loc,{#10000},7,3,7,10"
locations_default(#20004,#10000,7,3,7,10)
xmllocations(#20003,#20004)
#20005=*
xmlElements(#20005,"body",#20001,1,#10000)
#20006=@"loc,{#10000},7,3,7,10"
locations_default(#20006,#10000,7,3,7,10)
xmlElements(#20005,"head",#20001,0,#10000)
#20006=@"loc,{#10000},3,3,6,9"
locations_default(#20006,#10000,3,3,6,9)
xmllocations(#20005,#20006)
#20007=*
xmlElements(#20007,"script",#20003,0,#10000)
xmlElements(#20007,"script",#20005,0,#10000)
#20008=@"loc,{#10000},4,5,5,21"
locations_default(#20008,#10000,4,5,5,21)
xmllocations(#20007,#20008)

View File

@@ -92,29 +92,29 @@ xmlElements(#20025,"html",#10000,0,#10000)
locations_default(#20026,#10000,1,1,8,7)
xmllocations(#20025,#20026)
#20027=*
xmlElements(#20027,"head",#20025,0,#10000)
#20028=@"loc,{#10000},2,1,4,7"
locations_default(#20028,#10000,2,1,4,7)
xmlElements(#20027,"body",#20025,1,#10000)
#20028=@"loc,{#10000},5,1,7,7"
locations_default(#20028,#10000,5,1,7,7)
xmllocations(#20027,#20028)
#20029=*
xmlElements(#20029,"body",#20025,1,#10000)
#20030=@"loc,{#10000},5,1,7,7"
locations_default(#20030,#10000,5,1,7,7)
xmlElements(#20029,"a",#20027,0,#10000)
#20030=@"loc,{#10000},6,1,6,29"
locations_default(#20030,#10000,6,1,6,29)
xmllocations(#20029,#20030)
#20031=*
xmlElements(#20031,"title",#20027,0,#10000)
#20032=@"loc,{#10000},3,1,3,15"
locations_default(#20032,#10000,3,1,3,15)
xmlAttrs(#20031,#20029,"onclick","var x = 42;",0,#10000)
#20032=@"loc,{#10000},6,4,6,24"
locations_default(#20032,#10000,6,4,6,24)
xmllocations(#20031,#20032)
#20033=*
xmlElements(#20033,"a",#20029,0,#10000)
#20034=@"loc,{#10000},6,1,6,29"
locations_default(#20034,#10000,6,1,6,29)
xmlElements(#20033,"head",#20025,0,#10000)
#20034=@"loc,{#10000},2,1,4,7"
locations_default(#20034,#10000,2,1,4,7)
xmllocations(#20033,#20034)
#20035=*
xmlAttrs(#20035,#20033,"onclick","var x = 42;",0,#10000)
#20036=@"loc,{#10000},6,4,6,24"
locations_default(#20036,#10000,6,4,6,24)
xmlElements(#20035,"title",#20033,0,#10000)
#20036=@"loc,{#10000},3,1,3,15"
locations_default(#20036,#10000,3,1,3,15)
xmllocations(#20035,#20036)
numlines(#10000,8,1,0)
filetype(#10000,"html")

View File

@@ -49,17 +49,17 @@ xmlElements(#20013,"html",#10000,0,#10000)
locations_default(#20014,#10000,1,1,10,7)
xmllocations(#20013,#20014)
#20015=*
xmlElements(#20015,"head",#20013,0,#10000)
#20016=@"loc,{#10000},2,5,7,11"
locations_default(#20016,#10000,2,5,7,11)
xmlElements(#20015,"body",#20013,1,#10000)
#20016=@"loc,{#10000},8,5,9,11"
locations_default(#20016,#10000,8,5,9,11)
xmllocations(#20015,#20016)
#20017=*
xmlElements(#20017,"body",#20013,1,#10000)
#20018=@"loc,{#10000},8,5,9,11"
locations_default(#20018,#10000,8,5,9,11)
xmlElements(#20017,"head",#20013,0,#10000)
#20018=@"loc,{#10000},2,5,7,11"
locations_default(#20018,#10000,2,5,7,11)
xmllocations(#20017,#20018)
#20019=*
xmlElements(#20019,"script",#20015,0,#10000)
xmlElements(#20019,"script",#20017,0,#10000)
#20020=@"loc,{#10000},3,9,6,17"
locations_default(#20020,#10000,3,9,6,17)
xmllocations(#20019,#20020)