Merge tag 'codeql-cli/latest' into auto/sync-main-pr

Compatible with the latest released version of the CodeQL CLI
This commit is contained in:
github-actions[bot]
2025-04-08 23:27:08 +00:00
3131 changed files with 73764 additions and 38658 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add support for quoted string, intersection and subtraction
compatibility: backwards

View File

@@ -0,0 +1,37 @@
// Removes all nodes nested inside a qualified type access,
// and changes qualified type access nodes to "named type" nodes.
//
/*
* jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
* int kind: int ref,
* int parent: @jsdoc_type_expr_parent ref,
* int idx: int ref,
* varchar(900) tostring: string ref);
*/
class JSDocTypeExprParent extends @jsdoc_type_expr_parent {
string toString() { none() }
}
class JSDocTypeExpr extends @jsdoc_type_expr {
string toString() { none() }
JSDocTypeExpr getChild(int n) { jsdoc_type_exprs(result, _, this, n, _) }
int getNewKind() { jsdoc_type_exprs(this, result, _, _, _) }
predicate shouldRemove() { this = any(JSDocQualifiedTypeAccess a).getChild(_) }
}
class JSDocQualifiedTypeAccess extends @jsdoc_qualified_type_expr, JSDocTypeExpr {
override int getNewKind() {
result = 5
/* 5 = @jsdoc_named_type_expr */
}
}
from JSDocTypeExpr node, JSDocTypeExprParent parent, int idx, string tostring
where
jsdoc_type_exprs(node, _, parent, idx, tostring) and
not node.shouldRemove()
select node, node.getNewKind(), parent, idx, tostring

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: split up qualified names in jsdoc type exprs
compatibility: backwards
jsdoc_type_exprs.rel: run jsdoc_type_exprs.ql

View File

@@ -6,7 +6,7 @@
"": {
"name": "typescript-parser-wrapper",
"dependencies": {
"typescript": "^5.7.2"
"typescript": "^5.8.2"
},
"devDependencies": {
"@types/node": "18.15.3"
@@ -20,9 +20,9 @@
"license": "MIT"
},
"node_modules/typescript": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
"version": "5.8.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",

View File

@@ -2,7 +2,7 @@
"name": "typescript-parser-wrapper",
"private": true,
"dependencies": {
"typescript": "^5.7.2"
"typescript": "^5.8.2"
},
"scripts": {
"build": "tsc --project tsconfig.json",

View File

@@ -69,4 +69,9 @@ public class MemberExpression extends Expression
public void setSymbol(int symbol) {
this.symbol = symbol;
}
@Override
public boolean isValidTypeExpression() {
return object instanceof ITypeExpression && ((ITypeExpression)object).isValidTypeExpression() || object instanceof DynamicImport;
}
}

View File

@@ -2,12 +2,12 @@ package com.semmle.js.ast.jsdoc;
import com.semmle.js.ast.SourceLocation;
/** A named JSDoc type. */
public class NameExpression extends JSDocTypeExpression {
/** An identifier in a JSDoc type. */
public class Identifier extends JSDocTypeExpression {
private final String name;
public NameExpression(SourceLocation loc, String name) {
super(loc, "NameExpression");
public Identifier(SourceLocation loc, String name) {
super(loc, "Identifier");
this.name = name;
}

View File

@@ -0,0 +1,35 @@
package com.semmle.js.ast.jsdoc;
import com.semmle.js.ast.SourceLocation;
/** A qualified name in a JSDoc type. */
public class QualifiedNameExpression extends JSDocTypeExpression {
private final JSDocTypeExpression base;
private final Identifier name;
public QualifiedNameExpression(SourceLocation loc, JSDocTypeExpression base, Identifier name) {
super(loc, "QualifiedNameExpression");
this.base = base;
this.name = name;
}
@Override
public void accept(Visitor v) {
v.visit(this);
}
/** Returns the expression on the left side of the dot character. */
public JSDocTypeExpression getBase() {
return base;
}
/** Returns the identifier on the right-hand side of the dot character. */
public Identifier getNameNode() {
return name;
}
@Override
public String pp() {
return base.pp() + "." + name.pp();
}
}

View File

@@ -10,7 +10,9 @@ public interface Visitor {
public void visit(JSDocTag nd);
public void visit(NameExpression nd);
public void visit(Identifier nd);
public void visit(QualifiedNameExpression nd);
public void visit(NullableLiteral nd);

View File

@@ -0,0 +1,26 @@
package com.semmle.js.ast.regexp;
import com.semmle.js.ast.SourceLocation;
import java.util.List;
/**
* A character class intersection in a regular expression available only with the `v` flag.
* Example: [[abc]&&[ab]&&[b]] matches character `b` only.
*/
public class CharacterClassIntersection extends RegExpTerm {
private final List<RegExpTerm> elements;
public CharacterClassIntersection(SourceLocation loc, List<RegExpTerm> elements) {
super(loc, "CharacterClassIntersection");
this.elements = elements;
}
@Override
public void accept(Visitor v) {
v.visit(this);
}
public List<RegExpTerm> getElements() {
return elements;
}
}

View File

@@ -0,0 +1,28 @@
package com.semmle.js.ast.regexp;
import com.semmle.js.ast.SourceLocation;
/**
* A quoted string escape sequence '\q{}' in a regular expression.
* This feature is a non-standard extension that requires the 'v' flag.
*
* Example: [\q{abc|def}] creates a character class that matches either the string
* "abc" or "def". Within the quoted string, only the alternation operator '|' is supported.
*/
public class CharacterClassQuotedString extends RegExpTerm {
private final RegExpTerm term;
public CharacterClassQuotedString(SourceLocation loc, RegExpTerm term) {
super(loc, "CharacterClassQuotedString");
this.term = term;
}
public RegExpTerm getTerm() {
return term;
}
@Override
public void accept(Visitor v) {
v.visit(this);
}
}

View File

@@ -0,0 +1,26 @@
package com.semmle.js.ast.regexp;
import com.semmle.js.ast.SourceLocation;
import java.util.List;
/**
* A character class subtraction in a regular expression available only with the `v` flag.
* Example: [[abc]--[a]--[b]] matches character `c` only.
*/
public class CharacterClassSubtraction extends RegExpTerm {
private final List<RegExpTerm> elements;
public CharacterClassSubtraction(SourceLocation loc, List<RegExpTerm> elements) {
super(loc, "CharacterClassSubtraction");
this.elements = elements;
}
@Override
public void accept(Visitor v) {
v.visit(this);
}
public List<RegExpTerm> getElements() {
return elements;
}
}

View File

@@ -61,4 +61,10 @@ public interface Visitor {
public void visit(ZeroWidthNegativeLookbehind nd);
public void visit(UnicodePropertyEscape nd);
public void visit(CharacterClassQuotedString nd);
public void visit(CharacterClassIntersection nd);
public void visit(CharacterClassSubtraction nd);
}

View File

@@ -600,7 +600,7 @@ public class ASTExtractor {
SourceMap sourceMap =
SourceMap.legacyWithStartPos(
SourceMap.fromString(nd.getRaw()).offsetBy(0, offsets), startPos);
regexpExtractor.extract(source.substring(1, source.lastIndexOf('/')), sourceMap, nd, false);
regexpExtractor.extract(source.substring(1, source.lastIndexOf('/')), sourceMap, nd, false, source.substring(source.lastIndexOf('/'), source.length()));
} else if (nd.isStringLiteral()
&& !c.isInsideType()
&& nd.getRaw().length() < 1000

View File

@@ -160,6 +160,9 @@ import com.semmle.util.trap.TrapWriter;
* is of the form "codeql-javascript-*.json".
* <li>JavaScript, JSON or YAML files whose base name starts with ".eslintrc".
* <li>JSON files whose base name is ".xsaccess".
* <li>JSON files whose base name is "xs-app.json".
* <li>JSON files whose base name ends with ".view.json".
* <li>JSON files whose base name is "manifest.json".
* <li>All extension-less files.
* </ul>
*
@@ -394,10 +397,12 @@ public class AutoBuild {
for (FileType filetype : defaultExtract)
for (String extension : filetype.getExtensions()) patterns.add("**/*" + extension);
// include .eslintrc files, .xsaccess files, package.json files,
// tsconfig.json files, and codeql-javascript-*.json files
// include JSON files which are relevant to our analysis
patterns.add("**/.eslintrc*");
patterns.add("**/.xsaccess");
patterns.add("**/.xsaccess"); // SAP XSJS
patterns.add("**/xs-app.json"); // SAP XSJS
patterns.add("**/*.view.json"); // SAP UI5
patterns.add("**/manifest.json");
patterns.add("**/package.json");
patterns.add("**/tsconfig*.json");
patterns.add("**/codeql-javascript-*.json");

View File

@@ -9,13 +9,14 @@ import com.semmle.js.ast.jsdoc.JSDocComment;
import com.semmle.js.ast.jsdoc.JSDocElement;
import com.semmle.js.ast.jsdoc.JSDocTag;
import com.semmle.js.ast.jsdoc.JSDocTypeExpression;
import com.semmle.js.ast.jsdoc.NameExpression;
import com.semmle.js.ast.jsdoc.Identifier;
import com.semmle.js.ast.jsdoc.NonNullableType;
import com.semmle.js.ast.jsdoc.NullLiteral;
import com.semmle.js.ast.jsdoc.NullableLiteral;
import com.semmle.js.ast.jsdoc.NullableType;
import com.semmle.js.ast.jsdoc.OptionalType;
import com.semmle.js.ast.jsdoc.ParameterType;
import com.semmle.js.ast.jsdoc.QualifiedNameExpression;
import com.semmle.js.ast.jsdoc.RecordType;
import com.semmle.js.ast.jsdoc.RestType;
import com.semmle.js.ast.jsdoc.TypeApplication;
@@ -42,7 +43,7 @@ public class JSDocExtractor {
jsdocTypeExprKinds.put("UndefinedLiteral", 2);
jsdocTypeExprKinds.put("NullableLiteral", 3);
jsdocTypeExprKinds.put("VoidLiteral", 4);
jsdocTypeExprKinds.put("NameExpression", 5);
jsdocTypeExprKinds.put("Identifier", 5);
jsdocTypeExprKinds.put("TypeApplication", 6);
jsdocTypeExprKinds.put("NullableType", 7);
jsdocTypeExprKinds.put("NonNullableType", 8);
@@ -52,6 +53,7 @@ public class JSDocExtractor {
jsdocTypeExprKinds.put("FunctionType", 12);
jsdocTypeExprKinds.put("OptionalType", 13);
jsdocTypeExprKinds.put("RestType", 14);
jsdocTypeExprKinds.put("QualifiedNameExpression", 15);
}
private final TrapWriter trapwriter;
@@ -122,10 +124,17 @@ public class JSDocExtractor {
}
@Override
public void visit(NameExpression nd) {
public void visit(Identifier nd) {
visit((JSDocTypeExpression) nd);
}
@Override
public void visit(QualifiedNameExpression nd) {
Label label = visit((JSDocTypeExpression) nd);
visit(nd.getBase(), label, 0);
visit(nd.getNameNode(), label, 1);
}
@Override
public void visit(NullableLiteral nd) {
visit((JSDocTypeExpression) nd);

View File

@@ -42,7 +42,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 = "2025-02-03";
public static final String EXTRACTOR_VERSION = "2025-03-20";
public static final Pattern NEWLINE = Pattern.compile("\n");

View File

@@ -10,7 +10,9 @@ import com.semmle.js.ast.regexp.BackReference;
import com.semmle.js.ast.regexp.Caret;
import com.semmle.js.ast.regexp.CharacterClass;
import com.semmle.js.ast.regexp.CharacterClassEscape;
import com.semmle.js.ast.regexp.CharacterClassQuotedString;
import com.semmle.js.ast.regexp.CharacterClassRange;
import com.semmle.js.ast.regexp.CharacterClassSubtraction;
import com.semmle.js.ast.regexp.Constant;
import com.semmle.js.ast.regexp.ControlEscape;
import com.semmle.js.ast.regexp.ControlLetter;
@@ -22,6 +24,7 @@ import com.semmle.js.ast.regexp.Error;
import com.semmle.js.ast.regexp.Group;
import com.semmle.js.ast.regexp.HexEscapeSequence;
import com.semmle.js.ast.regexp.IdentityEscape;
import com.semmle.js.ast.regexp.CharacterClassIntersection;
import com.semmle.js.ast.regexp.Literal;
import com.semmle.js.ast.regexp.NamedBackReference;
import com.semmle.js.ast.regexp.NonWordBoundary;
@@ -92,6 +95,9 @@ public class RegExpExtractor {
termkinds.put("ZeroWidthPositiveLookbehind", 25);
termkinds.put("ZeroWidthNegativeLookbehind", 26);
termkinds.put("UnicodePropertyEscape", 27);
termkinds.put("CharacterClassQuotedString", 28);
termkinds.put("CharacterClassIntersection", 29);
termkinds.put("CharacterClassSubtraction", 30);
}
private static final String[] errmsgs =
@@ -344,10 +350,32 @@ public class RegExpExtractor {
visit(nd.getLeft(), lbl, 0);
visit(nd.getRight(), lbl, 1);
}
@Override
public void visit(CharacterClassQuotedString nd) {
Label lbl = extractTerm(nd, parent, idx);
visit(nd.getTerm(), lbl, 0);
}
@Override
public void visit(CharacterClassIntersection nd) {
Label lbl = extractTerm(nd, parent, idx);
int i = 0;
for (RegExpTerm element : nd.getElements())
visit(element, lbl, i++);
}
@Override
public void visit(CharacterClassSubtraction nd) {
Label lbl = extractTerm(nd, parent, idx);
int i = 0;
for (RegExpTerm element : nd.getElements())
visit(element, lbl, i++);
}
}
public void extract(String src, SourceMap sourceMap, Node parent, boolean isSpeculativeParsing) {
Result res = parser.parse(src);
public void extract(String src, SourceMap sourceMap, Node parent, boolean isSpeculativeParsing, String flags) {
Result res = parser.parse(src, flags);
if (isSpeculativeParsing && res.getErrors().size() > 0) {
return;
}
@@ -364,4 +392,8 @@ public class RegExpExtractor {
this.emitLocation(err, lbl);
}
}
public void extract(String src, SourceMap sourceMap, Node parent, boolean isSpeculativeParsing) {
extract(src, sourceMap, parent, isSpeculativeParsing, "");
}
}

View File

@@ -10,13 +10,14 @@ import com.semmle.js.ast.jsdoc.FunctionType;
import com.semmle.js.ast.jsdoc.JSDocComment;
import com.semmle.js.ast.jsdoc.JSDocTag;
import com.semmle.js.ast.jsdoc.JSDocTypeExpression;
import com.semmle.js.ast.jsdoc.NameExpression;
import com.semmle.js.ast.jsdoc.Identifier;
import com.semmle.js.ast.jsdoc.NonNullableType;
import com.semmle.js.ast.jsdoc.NullLiteral;
import com.semmle.js.ast.jsdoc.NullableLiteral;
import com.semmle.js.ast.jsdoc.NullableType;
import com.semmle.js.ast.jsdoc.OptionalType;
import com.semmle.js.ast.jsdoc.ParameterType;
import com.semmle.js.ast.jsdoc.QualifiedNameExpression;
import com.semmle.js.ast.jsdoc.RecordType;
import com.semmle.js.ast.jsdoc.RestType;
import com.semmle.js.ast.jsdoc.TypeApplication;
@@ -70,30 +71,6 @@ public class JSDocParser {
return new JSDocComment(comment, r.fst(), tags);
}
/** Specification of Doctrine AST types for JSDoc type expressions. */
private static final Map<Class<? extends JSDocTypeExpression>, List<String>> spec =
new LinkedHashMap<Class<? extends JSDocTypeExpression>, List<String>>();
static {
spec.put(AllLiteral.class, Arrays.<String>asList());
spec.put(ArrayType.class, Arrays.asList("elements"));
spec.put(FieldType.class, Arrays.asList("key", "value"));
spec.put(FunctionType.class, Arrays.asList("this", "new", "params", "result"));
spec.put(NameExpression.class, Arrays.asList("name"));
spec.put(NonNullableType.class, Arrays.asList("expression", "prefix"));
spec.put(NullableLiteral.class, Arrays.<String>asList());
spec.put(NullLiteral.class, Arrays.<String>asList());
spec.put(NullableType.class, Arrays.asList("expression", "prefix"));
spec.put(OptionalType.class, Arrays.asList("expression"));
spec.put(ParameterType.class, Arrays.asList("name", "expression"));
spec.put(RecordType.class, Arrays.asList("fields"));
spec.put(RestType.class, Arrays.asList("expression"));
spec.put(TypeApplication.class, Arrays.asList("expression", "applications"));
spec.put(UndefinedLiteral.class, Arrays.<String>asList());
spec.put(UnionType.class, Arrays.asList("elements"));
spec.put(VoidLiteral.class, Arrays.<String>asList());
}
private static String sliceSource(String source, int index, int last) {
if (index >= source.length()) return "";
if (last > source.length()) last = source.length();
@@ -137,7 +114,7 @@ public class JSDocParser {
}
private static boolean isTypeName(char ch) {
return "><(){}[],:*|?!=".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
return "><(){}[],:*|?!=.".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
}
private static boolean isParamTitle(String title) {
@@ -559,21 +536,12 @@ public class JSDocParser {
}
private Token scanTypeName() {
char ch, ch2;
value = new String(Character.toChars(advance()));
StringBuilder sb = new StringBuilder();
sb.append((char)advance());
while (index < endIndex && isTypeName(source.charAt(index))) {
ch = source.charAt(index);
if (ch == '.') {
if ((index + 1) < endIndex) {
ch2 = source.charAt(index + 1);
if (ch2 == '<') {
break;
}
}
}
value += new String(Character.toChars(advance()));
sb.append((char)advance());
}
value = sb.toString();
return Token.NAME;
}
@@ -848,11 +816,24 @@ public class JSDocParser {
return finishNode(new RecordType(loc, fields));
}
private JSDocTypeExpression parseNameExpression() throws ParseError {
Object name = value;
private Identifier parseIdentifier() throws ParseError {
SourceLocation loc = loc();
Object value = this.value; // save the value of the current token
expect(Token.NAME);
return finishNode(new NameExpression(loc, name.toString()));
return finishNode(new Identifier(loc, value.toString()));
}
private JSDocTypeExpression parseNameExpression() throws ParseError {
JSDocTypeExpression node = parseIdentifier();
while (token == Token.DOT) {
consume(Token.DOT);
Identifier memberName = parseIdentifier();
// Create a SourceLocation object with the correct start location.
// The call to finishNode() will set the end location.
SourceLocation loc = new SourceLocation(node.getLoc());
node = finishNode(new QualifiedNameExpression(loc, node, memberName));
}
return node;
}
// TypeExpressionList :=
@@ -945,14 +926,14 @@ public class JSDocParser {
SourceLocation loc = loc();
expr = parseTypeExpression();
if (expr instanceof NameExpression && token == Token.COLON) {
if (expr instanceof Identifier && token == Token.COLON) {
// Identifier ':' TypeExpression
consume(Token.COLON);
expr =
finishNode(
new ParameterType(
new SourceLocation(loc),
((NameExpression) expr).getName(),
((Identifier) expr).getName(),
parseTypeExpression()));
}
if (token == Token.EQUAL) {
@@ -1128,7 +1109,7 @@ public class JSDocParser {
consume(Token.RBRACK, "expected an array-style type declaration (' + value + '[])");
List<JSDocTypeExpression> expressions = new ArrayList<>();
expressions.add(expr);
NameExpression nameExpr = finishNode(new NameExpression(new SourceLocation(loc), "Array"));
Identifier nameExpr = finishNode(new Identifier(new SourceLocation(loc), "Array"));
return finishNode(new TypeApplication(loc, nameExpr, expressions));
}
@@ -1549,9 +1530,9 @@ public class JSDocParser {
// fixed at the end
if (isParamTitle(this._title)
&& this._tag.type != null
&& this._tag.type instanceof NameExpression) {
this._extra_name = ((NameExpression) this._tag.type).getName();
this._tag.name = ((NameExpression) this._tag.type).getName();
&& this._tag.type instanceof Identifier) {
this._extra_name = ((Identifier) this._tag.type).getName();
this._tag.name = ((Identifier) this._tag.type).getName();
this._tag.type = null;
} else {
if (!this.addError("Missing or invalid tag name")) {
@@ -1667,7 +1648,7 @@ public class JSDocParser {
Position start = new Position(_tag.startLine, _tag.startColumn, _tag.startColumn);
Position end = new Position(_tag.startLine, _tag.startColumn, _tag.startColumn);
SourceLocation loc = new SourceLocation(_extra_name, start, end);
this._tag.type = new NameExpression(loc, _extra_name);
this._tag.type = new Identifier(loc, _extra_name);
}
this._tag.name = null;

View File

@@ -6,7 +6,9 @@ import com.semmle.js.ast.regexp.BackReference;
import com.semmle.js.ast.regexp.Caret;
import com.semmle.js.ast.regexp.CharacterClass;
import com.semmle.js.ast.regexp.CharacterClassEscape;
import com.semmle.js.ast.regexp.CharacterClassQuotedString;
import com.semmle.js.ast.regexp.CharacterClassRange;
import com.semmle.js.ast.regexp.CharacterClassSubtraction;
import com.semmle.js.ast.regexp.Constant;
import com.semmle.js.ast.regexp.ControlEscape;
import com.semmle.js.ast.regexp.ControlLetter;
@@ -18,6 +20,7 @@ import com.semmle.js.ast.regexp.Error;
import com.semmle.js.ast.regexp.Group;
import com.semmle.js.ast.regexp.HexEscapeSequence;
import com.semmle.js.ast.regexp.IdentityEscape;
import com.semmle.js.ast.regexp.CharacterClassIntersection;
import com.semmle.js.ast.regexp.NamedBackReference;
import com.semmle.js.ast.regexp.NonWordBoundary;
import com.semmle.js.ast.regexp.OctalEscape;
@@ -36,6 +39,7 @@ import com.semmle.js.ast.regexp.ZeroWidthPositiveLookahead;
import com.semmle.js.ast.regexp.ZeroWidthPositiveLookbehind;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/** A parser for ECMAScript 2018 regular expressions. */
@@ -67,6 +71,8 @@ public class RegExpParser {
private List<Error> errors;
private List<BackReference> backrefs;
private int maxbackref;
private boolean vFlagEnabled = false;
private boolean uFlagEnabled = false;
/** Parse the given string as a regular expression. */
public Result parse(String src) {
@@ -82,6 +88,12 @@ public class RegExpParser {
return new Result(root, errors);
}
public Result parse(String src, String flags) {
vFlagEnabled = flags != null && flags.contains("v");
uFlagEnabled = flags != null && flags.contains("u");
return parse(src);
}
private static String fromCodePoint(int codepoint) {
if (Character.isValidCodePoint(codepoint)) return new String(Character.toChars(codepoint));
// replacement character
@@ -277,6 +289,43 @@ public class RegExpParser {
return this.finishTerm(this.parseQuantifierOpt(loc, this.parseAtom()));
}
private RegExpTerm parseDisjunctionInsideQuotedString() {
SourceLocation loc = new SourceLocation(pos());
List<RegExpTerm> disjuncts = new ArrayList<>();
disjuncts.add(this.parseAlternativeInsideQuotedString());
while (this.match("|")) {
disjuncts.add(this.parseAlternativeInsideQuotedString());
}
if (disjuncts.size() == 1) return disjuncts.get(0);
return this.finishTerm(new Disjunction(loc, disjuncts));
}
private RegExpTerm parseAlternativeInsideQuotedString() {
SourceLocation loc = new SourceLocation(pos());
int startPos = this.pos;
boolean escaped = false;
while (true) {
// If we're at the end of the string, something went wrong.
if (this.atEOS()) {
this.error(Error.UNEXPECTED_EOS);
break;
}
// We can end parsing if we're not escaped and we see a `|` which would mean Alternation
// or `}` which would mean the end of the Quoted String.
if(!escaped && this.lookahead(null, "|", "}")){
break;
}
char c = this.nextChar();
// Track whether the character is an escape character.
escaped = !escaped && (c == '\\');
}
String literal = src.substring(startPos, pos);
loc.setEnd(pos());
loc.setSource(literal);
return new Constant(loc, literal);
}
private RegExpTerm parseQuantifierOpt(SourceLocation loc, RegExpTerm atom) {
if (this.match("*")) return this.finishTerm(new Star(loc, atom, !this.match("?")));
if (this.match("+")) return this.finishTerm(new Plus(loc, atom, !this.match("?")));
@@ -421,7 +470,13 @@ public class RegExpParser {
return this.finishTerm(new NamedBackReference(loc, name, "\\k<" + name + ">"));
}
if (this.match("p{", "P{")) {
if (vFlagEnabled && this.match("q{")) {
RegExpTerm term = parseDisjunctionInsideQuotedString();
this.expectRBrace();
return this.finishTerm(new CharacterClassQuotedString(loc, term));
}
if ((vFlagEnabled || uFlagEnabled) && this.match("p{", "P{")) {
String name = this.readIdentifier();
if (this.match("=")) {
value = this.readIdentifier();
@@ -493,6 +548,7 @@ public class RegExpParser {
}
private RegExpTerm parseCharacterClass() {
if (vFlagEnabled) return parseNestedCharacterClass();
SourceLocation loc = new SourceLocation(pos());
List<RegExpTerm> elements = new ArrayList<>();
@@ -508,6 +564,43 @@ public class RegExpParser {
return this.finishTerm(new CharacterClass(loc, elements, inverted));
}
private enum CharacterClassType {
STANDARD,
INTERSECTION,
SUBTRACTION
}
// ECMA 2024 `v` flag allows nested character classes.
private RegExpTerm parseNestedCharacterClass() {
SourceLocation loc = new SourceLocation(pos());
List<RegExpTerm> elements = new ArrayList<>();
CharacterClassType classType = CharacterClassType.STANDARD;
this.match("[");
boolean inverted = this.match("^");
while (!this.match("]")) {
if (this.atEOS()) {
this.error(Error.EXPECTED_RBRACKET);
break;
}
if (lookahead("[")) elements.add(parseNestedCharacterClass());
else if (this.match("&&")) classType = CharacterClassType.INTERSECTION;
else if (this.match("--")) classType = CharacterClassType.SUBTRACTION;
else elements.add(this.parseCharacterClassElement());
}
// Create appropriate RegExpTerm based on the detected class type
switch (classType) {
case INTERSECTION:
return this.finishTerm(new CharacterClass(loc, Collections.singletonList(new CharacterClassIntersection(loc, elements)), inverted));
case SUBTRACTION:
return this.finishTerm(new CharacterClass(loc, Collections.singletonList(new CharacterClassSubtraction(loc, elements)), inverted));
case STANDARD:
default:
return this.finishTerm(new CharacterClass(loc, elements, inverted));
}
}
private static final List<String> escapeClasses = Arrays.asList("d", "D", "s", "S", "w", "W");
private RegExpTerm parseCharacterClassElement() {
@@ -519,7 +612,7 @@ public class RegExpParser {
return atom;
}
}
if (!this.lookahead("-]") && this.match("-") && !(atom instanceof CharacterClassEscape))
if (!this.lookahead("-]") && !this.lookahead("--") && this.match("-") && !(atom instanceof CharacterClassEscape))
return this.finishTerm(new CharacterClassRange(loc, atom, this.parseCharacterClassAtom()));
return atom;
}

View File

@@ -10,4 +10,6 @@ import com.semmle.js.ast.Literal;
* however, some expressions such as {@link Literal} type may occur in a type annotation because the
* TypeScript AST does not distinguish <code>null</code> literals from the <code>null</code> type.
*/
public interface ITypeExpression extends INode, ITypedAstNode {}
public interface ITypeExpression extends INode, ITypedAstNode {
public default boolean isValidTypeExpression() { return true; }
}

View File

@@ -1907,7 +1907,7 @@ public class TypeScriptASTConverter {
}
private ITypeExpression asType(Node node) {
return node instanceof ITypeExpression ? (ITypeExpression) node : null;
return node instanceof ITypeExpression && ((ITypeExpression)node).isValidTypeExpression() ? (ITypeExpression) node : null;
}
private List<ITypeExpression> convertChildrenAsTypes(JsonObject node, String child)

View File

@@ -517,150 +517,170 @@ jsdoc_type_exprs(#20157,4,#20145,-1,"void")
locations_default(#20158,#10000,11,60,11,63)
hasLocation(#20157,#20158)
#20159=*
jsdoc_type_exprs(#20159,5,#20145,-2,"goog.ui.Menu")
jsdoc_type_exprs(#20159,15,#20145,-2,"goog.ui.Menu")
#20160=@"loc,{#10000},11,26,11,37"
locations_default(#20160,#10000,11,26,11,37)
hasLocation(#20159,#20160)
jsdoc_has_new_parameter(#20145)
#20161=*
jsdoc_tags(#20161,"param",#20117,4,"@param")
#20162=@"loc,{#10000},12,5,12,10"
locations_default(#20162,#10000,12,5,12,10)
jsdoc_type_exprs(#20161,15,#20159,0,"goog.ui")
#20162=@"loc,{#10000},11,26,11,32"
locations_default(#20162,#10000,11,26,11,32)
hasLocation(#20161,#20162)
jsdoc_tag_names(#20161,"var_args")
#20163=*
jsdoc_type_exprs(#20163,14,#20161,0,"...number")
#20164=@"loc,{#10000},12,13,12,21"
locations_default(#20164,#10000,12,13,12,21)
jsdoc_type_exprs(#20163,5,#20161,0,"goog")
#20164=@"loc,{#10000},11,26,11,29"
locations_default(#20164,#10000,11,26,11,29)
hasLocation(#20163,#20164)
#20165=*
jsdoc_type_exprs(#20165,5,#20163,0,"number")
#20166=@"loc,{#10000},12,16,12,21"
locations_default(#20166,#10000,12,16,12,21)
jsdoc_type_exprs(#20165,5,#20161,1,"ui")
#20166=@"loc,{#10000},11,31,11,32"
locations_default(#20166,#10000,11,31,11,32)
hasLocation(#20165,#20166)
#20167=*
jsdoc(#20167,"",#20010)
hasLocation(#20167,#20011)
#20168=*
jsdoc_tags(#20168,"param",#20167,0,"@param")
#20169=@"loc,{#10000},15,4,15,9"
locations_default(#20169,#10000,15,4,15,9)
hasLocation(#20168,#20169)
#20170=*
jsdoc_errors(#20170,#20168,"Missing or invalid tag name","Missing ... ag name")
jsdoc_type_exprs(#20167,5,#20159,1,"Menu")
#20168=@"loc,{#10000},11,34,11,37"
locations_default(#20168,#10000,11,34,11,37)
hasLocation(#20167,#20168)
jsdoc_has_new_parameter(#20145)
#20169=*
jsdoc_tags(#20169,"param",#20117,4,"@param")
#20170=@"loc,{#10000},12,5,12,10"
locations_default(#20170,#10000,12,5,12,10)
hasLocation(#20169,#20170)
jsdoc_tag_names(#20169,"var_args")
#20171=*
jsdoc_tags(#20171,"param",#20167,1,"@param")
#20172=@"loc,{#10000},16,4,16,9"
locations_default(#20172,#10000,16,4,16,9)
jsdoc_type_exprs(#20171,14,#20169,0,"...number")
#20172=@"loc,{#10000},12,13,12,21"
locations_default(#20172,#10000,12,13,12,21)
hasLocation(#20171,#20172)
jsdoc_tag_names(#20171,"x")
#20173=*
jsdoc(#20173,"",#20012)
hasLocation(#20173,#20013)
#20174=*
jsdoc_tags(#20174,"",#20173,0,"@")
#20175=@"loc,{#10000},20,4,20,4"
locations_default(#20175,#10000,20,4,20,4)
hasLocation(#20174,#20175)
jsdoc_tag_descriptions(#20174,"{link a}")
jsdoc_type_exprs(#20173,5,#20171,0,"number")
#20174=@"loc,{#10000},12,16,12,21"
locations_default(#20174,#10000,12,16,12,21)
hasLocation(#20173,#20174)
#20175=*
jsdoc(#20175,"",#20010)
hasLocation(#20175,#20011)
#20176=*
jsdoc_errors(#20176,#20174,"Missing or invalid title","Missing ... d title")
#20177=*
jsdoc(#20177,"",#20014)
hasLocation(#20177,#20015)
jsdoc_tags(#20176,"param",#20175,0,"@param")
#20177=@"loc,{#10000},15,4,15,9"
locations_default(#20177,#10000,15,4,15,9)
hasLocation(#20176,#20177)
#20178=*
jsdoc_tags(#20178,"typedef",#20177,0,"@typedef")
#20179=@"loc,{#10000},24,4,24,11"
locations_default(#20179,#10000,24,4,24,11)
hasLocation(#20178,#20179)
jsdoc_tag_descriptions(#20178,"{a}")
#20180=*
jsdoc_errors(#20180,#20178,"Missing or invalid tag type","Missing ... ag type")
jsdoc_errors(#20178,#20176,"Missing or invalid tag name","Missing ... ag name")
#20179=*
jsdoc_tags(#20179,"param",#20175,1,"@param")
#20180=@"loc,{#10000},16,4,16,9"
locations_default(#20180,#10000,16,4,16,9)
hasLocation(#20179,#20180)
jsdoc_tag_names(#20179,"x")
#20181=*
jsdoc(#20181,"[resize description]",#20016)
hasLocation(#20181,#20017)
jsdoc(#20181,"",#20012)
hasLocation(#20181,#20013)
#20182=*
jsdoc_tags(#20182,"param",#20181,0,"@param")
#20183=@"loc,{#10000},30,4,30,9"
locations_default(#20183,#10000,30,4,30,9)
jsdoc_tags(#20182,"",#20181,0,"@")
#20183=@"loc,{#10000},20,4,20,4"
locations_default(#20183,#10000,20,4,20,4)
hasLocation(#20182,#20183)
jsdoc_tag_descriptions(#20182,"[description]
")
jsdoc_tag_names(#20182,"w")
jsdoc_tag_descriptions(#20182,"{link a}")
#20184=*
jsdoc_type_exprs(#20184,10,#20182,0,"[type]")
#20185=@"loc,{#10000},30,13,30,18"
locations_default(#20185,#10000,30,13,30,18)
hasLocation(#20184,#20185)
jsdoc_errors(#20184,#20182,"Missing or invalid title","Missing ... d title")
#20185=*
jsdoc(#20185,"",#20014)
hasLocation(#20185,#20015)
#20186=*
jsdoc_type_exprs(#20186,5,#20184,0,"type")
#20187=@"loc,{#10000},30,14,30,17"
locations_default(#20187,#10000,30,14,30,17)
jsdoc_tags(#20186,"typedef",#20185,0,"@typedef")
#20187=@"loc,{#10000},24,4,24,11"
locations_default(#20187,#10000,24,4,24,11)
hasLocation(#20186,#20187)
jsdoc_tag_descriptions(#20186,"{a}")
#20188=*
jsdoc_tags(#20188,"param",#20181,1,"@param")
#20189=@"loc,{#10000},31,4,31,9"
locations_default(#20189,#10000,31,4,31,9)
hasLocation(#20188,#20189)
jsdoc_tag_descriptions(#20188,"[description]
")
jsdoc_errors(#20188,#20186,"Missing or invalid tag type","Missing ... ag type")
#20189=*
jsdoc(#20189,"[resize description]",#20016)
hasLocation(#20189,#20017)
#20190=*
jsdoc_tags(#20190,"return",#20181,2,"@return")
#20191=@"loc,{#10000},32,4,32,10"
locations_default(#20191,#10000,32,4,32,10)
jsdoc_tags(#20190,"param",#20189,0,"@param")
#20191=@"loc,{#10000},30,4,30,9"
locations_default(#20191,#10000,30,4,30,9)
hasLocation(#20190,#20191)
jsdoc_tag_descriptions(#20190,"[description]")
jsdoc_tag_descriptions(#20190,"[description]
")
jsdoc_tag_names(#20190,"w")
#20192=*
jsdoc_type_exprs(#20192,10,#20190,0,"[type]")
#20193=@"loc,{#10000},32,13,32,18"
locations_default(#20193,#10000,32,13,32,18)
#20193=@"loc,{#10000},30,13,30,18"
locations_default(#20193,#10000,30,13,30,18)
hasLocation(#20192,#20193)
#20194=*
jsdoc_type_exprs(#20194,5,#20192,0,"type")
#20195=@"loc,{#10000},32,14,32,17"
locations_default(#20195,#10000,32,14,32,17)
#20195=@"loc,{#10000},30,14,30,17"
locations_default(#20195,#10000,30,14,30,17)
hasLocation(#20194,#20195)
#20196=*
jsdoc(#20196,"",#20018)
hasLocation(#20196,#20019)
#20197=*
jsdoc_tags(#20197,"exports",#20196,0,"@exports")
#20198=@"loc,{#10000},36,3,36,10"
locations_default(#20198,#10000,36,3,36,10)
hasLocation(#20197,#20198)
jsdoc_tag_descriptions(#20197,"R
jsdoc_tags(#20196,"param",#20189,1,"@param")
#20197=@"loc,{#10000},31,4,31,9"
locations_default(#20197,#10000,31,4,31,9)
hasLocation(#20196,#20197)
jsdoc_tag_descriptions(#20196,"[description]
")
#20199=*
jsdoc(#20199,"",#20020)
hasLocation(#20199,#20021)
#20198=*
jsdoc_tags(#20198,"return",#20189,2,"@return")
#20199=@"loc,{#10000},32,4,32,10"
locations_default(#20199,#10000,32,4,32,10)
hasLocation(#20198,#20199)
jsdoc_tag_descriptions(#20198,"[description]")
#20200=*
jsdoc_tags(#20200,"typedef",#20199,0,"@typedef")
#20201=@"loc,{#10000},41,4,41,11"
locations_default(#20201,#10000,41,4,41,11)
jsdoc_type_exprs(#20200,10,#20198,0,"[type]")
#20201=@"loc,{#10000},32,13,32,18"
locations_default(#20201,#10000,32,13,32,18)
hasLocation(#20200,#20201)
#20202=*
jsdoc_type_exprs(#20202,9,#20200,0,"{0: number}")
#20203=@"loc,{#10000},41,14,41,24"
locations_default(#20203,#10000,41,14,41,24)
jsdoc_type_exprs(#20202,5,#20200,0,"type")
#20203=@"loc,{#10000},32,14,32,17"
locations_default(#20203,#10000,32,14,32,17)
hasLocation(#20202,#20203)
jsdoc_record_field_name(#20202,0,"0")
#20204=*
jsdoc_type_exprs(#20204,5,#20202,0,"number")
#20205=@"loc,{#10000},41,18,41,23"
locations_default(#20205,#10000,41,18,41,23)
hasLocation(#20204,#20205)
toplevels(#20001,0)
#20206=@"loc,{#10000},1,1,43,0"
locations_default(#20206,#10000,1,1,43,0)
hasLocation(#20001,#20206)
jsdoc(#20204,"",#20018)
hasLocation(#20204,#20019)
#20205=*
jsdoc_tags(#20205,"exports",#20204,0,"@exports")
#20206=@"loc,{#10000},36,3,36,10"
locations_default(#20206,#10000,36,3,36,10)
hasLocation(#20205,#20206)
jsdoc_tag_descriptions(#20205,"R
")
#20207=*
entry_cfg_node(#20207,#20001)
#20208=@"loc,{#10000},1,1,1,0"
locations_default(#20208,#10000,1,1,1,0)
hasLocation(#20207,#20208)
#20209=*
exit_cfg_node(#20209,#20001)
hasLocation(#20209,#20105)
successor(#20207,#20209)
jsdoc(#20207,"",#20020)
hasLocation(#20207,#20021)
#20208=*
jsdoc_tags(#20208,"typedef",#20207,0,"@typedef")
#20209=@"loc,{#10000},41,4,41,11"
locations_default(#20209,#10000,41,4,41,11)
hasLocation(#20208,#20209)
#20210=*
jsdoc_type_exprs(#20210,9,#20208,0,"{0: number}")
#20211=@"loc,{#10000},41,14,41,24"
locations_default(#20211,#10000,41,14,41,24)
hasLocation(#20210,#20211)
jsdoc_record_field_name(#20210,0,"0")
#20212=*
jsdoc_type_exprs(#20212,5,#20210,0,"number")
#20213=@"loc,{#10000},41,18,41,23"
locations_default(#20213,#10000,41,18,41,23)
hasLocation(#20212,#20213)
toplevels(#20001,0)
#20214=@"loc,{#10000},1,1,43,0"
locations_default(#20214,#10000,1,1,43,0)
hasLocation(#20001,#20214)
#20215=*
entry_cfg_node(#20215,#20001)
#20216=@"loc,{#10000},1,1,1,0"
locations_default(#20216,#10000,1,1,1,0)
hasLocation(#20215,#20216)
#20217=*
exit_cfg_node(#20217,#20001)
hasLocation(#20217,#20105)
successor(#20215,#20217)
numlines(#10000,42,0,37)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,2 @@
/^p(ost)?[ |\.]*o(ffice)?[ |\.]*(box)?[ 0-9]*[^[a-z ]]*/g;
/([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)+X/;

View File

@@ -0,0 +1,7 @@
/[[abc]&&[bcd]]/v; // Valid use of intersection operator, matches b or c
/abc&&bcd/v; //Valid regex, but no intersection operation: Matches the literal string "abc&&bcd"
/[abc]&&[bcd]/v; // Valid regex, but incorrect intersection operation:
// - Matches a single character from [abc]
// - Then the literal "&&"
// - Then a single character from [bcd]
/[[abc]&&[bcd]&&[c]]/v; // Valid use of intersection operator, matches c

View File

@@ -0,0 +1,3 @@
/[[]]/v; //Previously not allowed to nest character classes now completely valid with v flag.
/[[a]]/v;
/[ [] [ [] [] ] ]/v;

View File

@@ -0,0 +1,5 @@
/[\q{abc}]/v;
/[\q{abc|cbd|dcb}]/v;
/[\q{\}}]/v;
/[\q{\{}]/v;
/[\q{cc|\}a|cc}]/v;

View File

@@ -0,0 +1,3 @@
/[\p{Script_Extensions=Greek}--\p{Letter}]/v;
/[[abc]--[cbd]]/v;
/[[abc]--[cbd]--[bde]]/v;

View File

@@ -0,0 +1 @@
const regex = /\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|\b[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)/gmv;

View File

@@ -0,0 +1,6 @@
/[\p{Script_Extensions=Greek}\p{RGI_Emoji}]/v;
/[[abc][cbd]]/v;
/[\p{Emoji}\q{a&}byz]/v;
/[\q{\\\}a&}byz]/v;
/[\q{\\}]/v;
/[\q{abc|cbd|\}}]/v;

View File

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

View File

@@ -0,0 +1,546 @@
#10000=@"/additional_test_cases.js;sourcefile"
files(#10000,"/additional_test_cases.js")
#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=*
lines(#20002,#20001,"/^p(ost)?[ |\.]*o(ffice)?[ |\.]*(box)?[ 0-9]*[^[a-z ]]*/g;","
")
#20003=@"loc,{#10000},1,1,1,58"
locations_default(#20003,#10000,1,1,1,58)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"/([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)+X/;","
")
#20005=@"loc,{#10000},2,1,2,47"
locations_default(#20005,#10000,2,1,2,47)
hasLocation(#20004,#20005)
numlines(#20001,2,2,0)
#20006=*
tokeninfo(#20006,5,#20001,0,"/^p(ost)?[ |\.]*o(ffice)?[ |\.]*(box)?[ 0-9]*[^[a-z ]]*/g")
#20007=@"loc,{#10000},1,1,1,57"
locations_default(#20007,#10000,1,1,1,57)
hasLocation(#20006,#20007)
#20008=*
tokeninfo(#20008,8,#20001,1,";")
#20009=@"loc,{#10000},1,58,1,58"
locations_default(#20009,#10000,1,58,1,58)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,5,#20001,2,"/([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)+X/")
#20011=@"loc,{#10000},2,1,2,46"
locations_default(#20011,#10000,2,1,2,46)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,8,#20001,3,";")
#20013=@"loc,{#10000},2,47,2,47"
locations_default(#20013,#10000,2,47,2,47)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,0,#20001,4,"")
#20015=@"loc,{#10000},3,1,3,0"
locations_default(#20015,#10000,3,1,3,0)
hasLocation(#20014,#20015)
toplevels(#20001,0)
#20016=@"loc,{#10000},1,1,3,0"
locations_default(#20016,#10000,1,1,3,0)
hasLocation(#20001,#20016)
#20017=*
stmts(#20017,2,#20001,0,"/^p(ost ... ]]*/g;")
hasLocation(#20017,#20003)
stmt_containers(#20017,#20001)
#20018=*
exprs(#20018,5,#20017,0,"/^p(ost ... z ]]*/g")
hasLocation(#20018,#20007)
enclosing_stmt(#20018,#20017)
expr_containers(#20018,#20001)
literals("/^p(ost)?[ |\.]*o(ffice)?[ |\.]*(box)?[ 0-9]*[^[a-z ]]*/g","/^p(ost)?[ |\.]*o(ffice)?[ |\.]*(box)?[ 0-9]*[^[a-z ]]*/g",#20018)
#20019=*
regexpterm(#20019,1,#20018,0,"^p(ost)?[ |\.]*o(ffice)?[ |\.]*(box)?[ 0-9]*[^[a-z ]]*")
#20020=@"loc,{#10000},1,2,1,55"
locations_default(#20020,#10000,1,2,1,55)
hasLocation(#20019,#20020)
#20021=*
regexpterm(#20021,2,#20019,0,"^")
#20022=@"loc,{#10000},1,2,1,2"
locations_default(#20022,#10000,1,2,1,2)
hasLocation(#20021,#20022)
#20023=*
regexpterm(#20023,14,#20019,1,"p")
#20024=@"loc,{#10000},1,3,1,3"
locations_default(#20024,#10000,1,3,1,3)
hasLocation(#20023,#20024)
regexp_const_value(#20023,"p")
#20025=*
regexpterm(#20025,10,#20019,2,"(ost)?")
#20026=@"loc,{#10000},1,4,1,9"
locations_default(#20026,#10000,1,4,1,9)
hasLocation(#20025,#20026)
is_greedy(#20025)
#20027=*
regexpterm(#20027,13,#20025,0,"(ost)")
#20028=@"loc,{#10000},1,4,1,8"
locations_default(#20028,#10000,1,4,1,8)
hasLocation(#20027,#20028)
is_capture(#20027,1)
#20029=*
regexpterm(#20029,14,#20027,0,"ost")
#20030=@"loc,{#10000},1,5,1,7"
locations_default(#20030,#10000,1,5,1,7)
hasLocation(#20029,#20030)
regexp_const_value(#20029,"ost")
#20031=*
regexpterm(#20031,8,#20019,3,"[ |\.]*")
#20032=@"loc,{#10000},1,10,1,16"
locations_default(#20032,#10000,1,10,1,16)
hasLocation(#20031,#20032)
is_greedy(#20031)
#20033=*
regexpterm(#20033,23,#20031,0,"[ |\.]")
#20034=@"loc,{#10000},1,10,1,15"
locations_default(#20034,#10000,1,10,1,15)
hasLocation(#20033,#20034)
#20035=*
regexpterm(#20035,14,#20033,0," ")
#20036=@"loc,{#10000},1,11,1,11"
locations_default(#20036,#10000,1,11,1,11)
hasLocation(#20035,#20036)
regexp_const_value(#20035," ")
#20037=*
regexpterm(#20037,14,#20033,1,"|")
#20038=@"loc,{#10000},1,12,1,12"
locations_default(#20038,#10000,1,12,1,12)
hasLocation(#20037,#20038)
regexp_const_value(#20037,"|")
#20039=*
regexpterm(#20039,21,#20033,2,"\.")
#20040=@"loc,{#10000},1,13,1,14"
locations_default(#20040,#10000,1,13,1,14)
hasLocation(#20039,#20040)
regexp_const_value(#20039,".")
#20041=*
regexpterm(#20041,14,#20019,4,"o")
#20042=@"loc,{#10000},1,17,1,17"
locations_default(#20042,#10000,1,17,1,17)
hasLocation(#20041,#20042)
regexp_const_value(#20041,"o")
#20043=*
regexpterm(#20043,10,#20019,5,"(ffice)?")
#20044=@"loc,{#10000},1,18,1,25"
locations_default(#20044,#10000,1,18,1,25)
hasLocation(#20043,#20044)
is_greedy(#20043)
#20045=*
regexpterm(#20045,13,#20043,0,"(ffice)")
#20046=@"loc,{#10000},1,18,1,24"
locations_default(#20046,#10000,1,18,1,24)
hasLocation(#20045,#20046)
is_capture(#20045,2)
#20047=*
regexpterm(#20047,14,#20045,0,"ffice")
#20048=@"loc,{#10000},1,19,1,23"
locations_default(#20048,#10000,1,19,1,23)
hasLocation(#20047,#20048)
regexp_const_value(#20047,"ffice")
#20049=*
regexpterm(#20049,8,#20019,6,"[ |\.]*")
#20050=@"loc,{#10000},1,26,1,32"
locations_default(#20050,#10000,1,26,1,32)
hasLocation(#20049,#20050)
is_greedy(#20049)
#20051=*
regexpterm(#20051,23,#20049,0,"[ |\.]")
#20052=@"loc,{#10000},1,26,1,31"
locations_default(#20052,#10000,1,26,1,31)
hasLocation(#20051,#20052)
#20053=*
regexpterm(#20053,14,#20051,0," ")
#20054=@"loc,{#10000},1,27,1,27"
locations_default(#20054,#10000,1,27,1,27)
hasLocation(#20053,#20054)
regexp_const_value(#20053," ")
#20055=*
regexpterm(#20055,14,#20051,1,"|")
#20056=@"loc,{#10000},1,28,1,28"
locations_default(#20056,#10000,1,28,1,28)
hasLocation(#20055,#20056)
regexp_const_value(#20055,"|")
#20057=*
regexpterm(#20057,21,#20051,2,"\.")
#20058=@"loc,{#10000},1,29,1,30"
locations_default(#20058,#10000,1,29,1,30)
hasLocation(#20057,#20058)
regexp_const_value(#20057,".")
#20059=*
regexpterm(#20059,10,#20019,7,"(box)?")
#20060=@"loc,{#10000},1,33,1,38"
locations_default(#20060,#10000,1,33,1,38)
hasLocation(#20059,#20060)
is_greedy(#20059)
#20061=*
regexpterm(#20061,13,#20059,0,"(box)")
#20062=@"loc,{#10000},1,33,1,37"
locations_default(#20062,#10000,1,33,1,37)
hasLocation(#20061,#20062)
is_capture(#20061,3)
#20063=*
regexpterm(#20063,14,#20061,0,"box")
#20064=@"loc,{#10000},1,34,1,36"
locations_default(#20064,#10000,1,34,1,36)
hasLocation(#20063,#20064)
regexp_const_value(#20063,"box")
#20065=*
regexpterm(#20065,8,#20019,8,"[ 0-9]*")
#20066=@"loc,{#10000},1,39,1,45"
locations_default(#20066,#10000,1,39,1,45)
hasLocation(#20065,#20066)
is_greedy(#20065)
#20067=*
regexpterm(#20067,23,#20065,0,"[ 0-9]")
#20068=@"loc,{#10000},1,39,1,44"
locations_default(#20068,#10000,1,39,1,44)
hasLocation(#20067,#20068)
#20069=*
regexpterm(#20069,14,#20067,0," ")
#20070=@"loc,{#10000},1,40,1,40"
locations_default(#20070,#10000,1,40,1,40)
hasLocation(#20069,#20070)
regexp_const_value(#20069," ")
#20071=*
regexpterm(#20071,24,#20067,1,"0-9")
#20072=@"loc,{#10000},1,41,1,43"
locations_default(#20072,#10000,1,41,1,43)
hasLocation(#20071,#20072)
#20073=*
regexpterm(#20073,14,#20071,0,"0")
#20074=@"loc,{#10000},1,41,1,41"
locations_default(#20074,#10000,1,41,1,41)
hasLocation(#20073,#20074)
regexp_const_value(#20073,"0")
#20075=*
regexpterm(#20075,14,#20071,1,"9")
#20076=@"loc,{#10000},1,43,1,43"
locations_default(#20076,#10000,1,43,1,43)
hasLocation(#20075,#20076)
regexp_const_value(#20075,"9")
#20077=*
regexpterm(#20077,23,#20019,9,"[^[a-z ]")
#20078=@"loc,{#10000},1,46,1,53"
locations_default(#20078,#10000,1,46,1,53)
hasLocation(#20077,#20078)
is_inverted(#20077)
#20079=*
regexpterm(#20079,14,#20077,0,"[")
#20080=@"loc,{#10000},1,48,1,48"
locations_default(#20080,#10000,1,48,1,48)
hasLocation(#20079,#20080)
regexp_const_value(#20079,"[")
#20081=*
regexpterm(#20081,24,#20077,1,"a-z")
#20082=@"loc,{#10000},1,49,1,51"
locations_default(#20082,#10000,1,49,1,51)
hasLocation(#20081,#20082)
#20083=*
regexpterm(#20083,14,#20081,0,"a")
#20084=@"loc,{#10000},1,49,1,49"
locations_default(#20084,#10000,1,49,1,49)
hasLocation(#20083,#20084)
regexp_const_value(#20083,"a")
#20085=*
regexpterm(#20085,14,#20081,1,"z")
#20086=@"loc,{#10000},1,51,1,51"
locations_default(#20086,#10000,1,51,1,51)
hasLocation(#20085,#20086)
regexp_const_value(#20085,"z")
#20087=*
regexpterm(#20087,14,#20077,2," ")
#20088=@"loc,{#10000},1,52,1,52"
locations_default(#20088,#10000,1,52,1,52)
hasLocation(#20087,#20088)
regexp_const_value(#20087," ")
#20089=*
regexpterm(#20089,8,#20019,10,"]*")
#20090=@"loc,{#10000},1,54,1,55"
locations_default(#20090,#10000,1,54,1,55)
hasLocation(#20089,#20090)
is_greedy(#20089)
#20091=*
regexpterm(#20091,14,#20089,0,"]")
#20092=@"loc,{#10000},1,54,1,54"
locations_default(#20092,#10000,1,54,1,54)
hasLocation(#20091,#20092)
regexp_const_value(#20091,"]")
#20093=*
regexp_parse_errors(#20093,#20019,"unexpected character")
hasLocation(#20093,#20092)
#20094=*
stmts(#20094,2,#20001,1,"/([ ]*[ ... ]+)+X/;")
hasLocation(#20094,#20005)
stmt_containers(#20094,#20001)
#20095=*
exprs(#20095,5,#20094,0,"/([ ]*[ ... -]+)+X/")
hasLocation(#20095,#20011)
enclosing_stmt(#20095,#20094)
expr_containers(#20095,#20001)
literals("/([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)+X/","/([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)+X/",#20095)
#20096=*
regexpterm(#20096,1,#20095,0,"([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)+X")
#20097=@"loc,{#10000},2,2,2,45"
locations_default(#20097,#10000,2,2,2,45)
hasLocation(#20096,#20097)
#20098=*
regexpterm(#20098,9,#20096,0,"([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)+")
#20099=@"loc,{#10000},2,2,2,44"
locations_default(#20099,#10000,2,2,2,44)
hasLocation(#20098,#20099)
is_greedy(#20098)
#20100=*
regexpterm(#20100,13,#20098,0,"([ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+)")
#20101=@"loc,{#10000},2,2,2,43"
locations_default(#20101,#10000,2,2,2,43)
hasLocation(#20100,#20101)
is_capture(#20100,1)
#20102=*
regexpterm(#20102,1,#20100,0,"[ ]*[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+")
#20103=@"loc,{#10000},2,3,2,42"
locations_default(#20103,#10000,2,3,2,42)
hasLocation(#20102,#20103)
#20104=*
regexpterm(#20104,8,#20102,0,"[ ]*")
#20105=@"loc,{#10000},2,3,2,6"
locations_default(#20105,#10000,2,3,2,6)
hasLocation(#20104,#20105)
is_greedy(#20104)
#20106=*
regexpterm(#20106,23,#20104,0,"[ ]")
#20107=@"loc,{#10000},2,3,2,5"
locations_default(#20107,#10000,2,3,2,5)
hasLocation(#20106,#20107)
#20108=*
regexpterm(#20108,14,#20106,0," ")
#20109=@"loc,{#10000},2,4,2,4"
locations_default(#20109,#10000,2,4,2,4)
hasLocation(#20108,#20109)
regexp_const_value(#20108," ")
#20110=*
regexpterm(#20110,9,#20102,1,"[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]+")
#20111=@"loc,{#10000},2,7,2,42"
locations_default(#20111,#10000,2,7,2,42)
hasLocation(#20110,#20111)
is_greedy(#20110)
#20112=*
regexpterm(#20112,23,#20110,0,"[a-z0-9&#*=?@\\><:,()$[\]_.{}!+%^-]")
#20113=@"loc,{#10000},2,7,2,41"
locations_default(#20113,#10000,2,7,2,41)
hasLocation(#20112,#20113)
#20114=*
regexpterm(#20114,24,#20112,0,"a-z")
#20115=@"loc,{#10000},2,8,2,10"
locations_default(#20115,#10000,2,8,2,10)
hasLocation(#20114,#20115)
#20116=*
regexpterm(#20116,14,#20114,0,"a")
#20117=@"loc,{#10000},2,8,2,8"
locations_default(#20117,#10000,2,8,2,8)
hasLocation(#20116,#20117)
regexp_const_value(#20116,"a")
#20118=*
regexpterm(#20118,14,#20114,1,"z")
#20119=@"loc,{#10000},2,10,2,10"
locations_default(#20119,#10000,2,10,2,10)
hasLocation(#20118,#20119)
regexp_const_value(#20118,"z")
#20120=*
regexpterm(#20120,24,#20112,1,"0-9")
#20121=@"loc,{#10000},2,11,2,13"
locations_default(#20121,#10000,2,11,2,13)
hasLocation(#20120,#20121)
#20122=*
regexpterm(#20122,14,#20120,0,"0")
#20123=@"loc,{#10000},2,11,2,11"
locations_default(#20123,#10000,2,11,2,11)
hasLocation(#20122,#20123)
regexp_const_value(#20122,"0")
#20124=*
regexpterm(#20124,14,#20120,1,"9")
#20125=@"loc,{#10000},2,13,2,13"
locations_default(#20125,#10000,2,13,2,13)
hasLocation(#20124,#20125)
regexp_const_value(#20124,"9")
#20126=*
regexpterm(#20126,14,#20112,2,"&")
#20127=@"loc,{#10000},2,14,2,14"
locations_default(#20127,#10000,2,14,2,14)
hasLocation(#20126,#20127)
regexp_const_value(#20126,"&")
#20128=*
regexpterm(#20128,14,#20112,3,"#")
#20129=@"loc,{#10000},2,15,2,15"
locations_default(#20129,#10000,2,15,2,15)
hasLocation(#20128,#20129)
regexp_const_value(#20128,"#")
#20130=*
regexpterm(#20130,14,#20112,4,"*")
#20131=@"loc,{#10000},2,16,2,16"
locations_default(#20131,#10000,2,16,2,16)
hasLocation(#20130,#20131)
regexp_const_value(#20130,"*")
#20132=*
regexpterm(#20132,14,#20112,5,"=")
#20133=@"loc,{#10000},2,17,2,17"
locations_default(#20133,#10000,2,17,2,17)
hasLocation(#20132,#20133)
regexp_const_value(#20132,"=")
#20134=*
regexpterm(#20134,14,#20112,6,"?")
#20135=@"loc,{#10000},2,18,2,18"
locations_default(#20135,#10000,2,18,2,18)
hasLocation(#20134,#20135)
regexp_const_value(#20134,"?")
#20136=*
regexpterm(#20136,14,#20112,7,"@")
#20137=@"loc,{#10000},2,19,2,19"
locations_default(#20137,#10000,2,19,2,19)
hasLocation(#20136,#20137)
regexp_const_value(#20136,"@")
#20138=*
regexpterm(#20138,21,#20112,8,"\\")
#20139=@"loc,{#10000},2,20,2,21"
locations_default(#20139,#10000,2,20,2,21)
hasLocation(#20138,#20139)
regexp_const_value(#20138,"\")
#20140=*
regexpterm(#20140,14,#20112,9,">")
#20141=@"loc,{#10000},2,22,2,22"
locations_default(#20141,#10000,2,22,2,22)
hasLocation(#20140,#20141)
regexp_const_value(#20140,">")
#20142=*
regexpterm(#20142,14,#20112,10,"<")
#20143=@"loc,{#10000},2,23,2,23"
locations_default(#20143,#10000,2,23,2,23)
hasLocation(#20142,#20143)
regexp_const_value(#20142,"<")
#20144=*
regexpterm(#20144,14,#20112,11,":")
#20145=@"loc,{#10000},2,24,2,24"
locations_default(#20145,#10000,2,24,2,24)
hasLocation(#20144,#20145)
regexp_const_value(#20144,":")
#20146=*
regexpterm(#20146,14,#20112,12,",")
#20147=@"loc,{#10000},2,25,2,25"
locations_default(#20147,#10000,2,25,2,25)
hasLocation(#20146,#20147)
regexp_const_value(#20146,",")
#20148=*
regexpterm(#20148,14,#20112,13,"(")
#20149=@"loc,{#10000},2,26,2,26"
locations_default(#20149,#10000,2,26,2,26)
hasLocation(#20148,#20149)
regexp_const_value(#20148,"(")
#20150=*
regexpterm(#20150,14,#20112,14,")")
#20151=@"loc,{#10000},2,27,2,27"
locations_default(#20151,#10000,2,27,2,27)
hasLocation(#20150,#20151)
regexp_const_value(#20150,")")
#20152=*
regexpterm(#20152,14,#20112,15,"$")
#20153=@"loc,{#10000},2,28,2,28"
locations_default(#20153,#10000,2,28,2,28)
hasLocation(#20152,#20153)
regexp_const_value(#20152,"$")
#20154=*
regexpterm(#20154,14,#20112,16,"[")
#20155=@"loc,{#10000},2,29,2,29"
locations_default(#20155,#10000,2,29,2,29)
hasLocation(#20154,#20155)
regexp_const_value(#20154,"[")
#20156=*
regexpterm(#20156,21,#20112,17,"\]")
#20157=@"loc,{#10000},2,30,2,31"
locations_default(#20157,#10000,2,30,2,31)
hasLocation(#20156,#20157)
regexp_const_value(#20156,"]")
#20158=*
regexpterm(#20158,14,#20112,18,"_")
#20159=@"loc,{#10000},2,32,2,32"
locations_default(#20159,#10000,2,32,2,32)
hasLocation(#20158,#20159)
regexp_const_value(#20158,"_")
#20160=*
regexpterm(#20160,14,#20112,19,".")
#20161=@"loc,{#10000},2,33,2,33"
locations_default(#20161,#10000,2,33,2,33)
hasLocation(#20160,#20161)
regexp_const_value(#20160,".")
#20162=*
regexpterm(#20162,14,#20112,20,"{")
#20163=@"loc,{#10000},2,34,2,34"
locations_default(#20163,#10000,2,34,2,34)
hasLocation(#20162,#20163)
regexp_const_value(#20162,"{")
#20164=*
regexpterm(#20164,14,#20112,21,"}")
#20165=@"loc,{#10000},2,35,2,35"
locations_default(#20165,#10000,2,35,2,35)
hasLocation(#20164,#20165)
regexp_const_value(#20164,"}")
#20166=*
regexpterm(#20166,14,#20112,22,"!")
#20167=@"loc,{#10000},2,36,2,36"
locations_default(#20167,#10000,2,36,2,36)
hasLocation(#20166,#20167)
regexp_const_value(#20166,"!")
#20168=*
regexpterm(#20168,14,#20112,23,"+")
#20169=@"loc,{#10000},2,37,2,37"
locations_default(#20169,#10000,2,37,2,37)
hasLocation(#20168,#20169)
regexp_const_value(#20168,"+")
#20170=*
regexpterm(#20170,14,#20112,24,"%")
#20171=@"loc,{#10000},2,38,2,38"
locations_default(#20171,#10000,2,38,2,38)
hasLocation(#20170,#20171)
regexp_const_value(#20170,"%")
#20172=*
regexpterm(#20172,14,#20112,25,"^")
#20173=@"loc,{#10000},2,39,2,39"
locations_default(#20173,#10000,2,39,2,39)
hasLocation(#20172,#20173)
regexp_const_value(#20172,"^")
#20174=*
regexpterm(#20174,14,#20112,26,"-")
#20175=@"loc,{#10000},2,40,2,40"
locations_default(#20175,#10000,2,40,2,40)
hasLocation(#20174,#20175)
regexp_const_value(#20174,"-")
#20176=*
regexpterm(#20176,14,#20096,1,"X")
#20177=@"loc,{#10000},2,45,2,45"
locations_default(#20177,#10000,2,45,2,45)
hasLocation(#20176,#20177)
regexp_const_value(#20176,"X")
#20178=*
entry_cfg_node(#20178,#20001)
#20179=@"loc,{#10000},1,1,1,0"
locations_default(#20179,#10000,1,1,1,0)
hasLocation(#20178,#20179)
#20180=*
exit_cfg_node(#20180,#20001)
hasLocation(#20180,#20015)
successor(#20094,#20095)
successor(#20095,#20180)
successor(#20017,#20018)
successor(#20018,#20094)
successor(#20178,#20017)
numlines(#10000,2,2,0)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,397 @@
#10000=@"/intersection.js;sourcefile"
files(#10000,"/intersection.js")
#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," Valid use of intersection operator, matches b or c","// Vali ... b or c")
#20003=@"loc,{#10000},1,20,1,72"
locations_default(#20003,#10000,1,20,1,72)
hasLocation(#20002,#20003)
#20004=*
comments(#20004,0,#20001,"Valid regex, but no intersection operation: Matches the literal string ""abc&&bcd""","//Valid ... c&&bcd""")
#20005=@"loc,{#10000},2,14,2,96"
locations_default(#20005,#10000,2,14,2,96)
hasLocation(#20004,#20005)
#20006=*
comments(#20006,0,#20001," Valid regex, but incorrect intersection operation: ","// Vali ... ation: ")
#20007=@"loc,{#10000},3,18,3,71"
locations_default(#20007,#10000,3,18,3,71)
hasLocation(#20006,#20007)
#20008=*
comments(#20008,0,#20001," - Matches a single character from [abc]","// - Ma ... m [abc]")
#20009=@"loc,{#10000},4,18,4,59"
locations_default(#20009,#10000,4,18,4,59)
hasLocation(#20008,#20009)
#20010=*
comments(#20010,0,#20001," - Then the literal ""&&""","// - Th ... al ""&&""")
#20011=@"loc,{#10000},5,18,5,43"
locations_default(#20011,#10000,5,18,5,43)
hasLocation(#20010,#20011)
#20012=*
comments(#20012,0,#20001," - Then a single character from [bcd]","// - Th ... m [bcd]")
#20013=@"loc,{#10000},6,18,6,56"
locations_default(#20013,#10000,6,18,6,56)
hasLocation(#20012,#20013)
#20014=*
comments(#20014,0,#20001," Valid use of intersection operator, matches c","// Vali ... tches c")
#20015=@"loc,{#10000},7,25,7,72"
locations_default(#20015,#10000,7,25,7,72)
hasLocation(#20014,#20015)
#20016=*
lines(#20016,#20001,"/[[abc]&&[bcd]]/v; // Valid use of intersection operator, matches b or c","
")
#20017=@"loc,{#10000},1,1,1,72"
locations_default(#20017,#10000,1,1,1,72)
hasLocation(#20016,#20017)
#20018=*
lines(#20018,#20001,"/abc&&bcd/v; //Valid regex, but no intersection operation: Matches the literal string ""abc&&bcd""","
")
#20019=@"loc,{#10000},2,1,2,96"
locations_default(#20019,#10000,2,1,2,96)
hasLocation(#20018,#20019)
#20020=*
lines(#20020,#20001,"/[abc]&&[bcd]/v; // Valid regex, but incorrect intersection operation: ","
")
#20021=@"loc,{#10000},3,1,3,71"
locations_default(#20021,#10000,3,1,3,71)
hasLocation(#20020,#20021)
#20022=*
lines(#20022,#20001," // - Matches a single character from [abc]","
")
#20023=@"loc,{#10000},4,1,4,59"
locations_default(#20023,#10000,4,1,4,59)
hasLocation(#20022,#20023)
indentation(#10000,4," ",17)
#20024=*
lines(#20024,#20001," // - Then the literal ""&&""","
")
#20025=@"loc,{#10000},5,1,5,43"
locations_default(#20025,#10000,5,1,5,43)
hasLocation(#20024,#20025)
indentation(#10000,5," ",17)
#20026=*
lines(#20026,#20001," // - Then a single character from [bcd]","
")
#20027=@"loc,{#10000},6,1,6,56"
locations_default(#20027,#10000,6,1,6,56)
hasLocation(#20026,#20027)
indentation(#10000,6," ",17)
#20028=*
lines(#20028,#20001,"/[[abc]&&[bcd]&&[c]]/v; // Valid use of intersection operator, matches c","
")
#20029=@"loc,{#10000},7,1,7,72"
locations_default(#20029,#10000,7,1,7,72)
hasLocation(#20028,#20029)
numlines(#20001,7,4,7)
#20030=*
tokeninfo(#20030,5,#20001,0,"/[[abc]&&[bcd]]/v")
#20031=@"loc,{#10000},1,1,1,17"
locations_default(#20031,#10000,1,1,1,17)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,8,#20001,1,";")
#20033=@"loc,{#10000},1,18,1,18"
locations_default(#20033,#10000,1,18,1,18)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,5,#20001,2,"/abc&&bcd/v")
#20035=@"loc,{#10000},2,1,2,11"
locations_default(#20035,#10000,2,1,2,11)
hasLocation(#20034,#20035)
next_token(#20002,#20034)
#20036=*
tokeninfo(#20036,8,#20001,3,";")
#20037=@"loc,{#10000},2,12,2,12"
locations_default(#20037,#10000,2,12,2,12)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,5,#20001,4,"/[abc]&&[bcd]/v")
#20039=@"loc,{#10000},3,1,3,15"
locations_default(#20039,#10000,3,1,3,15)
hasLocation(#20038,#20039)
next_token(#20004,#20038)
#20040=*
tokeninfo(#20040,8,#20001,5,";")
#20041=@"loc,{#10000},3,16,3,16"
locations_default(#20041,#10000,3,16,3,16)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,5,#20001,6,"/[[abc]&&[bcd]&&[c]]/v")
#20043=@"loc,{#10000},7,1,7,22"
locations_default(#20043,#10000,7,1,7,22)
hasLocation(#20042,#20043)
next_token(#20006,#20042)
next_token(#20008,#20042)
next_token(#20010,#20042)
next_token(#20012,#20042)
#20044=*
tokeninfo(#20044,8,#20001,7,";")
#20045=@"loc,{#10000},7,23,7,23"
locations_default(#20045,#10000,7,23,7,23)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,0,#20001,8,"")
#20047=@"loc,{#10000},8,1,8,0"
locations_default(#20047,#10000,8,1,8,0)
hasLocation(#20046,#20047)
next_token(#20014,#20046)
toplevels(#20001,0)
#20048=@"loc,{#10000},1,1,8,0"
locations_default(#20048,#10000,1,1,8,0)
hasLocation(#20001,#20048)
#20049=*
stmts(#20049,2,#20001,0,"/[[abc]&&[bcd]]/v;")
#20050=@"loc,{#10000},1,1,1,18"
locations_default(#20050,#10000,1,1,1,18)
hasLocation(#20049,#20050)
stmt_containers(#20049,#20001)
#20051=*
exprs(#20051,5,#20049,0,"/[[abc]&&[bcd]]/v")
hasLocation(#20051,#20031)
enclosing_stmt(#20051,#20049)
expr_containers(#20051,#20001)
literals("/[[abc]&&[bcd]]/v","/[[abc]&&[bcd]]/v",#20051)
#20052=*
regexpterm(#20052,23,#20051,0,"[[abc]&&[bcd]]")
#20053=@"loc,{#10000},1,2,1,15"
locations_default(#20053,#10000,1,2,1,15)
hasLocation(#20052,#20053)
#20054=*
regexpterm(#20054,29,#20052,0,"[[abc]&&[bcd]]")
hasLocation(#20054,#20053)
#20055=*
regexpterm(#20055,23,#20054,0,"[abc]")
#20056=@"loc,{#10000},1,3,1,7"
locations_default(#20056,#10000,1,3,1,7)
hasLocation(#20055,#20056)
#20057=*
regexpterm(#20057,14,#20055,0,"a")
#20058=@"loc,{#10000},1,4,1,4"
locations_default(#20058,#10000,1,4,1,4)
hasLocation(#20057,#20058)
regexp_const_value(#20057,"a")
#20059=*
regexpterm(#20059,14,#20055,1,"b")
#20060=@"loc,{#10000},1,5,1,5"
locations_default(#20060,#10000,1,5,1,5)
hasLocation(#20059,#20060)
regexp_const_value(#20059,"b")
#20061=*
regexpterm(#20061,14,#20055,2,"c")
#20062=@"loc,{#10000},1,6,1,6"
locations_default(#20062,#10000,1,6,1,6)
hasLocation(#20061,#20062)
regexp_const_value(#20061,"c")
#20063=*
regexpterm(#20063,23,#20054,1,"[bcd]")
#20064=@"loc,{#10000},1,10,1,14"
locations_default(#20064,#10000,1,10,1,14)
hasLocation(#20063,#20064)
#20065=*
regexpterm(#20065,14,#20063,0,"b")
#20066=@"loc,{#10000},1,11,1,11"
locations_default(#20066,#10000,1,11,1,11)
hasLocation(#20065,#20066)
regexp_const_value(#20065,"b")
#20067=*
regexpterm(#20067,14,#20063,1,"c")
#20068=@"loc,{#10000},1,12,1,12"
locations_default(#20068,#10000,1,12,1,12)
hasLocation(#20067,#20068)
regexp_const_value(#20067,"c")
#20069=*
regexpterm(#20069,14,#20063,2,"d")
#20070=@"loc,{#10000},1,13,1,13"
locations_default(#20070,#10000,1,13,1,13)
hasLocation(#20069,#20070)
regexp_const_value(#20069,"d")
#20071=*
stmts(#20071,2,#20001,1,"/abc&&bcd/v;")
#20072=@"loc,{#10000},2,1,2,12"
locations_default(#20072,#10000,2,1,2,12)
hasLocation(#20071,#20072)
stmt_containers(#20071,#20001)
#20073=*
exprs(#20073,5,#20071,0,"/abc&&bcd/v")
hasLocation(#20073,#20035)
enclosing_stmt(#20073,#20071)
expr_containers(#20073,#20001)
literals("/abc&&bcd/v","/abc&&bcd/v",#20073)
#20074=*
regexpterm(#20074,14,#20073,0,"abc&&bcd")
#20075=@"loc,{#10000},2,2,2,9"
locations_default(#20075,#10000,2,2,2,9)
hasLocation(#20074,#20075)
regexp_const_value(#20074,"abc&&bcd")
#20076=*
stmts(#20076,2,#20001,2,"/[abc]&&[bcd]/v;")
#20077=@"loc,{#10000},3,1,3,16"
locations_default(#20077,#10000,3,1,3,16)
hasLocation(#20076,#20077)
stmt_containers(#20076,#20001)
#20078=*
exprs(#20078,5,#20076,0,"/[abc]&&[bcd]/v")
hasLocation(#20078,#20039)
enclosing_stmt(#20078,#20076)
expr_containers(#20078,#20001)
literals("/[abc]&&[bcd]/v","/[abc]&&[bcd]/v",#20078)
#20079=*
regexpterm(#20079,1,#20078,0,"[abc]&&[bcd]")
#20080=@"loc,{#10000},3,2,3,13"
locations_default(#20080,#10000,3,2,3,13)
hasLocation(#20079,#20080)
#20081=*
regexpterm(#20081,23,#20079,0,"[abc]")
#20082=@"loc,{#10000},3,2,3,6"
locations_default(#20082,#10000,3,2,3,6)
hasLocation(#20081,#20082)
#20083=*
regexpterm(#20083,14,#20081,0,"a")
#20084=@"loc,{#10000},3,3,3,3"
locations_default(#20084,#10000,3,3,3,3)
hasLocation(#20083,#20084)
regexp_const_value(#20083,"a")
#20085=*
regexpterm(#20085,14,#20081,1,"b")
#20086=@"loc,{#10000},3,4,3,4"
locations_default(#20086,#10000,3,4,3,4)
hasLocation(#20085,#20086)
regexp_const_value(#20085,"b")
#20087=*
regexpterm(#20087,14,#20081,2,"c")
#20088=@"loc,{#10000},3,5,3,5"
locations_default(#20088,#10000,3,5,3,5)
hasLocation(#20087,#20088)
regexp_const_value(#20087,"c")
#20089=*
regexpterm(#20089,14,#20079,1,"&&")
#20090=@"loc,{#10000},3,7,3,8"
locations_default(#20090,#10000,3,7,3,8)
hasLocation(#20089,#20090)
regexp_const_value(#20089,"&&")
#20091=*
regexpterm(#20091,23,#20079,2,"[bcd]")
#20092=@"loc,{#10000},3,9,3,13"
locations_default(#20092,#10000,3,9,3,13)
hasLocation(#20091,#20092)
#20093=*
regexpterm(#20093,14,#20091,0,"b")
#20094=@"loc,{#10000},3,10,3,10"
locations_default(#20094,#10000,3,10,3,10)
hasLocation(#20093,#20094)
regexp_const_value(#20093,"b")
#20095=*
regexpterm(#20095,14,#20091,1,"c")
#20096=@"loc,{#10000},3,11,3,11"
locations_default(#20096,#10000,3,11,3,11)
hasLocation(#20095,#20096)
regexp_const_value(#20095,"c")
#20097=*
regexpterm(#20097,14,#20091,2,"d")
#20098=@"loc,{#10000},3,12,3,12"
locations_default(#20098,#10000,3,12,3,12)
hasLocation(#20097,#20098)
regexp_const_value(#20097,"d")
#20099=*
stmts(#20099,2,#20001,3,"/[[abc] ... [c]]/v;")
#20100=@"loc,{#10000},7,1,7,23"
locations_default(#20100,#10000,7,1,7,23)
hasLocation(#20099,#20100)
stmt_containers(#20099,#20001)
#20101=*
exprs(#20101,5,#20099,0,"/[[abc] ... &[c]]/v")
hasLocation(#20101,#20043)
enclosing_stmt(#20101,#20099)
expr_containers(#20101,#20001)
literals("/[[abc]&&[bcd]&&[c]]/v","/[[abc]&&[bcd]&&[c]]/v",#20101)
#20102=*
regexpterm(#20102,23,#20101,0,"[[abc]&&[bcd]&&[c]]")
#20103=@"loc,{#10000},7,2,7,20"
locations_default(#20103,#10000,7,2,7,20)
hasLocation(#20102,#20103)
#20104=*
regexpterm(#20104,29,#20102,0,"[[abc]&&[bcd]&&[c]]")
hasLocation(#20104,#20103)
#20105=*
regexpterm(#20105,23,#20104,0,"[abc]")
#20106=@"loc,{#10000},7,3,7,7"
locations_default(#20106,#10000,7,3,7,7)
hasLocation(#20105,#20106)
#20107=*
regexpterm(#20107,14,#20105,0,"a")
#20108=@"loc,{#10000},7,4,7,4"
locations_default(#20108,#10000,7,4,7,4)
hasLocation(#20107,#20108)
regexp_const_value(#20107,"a")
#20109=*
regexpterm(#20109,14,#20105,1,"b")
#20110=@"loc,{#10000},7,5,7,5"
locations_default(#20110,#10000,7,5,7,5)
hasLocation(#20109,#20110)
regexp_const_value(#20109,"b")
#20111=*
regexpterm(#20111,14,#20105,2,"c")
#20112=@"loc,{#10000},7,6,7,6"
locations_default(#20112,#10000,7,6,7,6)
hasLocation(#20111,#20112)
regexp_const_value(#20111,"c")
#20113=*
regexpterm(#20113,23,#20104,1,"[bcd]")
#20114=@"loc,{#10000},7,10,7,14"
locations_default(#20114,#10000,7,10,7,14)
hasLocation(#20113,#20114)
#20115=*
regexpterm(#20115,14,#20113,0,"b")
#20116=@"loc,{#10000},7,11,7,11"
locations_default(#20116,#10000,7,11,7,11)
hasLocation(#20115,#20116)
regexp_const_value(#20115,"b")
#20117=*
regexpterm(#20117,14,#20113,1,"c")
#20118=@"loc,{#10000},7,12,7,12"
locations_default(#20118,#10000,7,12,7,12)
hasLocation(#20117,#20118)
regexp_const_value(#20117,"c")
#20119=*
regexpterm(#20119,14,#20113,2,"d")
#20120=@"loc,{#10000},7,13,7,13"
locations_default(#20120,#10000,7,13,7,13)
hasLocation(#20119,#20120)
regexp_const_value(#20119,"d")
#20121=*
regexpterm(#20121,23,#20104,2,"[c]")
#20122=@"loc,{#10000},7,17,7,19"
locations_default(#20122,#10000,7,17,7,19)
hasLocation(#20121,#20122)
#20123=*
regexpterm(#20123,14,#20121,0,"c")
#20124=@"loc,{#10000},7,18,7,18"
locations_default(#20124,#10000,7,18,7,18)
hasLocation(#20123,#20124)
regexp_const_value(#20123,"c")
#20125=*
entry_cfg_node(#20125,#20001)
#20126=@"loc,{#10000},1,1,1,0"
locations_default(#20126,#10000,1,1,1,0)
hasLocation(#20125,#20126)
#20127=*
exit_cfg_node(#20127,#20001)
hasLocation(#20127,#20047)
successor(#20099,#20101)
successor(#20101,#20127)
successor(#20076,#20078)
successor(#20078,#20099)
successor(#20071,#20073)
successor(#20073,#20076)
successor(#20049,#20051)
successor(#20051,#20071)
successor(#20125,#20049)
numlines(#10000,7,4,7)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,211 @@
#10000=@"/regex_nested_character_class.js;sourcefile"
files(#10000,"/regex_nested_character_class.js")
#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,"Previously not allowed to nest character classes now completely valid with v flag.","//Previ ... v flag.")
#20003=@"loc,{#10000},1,10,1,93"
locations_default(#20003,#10000,1,10,1,93)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"/[[]]/v; //Previously not allowed to nest character classes now completely valid with v flag.","
")
#20005=@"loc,{#10000},1,1,1,93"
locations_default(#20005,#10000,1,1,1,93)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"/[[a]]/v;","
")
#20007=@"loc,{#10000},2,1,2,9"
locations_default(#20007,#10000,2,1,2,9)
hasLocation(#20006,#20007)
#20008=*
lines(#20008,#20001,"/[ [] [ [] [] ] ]/v;","
")
#20009=@"loc,{#10000},3,1,3,20"
locations_default(#20009,#10000,3,1,3,20)
hasLocation(#20008,#20009)
numlines(#20001,3,3,1)
#20010=*
tokeninfo(#20010,5,#20001,0,"/[[]]/v")
#20011=@"loc,{#10000},1,1,1,7"
locations_default(#20011,#10000,1,1,1,7)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,8,#20001,1,";")
#20013=@"loc,{#10000},1,8,1,8"
locations_default(#20013,#10000,1,8,1,8)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,5,#20001,2,"/[[a]]/v")
#20015=@"loc,{#10000},2,1,2,8"
locations_default(#20015,#10000,2,1,2,8)
hasLocation(#20014,#20015)
next_token(#20002,#20014)
#20016=*
tokeninfo(#20016,8,#20001,3,";")
#20017=@"loc,{#10000},2,9,2,9"
locations_default(#20017,#10000,2,9,2,9)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,5,#20001,4,"/[ [] [ [] [] ] ]/v")
#20019=@"loc,{#10000},3,1,3,19"
locations_default(#20019,#10000,3,1,3,19)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,8,#20001,5,";")
#20021=@"loc,{#10000},3,20,3,20"
locations_default(#20021,#10000,3,20,3,20)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,0,#20001,6,"")
#20023=@"loc,{#10000},4,1,4,0"
locations_default(#20023,#10000,4,1,4,0)
hasLocation(#20022,#20023)
toplevels(#20001,0)
#20024=@"loc,{#10000},1,1,4,0"
locations_default(#20024,#10000,1,1,4,0)
hasLocation(#20001,#20024)
#20025=*
stmts(#20025,2,#20001,0,"/[[]]/v;")
#20026=@"loc,{#10000},1,1,1,8"
locations_default(#20026,#10000,1,1,1,8)
hasLocation(#20025,#20026)
stmt_containers(#20025,#20001)
#20027=*
exprs(#20027,5,#20025,0,"/[[]]/v")
hasLocation(#20027,#20011)
enclosing_stmt(#20027,#20025)
expr_containers(#20027,#20001)
literals("/[[]]/v","/[[]]/v",#20027)
#20028=*
regexpterm(#20028,23,#20027,0,"[[]]")
#20029=@"loc,{#10000},1,2,1,5"
locations_default(#20029,#10000,1,2,1,5)
hasLocation(#20028,#20029)
#20030=*
regexpterm(#20030,23,#20028,0,"[]")
#20031=@"loc,{#10000},1,3,1,4"
locations_default(#20031,#10000,1,3,1,4)
hasLocation(#20030,#20031)
#20032=*
stmts(#20032,2,#20001,1,"/[[a]]/v;")
hasLocation(#20032,#20007)
stmt_containers(#20032,#20001)
#20033=*
exprs(#20033,5,#20032,0,"/[[a]]/v")
hasLocation(#20033,#20015)
enclosing_stmt(#20033,#20032)
expr_containers(#20033,#20001)
literals("/[[a]]/v","/[[a]]/v",#20033)
#20034=*
regexpterm(#20034,23,#20033,0,"[[a]]")
#20035=@"loc,{#10000},2,2,2,6"
locations_default(#20035,#10000,2,2,2,6)
hasLocation(#20034,#20035)
#20036=*
regexpterm(#20036,23,#20034,0,"[a]")
#20037=@"loc,{#10000},2,3,2,5"
locations_default(#20037,#10000,2,3,2,5)
hasLocation(#20036,#20037)
#20038=*
regexpterm(#20038,14,#20036,0,"a")
#20039=@"loc,{#10000},2,4,2,4"
locations_default(#20039,#10000,2,4,2,4)
hasLocation(#20038,#20039)
regexp_const_value(#20038,"a")
#20040=*
stmts(#20040,2,#20001,2,"/[ [] [ [] [] ] ]/v;")
hasLocation(#20040,#20009)
stmt_containers(#20040,#20001)
#20041=*
exprs(#20041,5,#20040,0,"/[ [] [ [] [] ] ]/v")
hasLocation(#20041,#20019)
enclosing_stmt(#20041,#20040)
expr_containers(#20041,#20001)
literals("/[ [] [ [] [] ] ]/v","/[ [] [ [] [] ] ]/v",#20041)
#20042=*
regexpterm(#20042,23,#20041,0,"[ [] [ [] [] ] ]")
#20043=@"loc,{#10000},3,2,3,17"
locations_default(#20043,#10000,3,2,3,17)
hasLocation(#20042,#20043)
#20044=*
regexpterm(#20044,14,#20042,0," ")
#20045=@"loc,{#10000},3,3,3,3"
locations_default(#20045,#10000,3,3,3,3)
hasLocation(#20044,#20045)
regexp_const_value(#20044," ")
#20046=*
regexpterm(#20046,23,#20042,1,"[]")
#20047=@"loc,{#10000},3,4,3,5"
locations_default(#20047,#10000,3,4,3,5)
hasLocation(#20046,#20047)
#20048=*
regexpterm(#20048,14,#20042,2," ")
#20049=@"loc,{#10000},3,6,3,6"
locations_default(#20049,#10000,3,6,3,6)
hasLocation(#20048,#20049)
regexp_const_value(#20048," ")
#20050=*
regexpterm(#20050,23,#20042,3,"[ [] [] ]")
#20051=@"loc,{#10000},3,7,3,15"
locations_default(#20051,#10000,3,7,3,15)
hasLocation(#20050,#20051)
#20052=*
regexpterm(#20052,14,#20050,0," ")
#20053=@"loc,{#10000},3,8,3,8"
locations_default(#20053,#10000,3,8,3,8)
hasLocation(#20052,#20053)
regexp_const_value(#20052," ")
#20054=*
regexpterm(#20054,23,#20050,1,"[]")
#20055=@"loc,{#10000},3,9,3,10"
locations_default(#20055,#10000,3,9,3,10)
hasLocation(#20054,#20055)
#20056=*
regexpterm(#20056,14,#20050,2," ")
#20057=@"loc,{#10000},3,11,3,11"
locations_default(#20057,#10000,3,11,3,11)
hasLocation(#20056,#20057)
regexp_const_value(#20056," ")
#20058=*
regexpterm(#20058,23,#20050,3,"[]")
#20059=@"loc,{#10000},3,12,3,13"
locations_default(#20059,#10000,3,12,3,13)
hasLocation(#20058,#20059)
#20060=*
regexpterm(#20060,14,#20050,4," ")
#20061=@"loc,{#10000},3,14,3,14"
locations_default(#20061,#10000,3,14,3,14)
hasLocation(#20060,#20061)
regexp_const_value(#20060," ")
#20062=*
regexpterm(#20062,14,#20042,4," ")
#20063=@"loc,{#10000},3,16,3,16"
locations_default(#20063,#10000,3,16,3,16)
hasLocation(#20062,#20063)
regexp_const_value(#20062," ")
#20064=*
entry_cfg_node(#20064,#20001)
#20065=@"loc,{#10000},1,1,1,0"
locations_default(#20065,#10000,1,1,1,0)
hasLocation(#20064,#20065)
#20066=*
exit_cfg_node(#20066,#20001)
hasLocation(#20066,#20023)
successor(#20040,#20041)
successor(#20041,#20066)
successor(#20032,#20033)
successor(#20033,#20040)
successor(#20025,#20027)
successor(#20027,#20032)
successor(#20064,#20025)
numlines(#10000,3,3,1)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,286 @@
#10000=@"/regex_quoted_string.js;sourcefile"
files(#10000,"/regex_quoted_string.js")
#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=*
lines(#20002,#20001,"/[\q{abc}]/v;","
")
#20003=@"loc,{#10000},1,1,1,13"
locations_default(#20003,#10000,1,1,1,13)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"/[\q{abc|cbd|dcb}]/v;","
")
#20005=@"loc,{#10000},2,1,2,21"
locations_default(#20005,#10000,2,1,2,21)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"/[\q{\}}]/v;","
")
#20007=@"loc,{#10000},3,1,3,12"
locations_default(#20007,#10000,3,1,3,12)
hasLocation(#20006,#20007)
#20008=*
lines(#20008,#20001,"/[\q{\{}]/v;","
")
#20009=@"loc,{#10000},4,1,4,12"
locations_default(#20009,#10000,4,1,4,12)
hasLocation(#20008,#20009)
#20010=*
lines(#20010,#20001,"/[\q{cc|\}a|cc}]/v;","
")
#20011=@"loc,{#10000},5,1,5,19"
locations_default(#20011,#10000,5,1,5,19)
hasLocation(#20010,#20011)
numlines(#20001,5,5,0)
#20012=*
tokeninfo(#20012,5,#20001,0,"/[\q{abc}]/v")
#20013=@"loc,{#10000},1,1,1,12"
locations_default(#20013,#10000,1,1,1,12)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,8,#20001,1,";")
#20015=@"loc,{#10000},1,13,1,13"
locations_default(#20015,#10000,1,13,1,13)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,5,#20001,2,"/[\q{abc|cbd|dcb}]/v")
#20017=@"loc,{#10000},2,1,2,20"
locations_default(#20017,#10000,2,1,2,20)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,8,#20001,3,";")
#20019=@"loc,{#10000},2,21,2,21"
locations_default(#20019,#10000,2,21,2,21)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,5,#20001,4,"/[\q{\}}]/v")
#20021=@"loc,{#10000},3,1,3,11"
locations_default(#20021,#10000,3,1,3,11)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,8,#20001,5,";")
#20023=@"loc,{#10000},3,12,3,12"
locations_default(#20023,#10000,3,12,3,12)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,5,#20001,6,"/[\q{\{}]/v")
#20025=@"loc,{#10000},4,1,4,11"
locations_default(#20025,#10000,4,1,4,11)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,8,#20001,7,";")
#20027=@"loc,{#10000},4,12,4,12"
locations_default(#20027,#10000,4,12,4,12)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,5,#20001,8,"/[\q{cc|\}a|cc}]/v")
#20029=@"loc,{#10000},5,1,5,18"
locations_default(#20029,#10000,5,1,5,18)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,8,#20001,9,";")
#20031=@"loc,{#10000},5,19,5,19"
locations_default(#20031,#10000,5,19,5,19)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,0,#20001,10,"")
#20033=@"loc,{#10000},6,1,6,0"
locations_default(#20033,#10000,6,1,6,0)
hasLocation(#20032,#20033)
toplevels(#20001,0)
#20034=@"loc,{#10000},1,1,6,0"
locations_default(#20034,#10000,1,1,6,0)
hasLocation(#20001,#20034)
#20035=*
stmts(#20035,2,#20001,0,"/[\q{abc}]/v;")
hasLocation(#20035,#20003)
stmt_containers(#20035,#20001)
#20036=*
exprs(#20036,5,#20035,0,"/[\q{abc}]/v")
hasLocation(#20036,#20013)
enclosing_stmt(#20036,#20035)
expr_containers(#20036,#20001)
literals("/[\q{abc}]/v","/[\q{abc}]/v",#20036)
#20037=*
regexpterm(#20037,23,#20036,0,"[\q{abc}]")
#20038=@"loc,{#10000},1,2,1,10"
locations_default(#20038,#10000,1,2,1,10)
hasLocation(#20037,#20038)
#20039=*
regexpterm(#20039,28,#20037,0,"\q{abc}")
#20040=@"loc,{#10000},1,3,1,9"
locations_default(#20040,#10000,1,3,1,9)
hasLocation(#20039,#20040)
#20041=*
regexpterm(#20041,14,#20039,0,"abc")
#20042=@"loc,{#10000},1,6,1,8"
locations_default(#20042,#10000,1,6,1,8)
hasLocation(#20041,#20042)
regexp_const_value(#20041,"abc")
#20043=*
stmts(#20043,2,#20001,1,"/[\q{ab ... cb}]/v;")
hasLocation(#20043,#20005)
stmt_containers(#20043,#20001)
#20044=*
exprs(#20044,5,#20043,0,"/[\q{abc|cbd|dcb}]/v")
hasLocation(#20044,#20017)
enclosing_stmt(#20044,#20043)
expr_containers(#20044,#20001)
literals("/[\q{abc|cbd|dcb}]/v","/[\q{abc|cbd|dcb}]/v",#20044)
#20045=*
regexpterm(#20045,23,#20044,0,"[\q{abc|cbd|dcb}]")
#20046=@"loc,{#10000},2,2,2,18"
locations_default(#20046,#10000,2,2,2,18)
hasLocation(#20045,#20046)
#20047=*
regexpterm(#20047,28,#20045,0,"\q{abc|cbd|dcb}")
#20048=@"loc,{#10000},2,3,2,17"
locations_default(#20048,#10000,2,3,2,17)
hasLocation(#20047,#20048)
#20049=*
regexpterm(#20049,0,#20047,0,"abc|cbd|dcb")
#20050=@"loc,{#10000},2,6,2,16"
locations_default(#20050,#10000,2,6,2,16)
hasLocation(#20049,#20050)
#20051=*
regexpterm(#20051,14,#20049,0,"abc")
#20052=@"loc,{#10000},2,6,2,8"
locations_default(#20052,#10000,2,6,2,8)
hasLocation(#20051,#20052)
regexp_const_value(#20051,"abc")
#20053=*
regexpterm(#20053,14,#20049,1,"cbd")
#20054=@"loc,{#10000},2,10,2,12"
locations_default(#20054,#10000,2,10,2,12)
hasLocation(#20053,#20054)
regexp_const_value(#20053,"cbd")
#20055=*
regexpterm(#20055,14,#20049,2,"dcb")
#20056=@"loc,{#10000},2,14,2,16"
locations_default(#20056,#10000,2,14,2,16)
hasLocation(#20055,#20056)
regexp_const_value(#20055,"dcb")
#20057=*
stmts(#20057,2,#20001,2,"/[\q{\}}]/v;")
hasLocation(#20057,#20007)
stmt_containers(#20057,#20001)
#20058=*
exprs(#20058,5,#20057,0,"/[\q{\}}]/v")
hasLocation(#20058,#20021)
enclosing_stmt(#20058,#20057)
expr_containers(#20058,#20001)
literals("/[\q{\}}]/v","/[\q{\}}]/v",#20058)
#20059=*
regexpterm(#20059,23,#20058,0,"[\q{\}}]")
#20060=@"loc,{#10000},3,2,3,9"
locations_default(#20060,#10000,3,2,3,9)
hasLocation(#20059,#20060)
#20061=*
regexpterm(#20061,28,#20059,0,"\q{\}}")
#20062=@"loc,{#10000},3,3,3,8"
locations_default(#20062,#10000,3,3,3,8)
hasLocation(#20061,#20062)
#20063=*
regexpterm(#20063,14,#20061,0,"\}")
#20064=@"loc,{#10000},3,6,3,7"
locations_default(#20064,#10000,3,6,3,7)
hasLocation(#20063,#20064)
regexp_const_value(#20063,"\}")
#20065=*
stmts(#20065,2,#20001,3,"/[\q{\{}]/v;")
hasLocation(#20065,#20009)
stmt_containers(#20065,#20001)
#20066=*
exprs(#20066,5,#20065,0,"/[\q{\{}]/v")
hasLocation(#20066,#20025)
enclosing_stmt(#20066,#20065)
expr_containers(#20066,#20001)
literals("/[\q{\{}]/v","/[\q{\{}]/v",#20066)
#20067=*
regexpterm(#20067,23,#20066,0,"[\q{\{}]")
#20068=@"loc,{#10000},4,2,4,9"
locations_default(#20068,#10000,4,2,4,9)
hasLocation(#20067,#20068)
#20069=*
regexpterm(#20069,28,#20067,0,"\q{\{}")
#20070=@"loc,{#10000},4,3,4,8"
locations_default(#20070,#10000,4,3,4,8)
hasLocation(#20069,#20070)
#20071=*
regexpterm(#20071,14,#20069,0,"\{")
#20072=@"loc,{#10000},4,6,4,7"
locations_default(#20072,#10000,4,6,4,7)
hasLocation(#20071,#20072)
regexp_const_value(#20071,"\{")
#20073=*
stmts(#20073,2,#20001,4,"/[\q{cc|\}a|cc}]/v;")
hasLocation(#20073,#20011)
stmt_containers(#20073,#20001)
#20074=*
exprs(#20074,5,#20073,0,"/[\q{cc|\}a|cc}]/v")
hasLocation(#20074,#20029)
enclosing_stmt(#20074,#20073)
expr_containers(#20074,#20001)
literals("/[\q{cc|\}a|cc}]/v","/[\q{cc|\}a|cc}]/v",#20074)
#20075=*
regexpterm(#20075,23,#20074,0,"[\q{cc|\}a|cc}]")
#20076=@"loc,{#10000},5,2,5,16"
locations_default(#20076,#10000,5,2,5,16)
hasLocation(#20075,#20076)
#20077=*
regexpterm(#20077,28,#20075,0,"\q{cc|\}a|cc}")
#20078=@"loc,{#10000},5,3,5,15"
locations_default(#20078,#10000,5,3,5,15)
hasLocation(#20077,#20078)
#20079=*
regexpterm(#20079,0,#20077,0,"cc|\}a|cc")
#20080=@"loc,{#10000},5,6,5,14"
locations_default(#20080,#10000,5,6,5,14)
hasLocation(#20079,#20080)
#20081=*
regexpterm(#20081,14,#20079,0,"cc")
#20082=@"loc,{#10000},5,6,5,7"
locations_default(#20082,#10000,5,6,5,7)
hasLocation(#20081,#20082)
regexp_const_value(#20081,"cc")
#20083=*
regexpterm(#20083,14,#20079,1,"\}a")
#20084=@"loc,{#10000},5,9,5,11"
locations_default(#20084,#10000,5,9,5,11)
hasLocation(#20083,#20084)
regexp_const_value(#20083,"\}a")
#20085=*
regexpterm(#20085,14,#20079,2,"cc")
#20086=@"loc,{#10000},5,13,5,14"
locations_default(#20086,#10000,5,13,5,14)
hasLocation(#20085,#20086)
regexp_const_value(#20085,"cc")
#20087=*
entry_cfg_node(#20087,#20001)
#20088=@"loc,{#10000},1,1,1,0"
locations_default(#20088,#10000,1,1,1,0)
hasLocation(#20087,#20088)
#20089=*
exit_cfg_node(#20089,#20001)
hasLocation(#20089,#20033)
successor(#20073,#20074)
successor(#20074,#20089)
successor(#20065,#20066)
successor(#20066,#20073)
successor(#20057,#20058)
successor(#20058,#20065)
successor(#20043,#20044)
successor(#20044,#20057)
successor(#20035,#20036)
successor(#20036,#20043)
successor(#20087,#20035)
numlines(#10000,5,5,0)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,268 @@
#10000=@"/subtraction.js;sourcefile"
files(#10000,"/subtraction.js")
#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=*
lines(#20002,#20001,"/[\p{Script_Extensions=Greek}--\p{Letter}]/v;","
")
#20003=@"loc,{#10000},1,1,1,45"
locations_default(#20003,#10000,1,1,1,45)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"/[[abc]--[cbd]]/v;","
")
#20005=@"loc,{#10000},2,1,2,18"
locations_default(#20005,#10000,2,1,2,18)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"/[[abc]--[cbd]--[bde]]/v;","
")
#20007=@"loc,{#10000},3,1,3,25"
locations_default(#20007,#10000,3,1,3,25)
hasLocation(#20006,#20007)
numlines(#20001,3,3,0)
#20008=*
tokeninfo(#20008,5,#20001,0,"/[\p{Script_Extensions=Greek}--\p{Letter}]/v")
#20009=@"loc,{#10000},1,1,1,44"
locations_default(#20009,#10000,1,1,1,44)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,8,#20001,1,";")
#20011=@"loc,{#10000},1,45,1,45"
locations_default(#20011,#10000,1,45,1,45)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,5,#20001,2,"/[[abc]--[cbd]]/v")
#20013=@"loc,{#10000},2,1,2,17"
locations_default(#20013,#10000,2,1,2,17)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,8,#20001,3,";")
#20015=@"loc,{#10000},2,18,2,18"
locations_default(#20015,#10000,2,18,2,18)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,5,#20001,4,"/[[abc]--[cbd]--[bde]]/v")
#20017=@"loc,{#10000},3,1,3,24"
locations_default(#20017,#10000,3,1,3,24)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,8,#20001,5,";")
#20019=@"loc,{#10000},3,25,3,25"
locations_default(#20019,#10000,3,25,3,25)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,0,#20001,6,"")
#20021=@"loc,{#10000},4,1,4,0"
locations_default(#20021,#10000,4,1,4,0)
hasLocation(#20020,#20021)
toplevels(#20001,0)
#20022=@"loc,{#10000},1,1,4,0"
locations_default(#20022,#10000,1,1,4,0)
hasLocation(#20001,#20022)
#20023=*
stmts(#20023,2,#20001,0,"/[\p{Sc ... er}]/v;")
hasLocation(#20023,#20003)
stmt_containers(#20023,#20001)
#20024=*
exprs(#20024,5,#20023,0,"/[\p{Sc ... ter}]/v")
hasLocation(#20024,#20009)
enclosing_stmt(#20024,#20023)
expr_containers(#20024,#20001)
literals("/[\p{Script_Extensions=Greek}--\p{Letter}]/v","/[\p{Script_Extensions=Greek}--\p{Letter}]/v",#20024)
#20025=*
regexpterm(#20025,23,#20024,0,"[\p{Script_Extensions=Greek}--\p{Letter}]")
#20026=@"loc,{#10000},1,2,1,42"
locations_default(#20026,#10000,1,2,1,42)
hasLocation(#20025,#20026)
#20027=*
regexpterm(#20027,30,#20025,0,"[\p{Script_Extensions=Greek}--\p{Letter}]")
hasLocation(#20027,#20026)
#20028=*
regexpterm(#20028,27,#20027,0,"\p{Script_Extensions=Greek}")
#20029=@"loc,{#10000},1,3,1,29"
locations_default(#20029,#10000,1,3,1,29)
hasLocation(#20028,#20029)
unicode_property_escapename(#20028,"Script_Extensions")
unicode_property_escapevalue(#20028,"Greek")
#20030=*
regexpterm(#20030,27,#20027,1,"\p{Letter}")
#20031=@"loc,{#10000},1,32,1,41"
locations_default(#20031,#10000,1,32,1,41)
hasLocation(#20030,#20031)
unicode_property_escapename(#20030,"Letter")
#20032=*
stmts(#20032,2,#20001,1,"/[[abc]--[cbd]]/v;")
hasLocation(#20032,#20005)
stmt_containers(#20032,#20001)
#20033=*
exprs(#20033,5,#20032,0,"/[[abc]--[cbd]]/v")
hasLocation(#20033,#20013)
enclosing_stmt(#20033,#20032)
expr_containers(#20033,#20001)
literals("/[[abc]--[cbd]]/v","/[[abc]--[cbd]]/v",#20033)
#20034=*
regexpterm(#20034,23,#20033,0,"[[abc]--[cbd]]")
#20035=@"loc,{#10000},2,2,2,15"
locations_default(#20035,#10000,2,2,2,15)
hasLocation(#20034,#20035)
#20036=*
regexpterm(#20036,30,#20034,0,"[[abc]--[cbd]]")
hasLocation(#20036,#20035)
#20037=*
regexpterm(#20037,23,#20036,0,"[abc]")
#20038=@"loc,{#10000},2,3,2,7"
locations_default(#20038,#10000,2,3,2,7)
hasLocation(#20037,#20038)
#20039=*
regexpterm(#20039,14,#20037,0,"a")
#20040=@"loc,{#10000},2,4,2,4"
locations_default(#20040,#10000,2,4,2,4)
hasLocation(#20039,#20040)
regexp_const_value(#20039,"a")
#20041=*
regexpterm(#20041,14,#20037,1,"b")
#20042=@"loc,{#10000},2,5,2,5"
locations_default(#20042,#10000,2,5,2,5)
hasLocation(#20041,#20042)
regexp_const_value(#20041,"b")
#20043=*
regexpterm(#20043,14,#20037,2,"c")
#20044=@"loc,{#10000},2,6,2,6"
locations_default(#20044,#10000,2,6,2,6)
hasLocation(#20043,#20044)
regexp_const_value(#20043,"c")
#20045=*
regexpterm(#20045,23,#20036,1,"[cbd]")
#20046=@"loc,{#10000},2,10,2,14"
locations_default(#20046,#10000,2,10,2,14)
hasLocation(#20045,#20046)
#20047=*
regexpterm(#20047,14,#20045,0,"c")
#20048=@"loc,{#10000},2,11,2,11"
locations_default(#20048,#10000,2,11,2,11)
hasLocation(#20047,#20048)
regexp_const_value(#20047,"c")
#20049=*
regexpterm(#20049,14,#20045,1,"b")
#20050=@"loc,{#10000},2,12,2,12"
locations_default(#20050,#10000,2,12,2,12)
hasLocation(#20049,#20050)
regexp_const_value(#20049,"b")
#20051=*
regexpterm(#20051,14,#20045,2,"d")
#20052=@"loc,{#10000},2,13,2,13"
locations_default(#20052,#10000,2,13,2,13)
hasLocation(#20051,#20052)
regexp_const_value(#20051,"d")
#20053=*
stmts(#20053,2,#20001,2,"/[[abc] ... de]]/v;")
hasLocation(#20053,#20007)
stmt_containers(#20053,#20001)
#20054=*
exprs(#20054,5,#20053,0,"/[[abc] ... bde]]/v")
hasLocation(#20054,#20017)
enclosing_stmt(#20054,#20053)
expr_containers(#20054,#20001)
literals("/[[abc]--[cbd]--[bde]]/v","/[[abc]--[cbd]--[bde]]/v",#20054)
#20055=*
regexpterm(#20055,23,#20054,0,"[[abc]--[cbd]--[bde]]")
#20056=@"loc,{#10000},3,2,3,22"
locations_default(#20056,#10000,3,2,3,22)
hasLocation(#20055,#20056)
#20057=*
regexpterm(#20057,30,#20055,0,"[[abc]--[cbd]--[bde]]")
hasLocation(#20057,#20056)
#20058=*
regexpterm(#20058,23,#20057,0,"[abc]")
#20059=@"loc,{#10000},3,3,3,7"
locations_default(#20059,#10000,3,3,3,7)
hasLocation(#20058,#20059)
#20060=*
regexpterm(#20060,14,#20058,0,"a")
#20061=@"loc,{#10000},3,4,3,4"
locations_default(#20061,#10000,3,4,3,4)
hasLocation(#20060,#20061)
regexp_const_value(#20060,"a")
#20062=*
regexpterm(#20062,14,#20058,1,"b")
#20063=@"loc,{#10000},3,5,3,5"
locations_default(#20063,#10000,3,5,3,5)
hasLocation(#20062,#20063)
regexp_const_value(#20062,"b")
#20064=*
regexpterm(#20064,14,#20058,2,"c")
#20065=@"loc,{#10000},3,6,3,6"
locations_default(#20065,#10000,3,6,3,6)
hasLocation(#20064,#20065)
regexp_const_value(#20064,"c")
#20066=*
regexpterm(#20066,23,#20057,1,"[cbd]")
#20067=@"loc,{#10000},3,10,3,14"
locations_default(#20067,#10000,3,10,3,14)
hasLocation(#20066,#20067)
#20068=*
regexpterm(#20068,14,#20066,0,"c")
#20069=@"loc,{#10000},3,11,3,11"
locations_default(#20069,#10000,3,11,3,11)
hasLocation(#20068,#20069)
regexp_const_value(#20068,"c")
#20070=*
regexpterm(#20070,14,#20066,1,"b")
#20071=@"loc,{#10000},3,12,3,12"
locations_default(#20071,#10000,3,12,3,12)
hasLocation(#20070,#20071)
regexp_const_value(#20070,"b")
#20072=*
regexpterm(#20072,14,#20066,2,"d")
#20073=@"loc,{#10000},3,13,3,13"
locations_default(#20073,#10000,3,13,3,13)
hasLocation(#20072,#20073)
regexp_const_value(#20072,"d")
#20074=*
regexpterm(#20074,23,#20057,2,"[bde]")
#20075=@"loc,{#10000},3,17,3,21"
locations_default(#20075,#10000,3,17,3,21)
hasLocation(#20074,#20075)
#20076=*
regexpterm(#20076,14,#20074,0,"b")
#20077=@"loc,{#10000},3,18,3,18"
locations_default(#20077,#10000,3,18,3,18)
hasLocation(#20076,#20077)
regexp_const_value(#20076,"b")
#20078=*
regexpterm(#20078,14,#20074,1,"d")
#20079=@"loc,{#10000},3,19,3,19"
locations_default(#20079,#10000,3,19,3,19)
hasLocation(#20078,#20079)
regexp_const_value(#20078,"d")
#20080=*
regexpterm(#20080,14,#20074,2,"e")
#20081=@"loc,{#10000},3,20,3,20"
locations_default(#20081,#10000,3,20,3,20)
hasLocation(#20080,#20081)
regexp_const_value(#20080,"e")
#20082=*
entry_cfg_node(#20082,#20001)
#20083=@"loc,{#10000},1,1,1,0"
locations_default(#20083,#10000,1,1,1,0)
hasLocation(#20082,#20083)
#20084=*
exit_cfg_node(#20084,#20001)
hasLocation(#20084,#20021)
successor(#20053,#20054)
successor(#20054,#20084)
successor(#20032,#20033)
successor(#20033,#20053)
successor(#20023,#20024)
successor(#20024,#20032)
successor(#20082,#20023)
numlines(#10000,3,3,0)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,510 @@
#10000=@"/test.js;sourcefile"
files(#10000,"/test.js")
#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=*
lines(#20002,#20001,"const regex = /\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|\b[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)/gmv;","
")
#20003=@"loc,{#10000},1,1,1,172"
locations_default(#20003,#10000,1,1,1,172)
hasLocation(#20002,#20003)
numlines(#20001,1,1,0)
#20004=*
tokeninfo(#20004,7,#20001,0,"const")
#20005=@"loc,{#10000},1,1,1,5"
locations_default(#20005,#10000,1,1,1,5)
hasLocation(#20004,#20005)
#20006=*
tokeninfo(#20006,6,#20001,1,"regex")
#20007=@"loc,{#10000},1,7,1,11"
locations_default(#20007,#10000,1,7,1,11)
hasLocation(#20006,#20007)
#20008=*
tokeninfo(#20008,8,#20001,2,"=")
#20009=@"loc,{#10000},1,13,1,13"
locations_default(#20009,#10000,1,13,1,13)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,5,#20001,3,"/\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|\b[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)/gmv")
#20011=@"loc,{#10000},1,15,1,171"
locations_default(#20011,#10000,1,15,1,171)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,8,#20001,4,";")
#20013=@"loc,{#10000},1,172,1,172"
locations_default(#20013,#10000,1,172,1,172)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,0,#20001,5,"")
#20015=@"loc,{#10000},2,1,2,0"
locations_default(#20015,#10000,2,1,2,0)
hasLocation(#20014,#20015)
toplevels(#20001,0)
#20016=@"loc,{#10000},1,1,2,0"
locations_default(#20016,#10000,1,1,2,0)
hasLocation(#20001,#20016)
#20017=@"var;{regex};{#20000}"
variables(#20017,"regex",#20000)
#20018=*
stmts(#20018,22,#20001,0,"const r ... +)/gmv;")
hasLocation(#20018,#20003)
stmt_containers(#20018,#20001)
#20019=*
exprs(#20019,64,#20018,0,"regex = ... )+)/gmv")
#20020=@"loc,{#10000},1,7,1,171"
locations_default(#20020,#10000,1,7,1,171)
hasLocation(#20019,#20020)
enclosing_stmt(#20019,#20018)
expr_containers(#20019,#20001)
#20021=*
exprs(#20021,78,#20019,0,"regex")
hasLocation(#20021,#20007)
enclosing_stmt(#20021,#20018)
expr_containers(#20021,#20001)
literals("regex","regex",#20021)
decl(#20021,#20017)
#20022=*
exprs(#20022,5,#20019,1,"/\b(?:h ... )+)/gmv")
hasLocation(#20022,#20011)
enclosing_stmt(#20022,#20018)
expr_containers(#20022,#20001)
literals("/\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|\b[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)/gmv","/\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|\b[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)/gmv",#20022)
#20023=*
regexpterm(#20023,0,#20022,0,"\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|\b[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)")
#20024=@"loc,{#10000},1,16,1,167"
locations_default(#20024,#10000,1,16,1,167)
hasLocation(#20023,#20024)
#20025=*
regexpterm(#20025,1,#20023,0,"\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+")
#20026=@"loc,{#10000},1,16,1,98"
locations_default(#20026,#10000,1,16,1,98)
hasLocation(#20025,#20026)
#20027=*
regexpterm(#20027,4,#20025,0,"\b")
#20028=@"loc,{#10000},1,16,1,17"
locations_default(#20028,#10000,1,16,1,17)
hasLocation(#20027,#20028)
#20029=*
regexpterm(#20029,13,#20025,1,"(?:https?:\/\/|mailto:|www\.)")
#20030=@"loc,{#10000},1,18,1,46"
locations_default(#20030,#10000,1,18,1,46)
hasLocation(#20029,#20030)
#20031=*
regexpterm(#20031,0,#20029,0,"https?:\/\/|mailto:|www\.")
#20032=@"loc,{#10000},1,21,1,45"
locations_default(#20032,#10000,1,21,1,45)
hasLocation(#20031,#20032)
#20033=*
regexpterm(#20033,1,#20031,0,"https?:\/\/")
#20034=@"loc,{#10000},1,21,1,31"
locations_default(#20034,#10000,1,21,1,31)
hasLocation(#20033,#20034)
#20035=*
regexpterm(#20035,14,#20033,0,"http")
#20036=@"loc,{#10000},1,21,1,24"
locations_default(#20036,#10000,1,21,1,24)
hasLocation(#20035,#20036)
regexp_const_value(#20035,"http")
#20037=*
regexpterm(#20037,10,#20033,1,"s?")
#20038=@"loc,{#10000},1,25,1,26"
locations_default(#20038,#10000,1,25,1,26)
hasLocation(#20037,#20038)
is_greedy(#20037)
#20039=*
regexpterm(#20039,14,#20037,0,"s")
#20040=@"loc,{#10000},1,25,1,25"
locations_default(#20040,#10000,1,25,1,25)
hasLocation(#20039,#20040)
regexp_const_value(#20039,"s")
#20041=*
regexpterm(#20041,14,#20033,2,":")
#20042=@"loc,{#10000},1,27,1,27"
locations_default(#20042,#10000,1,27,1,27)
hasLocation(#20041,#20042)
regexp_const_value(#20041,":")
#20043=*
regexpterm(#20043,21,#20033,3,"\/")
#20044=@"loc,{#10000},1,28,1,29"
locations_default(#20044,#10000,1,28,1,29)
hasLocation(#20043,#20044)
regexp_const_value(#20043,"/")
#20045=*
regexpterm(#20045,21,#20033,4,"\/")
#20046=@"loc,{#10000},1,30,1,31"
locations_default(#20046,#10000,1,30,1,31)
hasLocation(#20045,#20046)
regexp_const_value(#20045,"/")
#20047=*
regexpterm(#20047,14,#20031,1,"mailto:")
#20048=@"loc,{#10000},1,33,1,39"
locations_default(#20048,#10000,1,33,1,39)
hasLocation(#20047,#20048)
regexp_const_value(#20047,"mailto:")
#20049=*
regexpterm(#20049,1,#20031,2,"www\.")
#20050=@"loc,{#10000},1,41,1,45"
locations_default(#20050,#10000,1,41,1,45)
hasLocation(#20049,#20050)
#20051=*
regexpterm(#20051,14,#20049,0,"www")
#20052=@"loc,{#10000},1,41,1,43"
locations_default(#20052,#10000,1,41,1,43)
hasLocation(#20051,#20052)
regexp_const_value(#20051,"www")
#20053=*
regexpterm(#20053,21,#20049,1,"\.")
#20054=@"loc,{#10000},1,44,1,45"
locations_default(#20054,#10000,1,44,1,45)
hasLocation(#20053,#20054)
regexp_const_value(#20053,".")
#20055=*
regexpterm(#20055,9,#20025,2,"(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+")
#20056=@"loc,{#10000},1,47,1,98"
locations_default(#20056,#10000,1,47,1,98)
hasLocation(#20055,#20056)
is_greedy(#20055)
#20057=*
regexpterm(#20057,13,#20055,0,"(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])")
#20058=@"loc,{#10000},1,47,1,97"
locations_default(#20058,#10000,1,47,1,97)
hasLocation(#20057,#20058)
#20059=*
regexpterm(#20059,0,#20057,0,"[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]]")
#20060=@"loc,{#10000},1,50,1,96"
locations_default(#20060,#10000,1,50,1,96)
hasLocation(#20059,#20060)
#20061=*
regexpterm(#20061,23,#20059,0,"[\S--[\p{P}<>]]")
#20062=@"loc,{#10000},1,50,1,64"
locations_default(#20062,#10000,1,50,1,64)
hasLocation(#20061,#20062)
#20063=*
regexpterm(#20063,30,#20061,0,"[\S--[\p{P}<>]]")
hasLocation(#20063,#20062)
#20064=*
regexpterm(#20064,20,#20063,0,"\S")
#20065=@"loc,{#10000},1,51,1,52"
locations_default(#20065,#10000,1,51,1,52)
hasLocation(#20064,#20065)
char_class_escape(#20064,"S")
#20066=*
regexpterm(#20066,23,#20063,1,"[\p{P}<>]")
#20067=@"loc,{#10000},1,55,1,63"
locations_default(#20067,#10000,1,55,1,63)
hasLocation(#20066,#20067)
#20068=*
regexpterm(#20068,27,#20066,0,"\p{P}")
#20069=@"loc,{#10000},1,56,1,60"
locations_default(#20069,#10000,1,56,1,60)
hasLocation(#20068,#20069)
unicode_property_escapename(#20068,"P")
#20070=*
regexpterm(#20070,14,#20066,1,"<")
#20071=@"loc,{#10000},1,61,1,61"
locations_default(#20071,#10000,1,61,1,61)
hasLocation(#20070,#20071)
regexp_const_value(#20070,"<")
#20072=*
regexpterm(#20072,14,#20066,2,">")
#20073=@"loc,{#10000},1,62,1,62"
locations_default(#20073,#10000,1,62,1,62)
hasLocation(#20072,#20073)
regexp_const_value(#20072,">")
#20074=*
regexpterm(#20074,21,#20059,1,"\/")
#20075=@"loc,{#10000},1,66,1,67"
locations_default(#20075,#10000,1,66,1,67)
hasLocation(#20074,#20075)
regexp_const_value(#20074,"/")
#20076=*
regexpterm(#20076,1,#20059,2,"[\S--[\[\]]]+[\S--[\p{P}<>]]")
#20077=@"loc,{#10000},1,69,1,96"
locations_default(#20077,#10000,1,69,1,96)
hasLocation(#20076,#20077)
#20078=*
regexpterm(#20078,9,#20076,0,"[\S--[\[\]]]+")
#20079=@"loc,{#10000},1,69,1,81"
locations_default(#20079,#10000,1,69,1,81)
hasLocation(#20078,#20079)
is_greedy(#20078)
#20080=*
regexpterm(#20080,23,#20078,0,"[\S--[\[\]]]")
#20081=@"loc,{#10000},1,69,1,80"
locations_default(#20081,#10000,1,69,1,80)
hasLocation(#20080,#20081)
#20082=*
regexpterm(#20082,30,#20080,0,"[\S--[\[\]]]")
hasLocation(#20082,#20081)
#20083=*
regexpterm(#20083,20,#20082,0,"\S")
#20084=@"loc,{#10000},1,70,1,71"
locations_default(#20084,#10000,1,70,1,71)
hasLocation(#20083,#20084)
char_class_escape(#20083,"S")
#20085=*
regexpterm(#20085,23,#20082,1,"[\[\]]")
#20086=@"loc,{#10000},1,74,1,79"
locations_default(#20086,#10000,1,74,1,79)
hasLocation(#20085,#20086)
#20087=*
regexpterm(#20087,21,#20085,0,"\[")
#20088=@"loc,{#10000},1,75,1,76"
locations_default(#20088,#10000,1,75,1,76)
hasLocation(#20087,#20088)
regexp_const_value(#20087,"[")
#20089=*
regexpterm(#20089,21,#20085,1,"\]")
#20090=@"loc,{#10000},1,77,1,78"
locations_default(#20090,#10000,1,77,1,78)
hasLocation(#20089,#20090)
regexp_const_value(#20089,"]")
#20091=*
regexpterm(#20091,23,#20076,1,"[\S--[\p{P}<>]]")
#20092=@"loc,{#10000},1,82,1,96"
locations_default(#20092,#10000,1,82,1,96)
hasLocation(#20091,#20092)
#20093=*
regexpterm(#20093,30,#20091,0,"[\S--[\p{P}<>]]")
hasLocation(#20093,#20092)
#20094=*
regexpterm(#20094,20,#20093,0,"\S")
#20095=@"loc,{#10000},1,83,1,84"
locations_default(#20095,#10000,1,83,1,84)
hasLocation(#20094,#20095)
char_class_escape(#20094,"S")
#20096=*
regexpterm(#20096,23,#20093,1,"[\p{P}<>]")
#20097=@"loc,{#10000},1,87,1,95"
locations_default(#20097,#10000,1,87,1,95)
hasLocation(#20096,#20097)
#20098=*
regexpterm(#20098,27,#20096,0,"\p{P}")
#20099=@"loc,{#10000},1,88,1,92"
locations_default(#20099,#10000,1,88,1,92)
hasLocation(#20098,#20099)
unicode_property_escapename(#20098,"P")
#20100=*
regexpterm(#20100,14,#20096,1,"<")
#20101=@"loc,{#10000},1,93,1,93"
locations_default(#20101,#10000,1,93,1,93)
hasLocation(#20100,#20101)
regexp_const_value(#20100,"<")
#20102=*
regexpterm(#20102,14,#20096,2,">")
#20103=@"loc,{#10000},1,94,1,94"
locations_default(#20103,#10000,1,94,1,94)
hasLocation(#20102,#20103)
regexp_const_value(#20102,">")
#20104=*
regexpterm(#20104,1,#20023,1,"\b[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)")
#20105=@"loc,{#10000},1,100,1,167"
locations_default(#20105,#10000,1,100,1,167)
hasLocation(#20104,#20105)
#20106=*
regexpterm(#20106,4,#20104,0,"\b")
#20107=@"loc,{#10000},1,100,1,101"
locations_default(#20107,#10000,1,100,1,101)
hasLocation(#20106,#20107)
#20108=*
regexpterm(#20108,9,#20104,1,"[\S--[@\p{Ps}\p{Pe}<>]]+")
#20109=@"loc,{#10000},1,102,1,125"
locations_default(#20109,#10000,1,102,1,125)
hasLocation(#20108,#20109)
is_greedy(#20108)
#20110=*
regexpterm(#20110,23,#20108,0,"[\S--[@\p{Ps}\p{Pe}<>]]")
#20111=@"loc,{#10000},1,102,1,124"
locations_default(#20111,#10000,1,102,1,124)
hasLocation(#20110,#20111)
#20112=*
regexpterm(#20112,30,#20110,0,"[\S--[@\p{Ps}\p{Pe}<>]]")
hasLocation(#20112,#20111)
#20113=*
regexpterm(#20113,20,#20112,0,"\S")
#20114=@"loc,{#10000},1,103,1,104"
locations_default(#20114,#10000,1,103,1,104)
hasLocation(#20113,#20114)
char_class_escape(#20113,"S")
#20115=*
regexpterm(#20115,23,#20112,1,"[@\p{Ps}\p{Pe}<>]")
#20116=@"loc,{#10000},1,107,1,123"
locations_default(#20116,#10000,1,107,1,123)
hasLocation(#20115,#20116)
#20117=*
regexpterm(#20117,14,#20115,0,"@")
#20118=@"loc,{#10000},1,108,1,108"
locations_default(#20118,#10000,1,108,1,108)
hasLocation(#20117,#20118)
regexp_const_value(#20117,"@")
#20119=*
regexpterm(#20119,27,#20115,1,"\p{Ps}")
#20120=@"loc,{#10000},1,109,1,114"
locations_default(#20120,#10000,1,109,1,114)
hasLocation(#20119,#20120)
unicode_property_escapename(#20119,"Ps")
#20121=*
regexpterm(#20121,27,#20115,2,"\p{Pe}")
#20122=@"loc,{#10000},1,115,1,120"
locations_default(#20122,#10000,1,115,1,120)
hasLocation(#20121,#20122)
unicode_property_escapename(#20121,"Pe")
#20123=*
regexpterm(#20123,14,#20115,3,"<")
#20124=@"loc,{#10000},1,121,1,121"
locations_default(#20124,#10000,1,121,1,121)
hasLocation(#20123,#20124)
regexp_const_value(#20123,"<")
#20125=*
regexpterm(#20125,14,#20115,4,">")
#20126=@"loc,{#10000},1,122,1,122"
locations_default(#20126,#10000,1,122,1,122)
hasLocation(#20125,#20126)
regexp_const_value(#20125,">")
#20127=*
regexpterm(#20127,14,#20104,2,"@")
#20128=@"loc,{#10000},1,126,1,126"
locations_default(#20128,#10000,1,126,1,126)
hasLocation(#20127,#20128)
regexp_const_value(#20127,"@")
#20129=*
regexpterm(#20129,13,#20104,3,"([\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+)")
#20130=@"loc,{#10000},1,127,1,167"
locations_default(#20130,#10000,1,127,1,167)
hasLocation(#20129,#20130)
is_capture(#20129,1)
#20131=*
regexpterm(#20131,1,#20129,0,"[\S--[\p{P}<>]]+(?:\.[\S--[\p{P}<>]]+)+")
#20132=@"loc,{#10000},1,128,1,166"
locations_default(#20132,#10000,1,128,1,166)
hasLocation(#20131,#20132)
#20133=*
regexpterm(#20133,9,#20131,0,"[\S--[\p{P}<>]]+")
#20134=@"loc,{#10000},1,128,1,143"
locations_default(#20134,#10000,1,128,1,143)
hasLocation(#20133,#20134)
is_greedy(#20133)
#20135=*
regexpterm(#20135,23,#20133,0,"[\S--[\p{P}<>]]")
#20136=@"loc,{#10000},1,128,1,142"
locations_default(#20136,#10000,1,128,1,142)
hasLocation(#20135,#20136)
#20137=*
regexpterm(#20137,30,#20135,0,"[\S--[\p{P}<>]]")
hasLocation(#20137,#20136)
#20138=*
regexpterm(#20138,20,#20137,0,"\S")
#20139=@"loc,{#10000},1,129,1,130"
locations_default(#20139,#10000,1,129,1,130)
hasLocation(#20138,#20139)
char_class_escape(#20138,"S")
#20140=*
regexpterm(#20140,23,#20137,1,"[\p{P}<>]")
#20141=@"loc,{#10000},1,133,1,141"
locations_default(#20141,#10000,1,133,1,141)
hasLocation(#20140,#20141)
#20142=*
regexpterm(#20142,27,#20140,0,"\p{P}")
#20143=@"loc,{#10000},1,134,1,138"
locations_default(#20143,#10000,1,134,1,138)
hasLocation(#20142,#20143)
unicode_property_escapename(#20142,"P")
#20144=*
regexpterm(#20144,14,#20140,1,"<")
#20145=@"loc,{#10000},1,139,1,139"
locations_default(#20145,#10000,1,139,1,139)
hasLocation(#20144,#20145)
regexp_const_value(#20144,"<")
#20146=*
regexpterm(#20146,14,#20140,2,">")
#20147=@"loc,{#10000},1,140,1,140"
locations_default(#20147,#10000,1,140,1,140)
hasLocation(#20146,#20147)
regexp_const_value(#20146,">")
#20148=*
regexpterm(#20148,9,#20131,1,"(?:\.[\S--[\p{P}<>]]+)+")
#20149=@"loc,{#10000},1,144,1,166"
locations_default(#20149,#10000,1,144,1,166)
hasLocation(#20148,#20149)
is_greedy(#20148)
#20150=*
regexpterm(#20150,13,#20148,0,"(?:\.[\S--[\p{P}<>]]+)")
#20151=@"loc,{#10000},1,144,1,165"
locations_default(#20151,#10000,1,144,1,165)
hasLocation(#20150,#20151)
#20152=*
regexpterm(#20152,1,#20150,0,"\.[\S--[\p{P}<>]]+")
#20153=@"loc,{#10000},1,147,1,164"
locations_default(#20153,#10000,1,147,1,164)
hasLocation(#20152,#20153)
#20154=*
regexpterm(#20154,21,#20152,0,"\.")
#20155=@"loc,{#10000},1,147,1,148"
locations_default(#20155,#10000,1,147,1,148)
hasLocation(#20154,#20155)
regexp_const_value(#20154,".")
#20156=*
regexpterm(#20156,9,#20152,1,"[\S--[\p{P}<>]]+")
#20157=@"loc,{#10000},1,149,1,164"
locations_default(#20157,#10000,1,149,1,164)
hasLocation(#20156,#20157)
is_greedy(#20156)
#20158=*
regexpterm(#20158,23,#20156,0,"[\S--[\p{P}<>]]")
#20159=@"loc,{#10000},1,149,1,163"
locations_default(#20159,#10000,1,149,1,163)
hasLocation(#20158,#20159)
#20160=*
regexpterm(#20160,30,#20158,0,"[\S--[\p{P}<>]]")
hasLocation(#20160,#20159)
#20161=*
regexpterm(#20161,20,#20160,0,"\S")
#20162=@"loc,{#10000},1,150,1,151"
locations_default(#20162,#10000,1,150,1,151)
hasLocation(#20161,#20162)
char_class_escape(#20161,"S")
#20163=*
regexpterm(#20163,23,#20160,1,"[\p{P}<>]")
#20164=@"loc,{#10000},1,154,1,162"
locations_default(#20164,#10000,1,154,1,162)
hasLocation(#20163,#20164)
#20165=*
regexpterm(#20165,27,#20163,0,"\p{P}")
#20166=@"loc,{#10000},1,155,1,159"
locations_default(#20166,#10000,1,155,1,159)
hasLocation(#20165,#20166)
unicode_property_escapename(#20165,"P")
#20167=*
regexpterm(#20167,14,#20163,1,"<")
#20168=@"loc,{#10000},1,160,1,160"
locations_default(#20168,#10000,1,160,1,160)
hasLocation(#20167,#20168)
regexp_const_value(#20167,"<")
#20169=*
regexpterm(#20169,14,#20163,2,">")
#20170=@"loc,{#10000},1,161,1,161"
locations_default(#20170,#10000,1,161,1,161)
hasLocation(#20169,#20170)
regexp_const_value(#20169,">")
#20171=*
entry_cfg_node(#20171,#20001)
#20172=@"loc,{#10000},1,1,1,0"
locations_default(#20172,#10000,1,1,1,0)
hasLocation(#20171,#20172)
#20173=*
exit_cfg_node(#20173,#20001)
hasLocation(#20173,#20015)
successor(#20018,#20021)
successor(#20022,#20019)
successor(#20021,#20022)
successor(#20019,#20173)
successor(#20171,#20018)
numlines(#10000,1,1,0)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,392 @@
#10000=@"/union.js;sourcefile"
files(#10000,"/union.js")
#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=*
lines(#20002,#20001,"/[\p{Script_Extensions=Greek}\p{RGI_Emoji}]/v;","
")
#20003=@"loc,{#10000},1,1,1,46"
locations_default(#20003,#10000,1,1,1,46)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"/[[abc][cbd]]/v;","
")
#20005=@"loc,{#10000},2,1,2,16"
locations_default(#20005,#10000,2,1,2,16)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"/[\p{Emoji}\q{a&}byz]/v;","
")
#20007=@"loc,{#10000},3,1,3,24"
locations_default(#20007,#10000,3,1,3,24)
hasLocation(#20006,#20007)
#20008=*
lines(#20008,#20001,"/[\q{\\\}a&}byz]/v;","
")
#20009=@"loc,{#10000},4,1,4,19"
locations_default(#20009,#10000,4,1,4,19)
hasLocation(#20008,#20009)
#20010=*
lines(#20010,#20001,"/[\q{\\}]/v;","
")
#20011=@"loc,{#10000},5,1,5,12"
locations_default(#20011,#10000,5,1,5,12)
hasLocation(#20010,#20011)
#20012=*
lines(#20012,#20001,"/[\q{abc|cbd|\}}]/v;","
")
#20013=@"loc,{#10000},6,1,6,20"
locations_default(#20013,#10000,6,1,6,20)
hasLocation(#20012,#20013)
numlines(#20001,6,6,0)
#20014=*
tokeninfo(#20014,5,#20001,0,"/[\p{Script_Extensions=Greek}\p{RGI_Emoji}]/v")
#20015=@"loc,{#10000},1,1,1,45"
locations_default(#20015,#10000,1,1,1,45)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,8,#20001,1,";")
#20017=@"loc,{#10000},1,46,1,46"
locations_default(#20017,#10000,1,46,1,46)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,5,#20001,2,"/[[abc][cbd]]/v")
#20019=@"loc,{#10000},2,1,2,15"
locations_default(#20019,#10000,2,1,2,15)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,8,#20001,3,";")
#20021=@"loc,{#10000},2,16,2,16"
locations_default(#20021,#10000,2,16,2,16)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,5,#20001,4,"/[\p{Emoji}\q{a&}byz]/v")
#20023=@"loc,{#10000},3,1,3,23"
locations_default(#20023,#10000,3,1,3,23)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,8,#20001,5,";")
#20025=@"loc,{#10000},3,24,3,24"
locations_default(#20025,#10000,3,24,3,24)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,5,#20001,6,"/[\q{\\\}a&}byz]/v")
#20027=@"loc,{#10000},4,1,4,18"
locations_default(#20027,#10000,4,1,4,18)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,8,#20001,7,";")
#20029=@"loc,{#10000},4,19,4,19"
locations_default(#20029,#10000,4,19,4,19)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,5,#20001,8,"/[\q{\\}]/v")
#20031=@"loc,{#10000},5,1,5,11"
locations_default(#20031,#10000,5,1,5,11)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,8,#20001,9,";")
#20033=@"loc,{#10000},5,12,5,12"
locations_default(#20033,#10000,5,12,5,12)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,5,#20001,10,"/[\q{abc|cbd|\}}]/v")
#20035=@"loc,{#10000},6,1,6,19"
locations_default(#20035,#10000,6,1,6,19)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,8,#20001,11,";")
#20037=@"loc,{#10000},6,20,6,20"
locations_default(#20037,#10000,6,20,6,20)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,0,#20001,12,"")
#20039=@"loc,{#10000},7,1,7,0"
locations_default(#20039,#10000,7,1,7,0)
hasLocation(#20038,#20039)
toplevels(#20001,0)
#20040=@"loc,{#10000},1,1,7,0"
locations_default(#20040,#10000,1,1,7,0)
hasLocation(#20001,#20040)
#20041=*
stmts(#20041,2,#20001,0,"/[\p{Sc ... ji}]/v;")
hasLocation(#20041,#20003)
stmt_containers(#20041,#20001)
#20042=*
exprs(#20042,5,#20041,0,"/[\p{Sc ... oji}]/v")
hasLocation(#20042,#20015)
enclosing_stmt(#20042,#20041)
expr_containers(#20042,#20001)
literals("/[\p{Script_Extensions=Greek}\p{RGI_Emoji}]/v","/[\p{Script_Extensions=Greek}\p{RGI_Emoji}]/v",#20042)
#20043=*
regexpterm(#20043,23,#20042,0,"[\p{Script_Extensions=Greek}\p{RGI_Emoji}]")
#20044=@"loc,{#10000},1,2,1,43"
locations_default(#20044,#10000,1,2,1,43)
hasLocation(#20043,#20044)
#20045=*
regexpterm(#20045,27,#20043,0,"\p{Script_Extensions=Greek}")
#20046=@"loc,{#10000},1,3,1,29"
locations_default(#20046,#10000,1,3,1,29)
hasLocation(#20045,#20046)
unicode_property_escapename(#20045,"Script_Extensions")
unicode_property_escapevalue(#20045,"Greek")
#20047=*
regexpterm(#20047,27,#20043,1,"\p{RGI_Emoji}")
#20048=@"loc,{#10000},1,30,1,42"
locations_default(#20048,#10000,1,30,1,42)
hasLocation(#20047,#20048)
unicode_property_escapename(#20047,"RGI_Emoji")
#20049=*
stmts(#20049,2,#20001,1,"/[[abc][cbd]]/v;")
hasLocation(#20049,#20005)
stmt_containers(#20049,#20001)
#20050=*
exprs(#20050,5,#20049,0,"/[[abc][cbd]]/v")
hasLocation(#20050,#20019)
enclosing_stmt(#20050,#20049)
expr_containers(#20050,#20001)
literals("/[[abc][cbd]]/v","/[[abc][cbd]]/v",#20050)
#20051=*
regexpterm(#20051,23,#20050,0,"[[abc][cbd]]")
#20052=@"loc,{#10000},2,2,2,13"
locations_default(#20052,#10000,2,2,2,13)
hasLocation(#20051,#20052)
#20053=*
regexpterm(#20053,23,#20051,0,"[abc]")
#20054=@"loc,{#10000},2,3,2,7"
locations_default(#20054,#10000,2,3,2,7)
hasLocation(#20053,#20054)
#20055=*
regexpterm(#20055,14,#20053,0,"a")
#20056=@"loc,{#10000},2,4,2,4"
locations_default(#20056,#10000,2,4,2,4)
hasLocation(#20055,#20056)
regexp_const_value(#20055,"a")
#20057=*
regexpterm(#20057,14,#20053,1,"b")
#20058=@"loc,{#10000},2,5,2,5"
locations_default(#20058,#10000,2,5,2,5)
hasLocation(#20057,#20058)
regexp_const_value(#20057,"b")
#20059=*
regexpterm(#20059,14,#20053,2,"c")
#20060=@"loc,{#10000},2,6,2,6"
locations_default(#20060,#10000,2,6,2,6)
hasLocation(#20059,#20060)
regexp_const_value(#20059,"c")
#20061=*
regexpterm(#20061,23,#20051,1,"[cbd]")
#20062=@"loc,{#10000},2,8,2,12"
locations_default(#20062,#10000,2,8,2,12)
hasLocation(#20061,#20062)
#20063=*
regexpterm(#20063,14,#20061,0,"c")
#20064=@"loc,{#10000},2,9,2,9"
locations_default(#20064,#10000,2,9,2,9)
hasLocation(#20063,#20064)
regexp_const_value(#20063,"c")
#20065=*
regexpterm(#20065,14,#20061,1,"b")
#20066=@"loc,{#10000},2,10,2,10"
locations_default(#20066,#10000,2,10,2,10)
hasLocation(#20065,#20066)
regexp_const_value(#20065,"b")
#20067=*
regexpterm(#20067,14,#20061,2,"d")
#20068=@"loc,{#10000},2,11,2,11"
locations_default(#20068,#10000,2,11,2,11)
hasLocation(#20067,#20068)
regexp_const_value(#20067,"d")
#20069=*
stmts(#20069,2,#20001,2,"/[\p{Em ... byz]/v;")
hasLocation(#20069,#20007)
stmt_containers(#20069,#20001)
#20070=*
exprs(#20070,5,#20069,0,"/[\p{Em ... }byz]/v")
hasLocation(#20070,#20023)
enclosing_stmt(#20070,#20069)
expr_containers(#20070,#20001)
literals("/[\p{Emoji}\q{a&}byz]/v","/[\p{Emoji}\q{a&}byz]/v",#20070)
#20071=*
regexpterm(#20071,23,#20070,0,"[\p{Emoji}\q{a&}byz]")
#20072=@"loc,{#10000},3,2,3,21"
locations_default(#20072,#10000,3,2,3,21)
hasLocation(#20071,#20072)
#20073=*
regexpterm(#20073,27,#20071,0,"\p{Emoji}")
#20074=@"loc,{#10000},3,3,3,11"
locations_default(#20074,#10000,3,3,3,11)
hasLocation(#20073,#20074)
unicode_property_escapename(#20073,"Emoji")
#20075=*
regexpterm(#20075,28,#20071,1,"\q{a&}")
#20076=@"loc,{#10000},3,12,3,17"
locations_default(#20076,#10000,3,12,3,17)
hasLocation(#20075,#20076)
#20077=*
regexpterm(#20077,14,#20075,0,"a&")
#20078=@"loc,{#10000},3,15,3,16"
locations_default(#20078,#10000,3,15,3,16)
hasLocation(#20077,#20078)
regexp_const_value(#20077,"a&")
#20079=*
regexpterm(#20079,14,#20071,2,"b")
#20080=@"loc,{#10000},3,18,3,18"
locations_default(#20080,#10000,3,18,3,18)
hasLocation(#20079,#20080)
regexp_const_value(#20079,"b")
#20081=*
regexpterm(#20081,14,#20071,3,"y")
#20082=@"loc,{#10000},3,19,3,19"
locations_default(#20082,#10000,3,19,3,19)
hasLocation(#20081,#20082)
regexp_const_value(#20081,"y")
#20083=*
regexpterm(#20083,14,#20071,4,"z")
#20084=@"loc,{#10000},3,20,3,20"
locations_default(#20084,#10000,3,20,3,20)
hasLocation(#20083,#20084)
regexp_const_value(#20083,"z")
#20085=*
stmts(#20085,2,#20001,3,"/[\q{\\\}a&}byz]/v;")
hasLocation(#20085,#20009)
stmt_containers(#20085,#20001)
#20086=*
exprs(#20086,5,#20085,0,"/[\q{\\\}a&}byz]/v")
hasLocation(#20086,#20027)
enclosing_stmt(#20086,#20085)
expr_containers(#20086,#20001)
literals("/[\q{\\\}a&}byz]/v","/[\q{\\\}a&}byz]/v",#20086)
#20087=*
regexpterm(#20087,23,#20086,0,"[\q{\\\}a&}byz]")
#20088=@"loc,{#10000},4,2,4,16"
locations_default(#20088,#10000,4,2,4,16)
hasLocation(#20087,#20088)
#20089=*
regexpterm(#20089,28,#20087,0,"\q{\\\}a&}")
#20090=@"loc,{#10000},4,3,4,12"
locations_default(#20090,#10000,4,3,4,12)
hasLocation(#20089,#20090)
#20091=*
regexpterm(#20091,14,#20089,0,"\\\}a&")
#20092=@"loc,{#10000},4,6,4,11"
locations_default(#20092,#10000,4,6,4,11)
hasLocation(#20091,#20092)
regexp_const_value(#20091,"\\\}a&")
#20093=*
regexpterm(#20093,14,#20087,1,"b")
#20094=@"loc,{#10000},4,13,4,13"
locations_default(#20094,#10000,4,13,4,13)
hasLocation(#20093,#20094)
regexp_const_value(#20093,"b")
#20095=*
regexpterm(#20095,14,#20087,2,"y")
#20096=@"loc,{#10000},4,14,4,14"
locations_default(#20096,#10000,4,14,4,14)
hasLocation(#20095,#20096)
regexp_const_value(#20095,"y")
#20097=*
regexpterm(#20097,14,#20087,3,"z")
#20098=@"loc,{#10000},4,15,4,15"
locations_default(#20098,#10000,4,15,4,15)
hasLocation(#20097,#20098)
regexp_const_value(#20097,"z")
#20099=*
stmts(#20099,2,#20001,4,"/[\q{\\}]/v;")
hasLocation(#20099,#20011)
stmt_containers(#20099,#20001)
#20100=*
exprs(#20100,5,#20099,0,"/[\q{\\}]/v")
hasLocation(#20100,#20031)
enclosing_stmt(#20100,#20099)
expr_containers(#20100,#20001)
literals("/[\q{\\}]/v","/[\q{\\}]/v",#20100)
#20101=*
regexpterm(#20101,23,#20100,0,"[\q{\\}]")
#20102=@"loc,{#10000},5,2,5,9"
locations_default(#20102,#10000,5,2,5,9)
hasLocation(#20101,#20102)
#20103=*
regexpterm(#20103,28,#20101,0,"\q{\\}")
#20104=@"loc,{#10000},5,3,5,8"
locations_default(#20104,#10000,5,3,5,8)
hasLocation(#20103,#20104)
#20105=*
regexpterm(#20105,14,#20103,0,"\\")
#20106=@"loc,{#10000},5,6,5,7"
locations_default(#20106,#10000,5,6,5,7)
hasLocation(#20105,#20106)
regexp_const_value(#20105,"\\")
#20107=*
stmts(#20107,2,#20001,5,"/[\q{abc|cbd|\}}]/v;")
hasLocation(#20107,#20013)
stmt_containers(#20107,#20001)
#20108=*
exprs(#20108,5,#20107,0,"/[\q{abc|cbd|\}}]/v")
hasLocation(#20108,#20035)
enclosing_stmt(#20108,#20107)
expr_containers(#20108,#20001)
literals("/[\q{abc|cbd|\}}]/v","/[\q{abc|cbd|\}}]/v",#20108)
#20109=*
regexpterm(#20109,23,#20108,0,"[\q{abc|cbd|\}}]")
#20110=@"loc,{#10000},6,2,6,17"
locations_default(#20110,#10000,6,2,6,17)
hasLocation(#20109,#20110)
#20111=*
regexpterm(#20111,28,#20109,0,"\q{abc|cbd|\}}")
#20112=@"loc,{#10000},6,3,6,16"
locations_default(#20112,#10000,6,3,6,16)
hasLocation(#20111,#20112)
#20113=*
regexpterm(#20113,0,#20111,0,"abc|cbd|\}")
#20114=@"loc,{#10000},6,6,6,15"
locations_default(#20114,#10000,6,6,6,15)
hasLocation(#20113,#20114)
#20115=*
regexpterm(#20115,14,#20113,0,"abc")
#20116=@"loc,{#10000},6,6,6,8"
locations_default(#20116,#10000,6,6,6,8)
hasLocation(#20115,#20116)
regexp_const_value(#20115,"abc")
#20117=*
regexpterm(#20117,14,#20113,1,"cbd")
#20118=@"loc,{#10000},6,10,6,12"
locations_default(#20118,#10000,6,10,6,12)
hasLocation(#20117,#20118)
regexp_const_value(#20117,"cbd")
#20119=*
regexpterm(#20119,14,#20113,2,"\}")
#20120=@"loc,{#10000},6,14,6,15"
locations_default(#20120,#10000,6,14,6,15)
hasLocation(#20119,#20120)
regexp_const_value(#20119,"\}")
#20121=*
entry_cfg_node(#20121,#20001)
#20122=@"loc,{#10000},1,1,1,0"
locations_default(#20122,#10000,1,1,1,0)
hasLocation(#20121,#20122)
#20123=*
exit_cfg_node(#20123,#20001)
hasLocation(#20123,#20039)
successor(#20107,#20108)
successor(#20108,#20123)
successor(#20099,#20100)
successor(#20100,#20107)
successor(#20085,#20086)
successor(#20086,#20099)
successor(#20069,#20070)
successor(#20070,#20085)
successor(#20049,#20050)
successor(#20050,#20069)
successor(#20041,#20042)
successor(#20042,#20049)
successor(#20121,#20041)
numlines(#10000,6,6,0)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,6 @@
interface Invalid extends (foo.bar) {}
interface Invalid extends (foo).bar {}
interface Invalid extends foo[bar] {}
interface Invalid extends foo?.bar {}
interface Invalid extends foo!.bar {}
interface Invalid extends foo() {}

View File

@@ -0,0 +1,451 @@
#10000=@"/invalidExtends.ts;sourcefile"
files(#10000,"/invalidExtends.ts")
#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=*
lines(#20002,#20001,"interface Invalid extends (foo.bar) {}","
")
#20003=@"loc,{#10000},1,1,1,38"
locations_default(#20003,#10000,1,1,1,38)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"interface Invalid extends (foo).bar {}","
")
#20005=@"loc,{#10000},2,1,2,38"
locations_default(#20005,#10000,2,1,2,38)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"interface Invalid extends foo[bar] {}","
")
#20007=@"loc,{#10000},3,1,3,37"
locations_default(#20007,#10000,3,1,3,37)
hasLocation(#20006,#20007)
#20008=*
lines(#20008,#20001,"interface Invalid extends foo?.bar {}","
")
#20009=@"loc,{#10000},4,1,4,37"
locations_default(#20009,#10000,4,1,4,37)
hasLocation(#20008,#20009)
#20010=*
lines(#20010,#20001,"interface Invalid extends foo!.bar {}","
")
#20011=@"loc,{#10000},5,1,5,37"
locations_default(#20011,#10000,5,1,5,37)
hasLocation(#20010,#20011)
#20012=*
lines(#20012,#20001,"interface Invalid extends foo() {}","
")
#20013=@"loc,{#10000},6,1,6,34"
locations_default(#20013,#10000,6,1,6,34)
hasLocation(#20012,#20013)
numlines(#20001,6,6,0)
#20014=*
tokeninfo(#20014,7,#20001,0,"interface")
#20015=@"loc,{#10000},1,1,1,9"
locations_default(#20015,#10000,1,1,1,9)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,6,#20001,1,"Invalid")
#20017=@"loc,{#10000},1,11,1,17"
locations_default(#20017,#10000,1,11,1,17)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,7,#20001,2,"extends")
#20019=@"loc,{#10000},1,19,1,25"
locations_default(#20019,#10000,1,19,1,25)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,8,#20001,3,"(")
#20021=@"loc,{#10000},1,27,1,27"
locations_default(#20021,#10000,1,27,1,27)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,6,#20001,4,"foo")
#20023=@"loc,{#10000},1,28,1,30"
locations_default(#20023,#10000,1,28,1,30)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,8,#20001,5,".")
#20025=@"loc,{#10000},1,31,1,31"
locations_default(#20025,#10000,1,31,1,31)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,6,#20001,6,"bar")
#20027=@"loc,{#10000},1,32,1,34"
locations_default(#20027,#10000,1,32,1,34)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,8,#20001,7,")")
#20029=@"loc,{#10000},1,35,1,35"
locations_default(#20029,#10000,1,35,1,35)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,8,#20001,8,"{")
#20031=@"loc,{#10000},1,37,1,37"
locations_default(#20031,#10000,1,37,1,37)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,8,#20001,9,"}")
#20033=@"loc,{#10000},1,38,1,38"
locations_default(#20033,#10000,1,38,1,38)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,7,#20001,10,"interface")
#20035=@"loc,{#10000},2,1,2,9"
locations_default(#20035,#10000,2,1,2,9)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,6,#20001,11,"Invalid")
#20037=@"loc,{#10000},2,11,2,17"
locations_default(#20037,#10000,2,11,2,17)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,7,#20001,12,"extends")
#20039=@"loc,{#10000},2,19,2,25"
locations_default(#20039,#10000,2,19,2,25)
hasLocation(#20038,#20039)
#20040=*
tokeninfo(#20040,8,#20001,13,"(")
#20041=@"loc,{#10000},2,27,2,27"
locations_default(#20041,#10000,2,27,2,27)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,6,#20001,14,"foo")
#20043=@"loc,{#10000},2,28,2,30"
locations_default(#20043,#10000,2,28,2,30)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,8,#20001,15,")")
#20045=@"loc,{#10000},2,31,2,31"
locations_default(#20045,#10000,2,31,2,31)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,8,#20001,16,".")
#20047=@"loc,{#10000},2,32,2,32"
locations_default(#20047,#10000,2,32,2,32)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,6,#20001,17,"bar")
#20049=@"loc,{#10000},2,33,2,35"
locations_default(#20049,#10000,2,33,2,35)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,8,#20001,18,"{")
#20051=@"loc,{#10000},2,37,2,37"
locations_default(#20051,#10000,2,37,2,37)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,8,#20001,19,"}")
#20053=@"loc,{#10000},2,38,2,38"
locations_default(#20053,#10000,2,38,2,38)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,7,#20001,20,"interface")
#20055=@"loc,{#10000},3,1,3,9"
locations_default(#20055,#10000,3,1,3,9)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,6,#20001,21,"Invalid")
#20057=@"loc,{#10000},3,11,3,17"
locations_default(#20057,#10000,3,11,3,17)
hasLocation(#20056,#20057)
#20058=*
tokeninfo(#20058,7,#20001,22,"extends")
#20059=@"loc,{#10000},3,19,3,25"
locations_default(#20059,#10000,3,19,3,25)
hasLocation(#20058,#20059)
#20060=*
tokeninfo(#20060,6,#20001,23,"foo")
#20061=@"loc,{#10000},3,27,3,29"
locations_default(#20061,#10000,3,27,3,29)
hasLocation(#20060,#20061)
#20062=*
tokeninfo(#20062,8,#20001,24,"[")
#20063=@"loc,{#10000},3,30,3,30"
locations_default(#20063,#10000,3,30,3,30)
hasLocation(#20062,#20063)
#20064=*
tokeninfo(#20064,6,#20001,25,"bar")
#20065=@"loc,{#10000},3,31,3,33"
locations_default(#20065,#10000,3,31,3,33)
hasLocation(#20064,#20065)
#20066=*
tokeninfo(#20066,8,#20001,26,"]")
#20067=@"loc,{#10000},3,34,3,34"
locations_default(#20067,#10000,3,34,3,34)
hasLocation(#20066,#20067)
#20068=*
tokeninfo(#20068,8,#20001,27,"{")
#20069=@"loc,{#10000},3,36,3,36"
locations_default(#20069,#10000,3,36,3,36)
hasLocation(#20068,#20069)
#20070=*
tokeninfo(#20070,8,#20001,28,"}")
#20071=@"loc,{#10000},3,37,3,37"
locations_default(#20071,#10000,3,37,3,37)
hasLocation(#20070,#20071)
#20072=*
tokeninfo(#20072,7,#20001,29,"interface")
#20073=@"loc,{#10000},4,1,4,9"
locations_default(#20073,#10000,4,1,4,9)
hasLocation(#20072,#20073)
#20074=*
tokeninfo(#20074,6,#20001,30,"Invalid")
#20075=@"loc,{#10000},4,11,4,17"
locations_default(#20075,#10000,4,11,4,17)
hasLocation(#20074,#20075)
#20076=*
tokeninfo(#20076,7,#20001,31,"extends")
#20077=@"loc,{#10000},4,19,4,25"
locations_default(#20077,#10000,4,19,4,25)
hasLocation(#20076,#20077)
#20078=*
tokeninfo(#20078,6,#20001,32,"foo")
#20079=@"loc,{#10000},4,27,4,29"
locations_default(#20079,#10000,4,27,4,29)
hasLocation(#20078,#20079)
#20080=*
tokeninfo(#20080,8,#20001,33,"?.")
#20081=@"loc,{#10000},4,30,4,31"
locations_default(#20081,#10000,4,30,4,31)
hasLocation(#20080,#20081)
#20082=*
tokeninfo(#20082,6,#20001,34,"bar")
#20083=@"loc,{#10000},4,32,4,34"
locations_default(#20083,#10000,4,32,4,34)
hasLocation(#20082,#20083)
#20084=*
tokeninfo(#20084,8,#20001,35,"{")
#20085=@"loc,{#10000},4,36,4,36"
locations_default(#20085,#10000,4,36,4,36)
hasLocation(#20084,#20085)
#20086=*
tokeninfo(#20086,8,#20001,36,"}")
#20087=@"loc,{#10000},4,37,4,37"
locations_default(#20087,#10000,4,37,4,37)
hasLocation(#20086,#20087)
#20088=*
tokeninfo(#20088,7,#20001,37,"interface")
#20089=@"loc,{#10000},5,1,5,9"
locations_default(#20089,#10000,5,1,5,9)
hasLocation(#20088,#20089)
#20090=*
tokeninfo(#20090,6,#20001,38,"Invalid")
#20091=@"loc,{#10000},5,11,5,17"
locations_default(#20091,#10000,5,11,5,17)
hasLocation(#20090,#20091)
#20092=*
tokeninfo(#20092,7,#20001,39,"extends")
#20093=@"loc,{#10000},5,19,5,25"
locations_default(#20093,#10000,5,19,5,25)
hasLocation(#20092,#20093)
#20094=*
tokeninfo(#20094,6,#20001,40,"foo")
#20095=@"loc,{#10000},5,27,5,29"
locations_default(#20095,#10000,5,27,5,29)
hasLocation(#20094,#20095)
#20096=*
tokeninfo(#20096,8,#20001,41,"!")
#20097=@"loc,{#10000},5,30,5,30"
locations_default(#20097,#10000,5,30,5,30)
hasLocation(#20096,#20097)
#20098=*
tokeninfo(#20098,8,#20001,42,".")
#20099=@"loc,{#10000},5,31,5,31"
locations_default(#20099,#10000,5,31,5,31)
hasLocation(#20098,#20099)
#20100=*
tokeninfo(#20100,6,#20001,43,"bar")
#20101=@"loc,{#10000},5,32,5,34"
locations_default(#20101,#10000,5,32,5,34)
hasLocation(#20100,#20101)
#20102=*
tokeninfo(#20102,8,#20001,44,"{")
#20103=@"loc,{#10000},5,36,5,36"
locations_default(#20103,#10000,5,36,5,36)
hasLocation(#20102,#20103)
#20104=*
tokeninfo(#20104,8,#20001,45,"}")
#20105=@"loc,{#10000},5,37,5,37"
locations_default(#20105,#10000,5,37,5,37)
hasLocation(#20104,#20105)
#20106=*
tokeninfo(#20106,7,#20001,46,"interface")
#20107=@"loc,{#10000},6,1,6,9"
locations_default(#20107,#10000,6,1,6,9)
hasLocation(#20106,#20107)
#20108=*
tokeninfo(#20108,6,#20001,47,"Invalid")
#20109=@"loc,{#10000},6,11,6,17"
locations_default(#20109,#10000,6,11,6,17)
hasLocation(#20108,#20109)
#20110=*
tokeninfo(#20110,7,#20001,48,"extends")
#20111=@"loc,{#10000},6,19,6,25"
locations_default(#20111,#10000,6,19,6,25)
hasLocation(#20110,#20111)
#20112=*
tokeninfo(#20112,6,#20001,49,"foo")
#20113=@"loc,{#10000},6,27,6,29"
locations_default(#20113,#10000,6,27,6,29)
hasLocation(#20112,#20113)
#20114=*
tokeninfo(#20114,8,#20001,50,"(")
#20115=@"loc,{#10000},6,30,6,30"
locations_default(#20115,#10000,6,30,6,30)
hasLocation(#20114,#20115)
#20116=*
tokeninfo(#20116,8,#20001,51,")")
#20117=@"loc,{#10000},6,31,6,31"
locations_default(#20117,#10000,6,31,6,31)
hasLocation(#20116,#20117)
#20118=*
tokeninfo(#20118,8,#20001,52,"{")
#20119=@"loc,{#10000},6,33,6,33"
locations_default(#20119,#10000,6,33,6,33)
hasLocation(#20118,#20119)
#20120=*
tokeninfo(#20120,8,#20001,53,"}")
#20121=@"loc,{#10000},6,34,6,34"
locations_default(#20121,#10000,6,34,6,34)
hasLocation(#20120,#20121)
#20122=*
tokeninfo(#20122,0,#20001,54,"")
#20123=@"loc,{#10000},7,1,7,0"
locations_default(#20123,#10000,7,1,7,0)
hasLocation(#20122,#20123)
toplevels(#20001,0)
#20124=@"loc,{#10000},1,1,7,0"
locations_default(#20124,#10000,1,1,7,0)
hasLocation(#20001,#20124)
#20125=@"local_type_name;{Invalid};{#20000}"
local_type_names(#20125,"Invalid",#20000)
#20126=*
stmts(#20126,34,#20001,0,"interfa ... bar) {}")
hasLocation(#20126,#20003)
stmt_containers(#20126,#20001)
#20127=*
typeexprs(#20127,1,#20126,0,"Invalid")
hasLocation(#20127,#20017)
enclosing_stmt(#20127,#20126)
expr_containers(#20127,#20001)
literals("Invalid","Invalid",#20127)
typedecl(#20127,#20125)
#20128=*
stmts(#20128,34,#20001,1,"interfa ... .bar {}")
hasLocation(#20128,#20005)
stmt_containers(#20128,#20001)
#20129=*
typeexprs(#20129,1,#20128,0,"Invalid")
hasLocation(#20129,#20037)
enclosing_stmt(#20129,#20128)
expr_containers(#20129,#20001)
literals("Invalid","Invalid",#20129)
typedecl(#20129,#20125)
#20130=*
stmts(#20130,34,#20001,2,"interfa ... bar] {}")
hasLocation(#20130,#20007)
stmt_containers(#20130,#20001)
#20131=*
typeexprs(#20131,13,#20130,-1,"foo[bar]")
#20132=@"loc,{#10000},3,27,3,34"
locations_default(#20132,#10000,3,27,3,34)
hasLocation(#20131,#20132)
enclosing_stmt(#20131,#20130)
expr_containers(#20131,#20001)
#20133=*
typeexprs(#20133,25,#20131,0,"foo")
hasLocation(#20133,#20061)
enclosing_stmt(#20133,#20130)
expr_containers(#20133,#20001)
literals("foo","foo",#20133)
#20134=*
typeexprs(#20134,15,#20131,1,"bar")
hasLocation(#20134,#20065)
enclosing_stmt(#20134,#20130)
expr_containers(#20134,#20001)
literals("bar","bar",#20134)
#20135=*
typeexprs(#20135,1,#20130,0,"Invalid")
hasLocation(#20135,#20057)
enclosing_stmt(#20135,#20130)
expr_containers(#20135,#20001)
literals("Invalid","Invalid",#20135)
typedecl(#20135,#20125)
#20136=*
stmts(#20136,34,#20001,3,"interfa ... .bar {}")
hasLocation(#20136,#20009)
stmt_containers(#20136,#20001)
#20137=*
typeexprs(#20137,13,#20136,-1,"foo?.bar")
#20138=@"loc,{#10000},4,27,4,34"
locations_default(#20138,#10000,4,27,4,34)
hasLocation(#20137,#20138)
enclosing_stmt(#20137,#20136)
expr_containers(#20137,#20001)
#20139=*
typeexprs(#20139,25,#20137,0,"foo")
hasLocation(#20139,#20079)
enclosing_stmt(#20139,#20136)
expr_containers(#20139,#20001)
literals("foo","foo",#20139)
#20140=*
typeexprs(#20140,15,#20137,1,"bar")
hasLocation(#20140,#20083)
enclosing_stmt(#20140,#20136)
expr_containers(#20140,#20001)
literals("bar","bar",#20140)
isOptionalChaining(#20137)
#20141=*
typeexprs(#20141,1,#20136,0,"Invalid")
hasLocation(#20141,#20075)
enclosing_stmt(#20141,#20136)
expr_containers(#20141,#20001)
literals("Invalid","Invalid",#20141)
typedecl(#20141,#20125)
#20142=*
stmts(#20142,34,#20001,4,"interfa ... .bar {}")
hasLocation(#20142,#20011)
stmt_containers(#20142,#20001)
#20143=*
typeexprs(#20143,1,#20142,0,"Invalid")
hasLocation(#20143,#20091)
enclosing_stmt(#20143,#20142)
expr_containers(#20143,#20001)
literals("Invalid","Invalid",#20143)
typedecl(#20143,#20125)
#20144=*
stmts(#20144,34,#20001,5,"interfa ... oo() {}")
hasLocation(#20144,#20013)
stmt_containers(#20144,#20001)
#20145=*
typeexprs(#20145,1,#20144,0,"Invalid")
hasLocation(#20145,#20109)
enclosing_stmt(#20145,#20144)
expr_containers(#20145,#20001)
literals("Invalid","Invalid",#20145)
typedecl(#20145,#20125)
#20146=*
entry_cfg_node(#20146,#20001)
#20147=@"loc,{#10000},1,1,1,0"
locations_default(#20147,#10000,1,1,1,0)
hasLocation(#20146,#20147)
#20148=*
exit_cfg_node(#20148,#20001)
hasLocation(#20148,#20123)
successor(#20144,#20148)
successor(#20142,#20144)
successor(#20136,#20142)
successor(#20130,#20136)
successor(#20128,#20130)
successor(#20126,#20128)
successor(#20146,#20126)
numlines(#10000,6,6,0)
filetype(#10000,"typescript")

View File

@@ -0,0 +1,16 @@
{
"Type": "sap.ui.core.mvc.JSONView",
"controllerName": "codeql-sap-js.controller.app",
"content": [
{
"Type": "sap.m.Input",
"placeholder": "Enter Payload",
"description": "Try: <img src=x onerror=alert(\"XSS\")>",
"value": "{/input}"
},
{
"Type": "sap.ui.core.HTML",
"content": "{/input}"
}
]
}

View File

@@ -0,0 +1,87 @@
#10000=@"/test.view.json;sourcefile"
files(#10000,"/test.view.json")
#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=*
json(#20000,5,#10000,0,"{\n "" ... ]\n}")
#20001=@"loc,{#10000},1,1,16,1"
locations_default(#20001,#10000,1,1,16,1)
json_locations(#20000,#20001)
#20002=*
json(#20002,3,#20000,0,"""sap.ui ... ONView""")
#20003=@"loc,{#10000},2,13,2,38"
locations_default(#20003,#10000,2,13,2,38)
json_locations(#20002,#20003)
json_literals("sap.ui.core.mvc.JSONView","""sap.ui.core.mvc.JSONView""",#20002)
json_properties(#20000,"Type",#20002)
#20004=*
json(#20004,3,#20000,1,"""codeql ... er.app""")
#20005=@"loc,{#10000},3,23,3,52"
locations_default(#20005,#10000,3,23,3,52)
json_locations(#20004,#20005)
json_literals("codeql-sap-js.controller.app","""codeql-sap-js.controller.app""",#20004)
json_properties(#20000,"controllerName",#20004)
#20006=*
json(#20006,4,#20000,2,"[\n ... }\n ]")
#20007=@"loc,{#10000},4,16,15,5"
locations_default(#20007,#10000,4,16,15,5)
json_locations(#20006,#20007)
#20008=*
json(#20008,5,#20006,0,"{\n ... }")
#20009=@"loc,{#10000},5,9,10,9"
locations_default(#20009,#10000,5,9,10,9)
json_locations(#20008,#20009)
#20010=*
json(#20010,3,#20008,0,"""sap.m.Input""")
#20011=@"loc,{#10000},6,21,6,33"
locations_default(#20011,#10000,6,21,6,33)
json_locations(#20010,#20011)
json_literals("sap.m.Input","""sap.m.Input""",#20010)
json_properties(#20008,"Type",#20010)
#20012=*
json(#20012,3,#20008,1,"""Enter Payload""")
#20013=@"loc,{#10000},7,28,7,42"
locations_default(#20013,#10000,7,28,7,42)
json_locations(#20012,#20013)
json_literals("Enter Payload","""Enter Payload""",#20012)
json_properties(#20008,"placeholder",#20012)
#20014=*
json(#20014,3,#20008,2,"""Try: < ... SS\"")>""")
#20015=@"loc,{#10000},8,28,8,68"
locations_default(#20015,#10000,8,28,8,68)
json_locations(#20014,#20015)
json_literals("Try: <img src=x onerror=alert(""XSS"")>","""Try: <img src=x onerror=alert(\""XSS\"")>""",#20014)
json_properties(#20008,"description",#20014)
#20016=*
json(#20016,3,#20008,3,"""{/input}""")
#20017=@"loc,{#10000},9,22,9,31"
locations_default(#20017,#10000,9,22,9,31)
json_locations(#20016,#20017)
json_literals("{/input}","""{/input}""",#20016)
json_properties(#20008,"value",#20016)
#20018=*
json(#20018,5,#20006,1,"{\n ... }")
#20019=@"loc,{#10000},11,9,14,9"
locations_default(#20019,#10000,11,9,14,9)
json_locations(#20018,#20019)
#20020=*
json(#20020,3,#20018,0,"""sap.ui.core.HTML""")
#20021=@"loc,{#10000},12,21,12,38"
locations_default(#20021,#10000,12,21,12,38)
json_locations(#20020,#20021)
json_literals("sap.ui.core.HTML","""sap.ui.core.HTML""",#20020)
json_properties(#20018,"Type",#20020)
#20022=*
json(#20022,3,#20018,1,"""{/input}""")
#20023=@"loc,{#10000},13,24,13,33"
locations_default(#20023,#10000,13,24,13,33)
json_locations(#20022,#20023)
json_literals("{/input}","""{/input}""",#20022)
json_properties(#20018,"content",#20022)
json_properties(#20000,"content",#20006)
numlines(#10000,16,0,0)
filetype(#10000,"json")

View File

@@ -0,0 +1,12 @@
{
"welcomeFile": "index.html",
"authenticationMethod": "none",
"routes": [
{
"source": "/bad/(.*)",
"destination": "srv_api",
"csrfProtection": false,
"authenticationType": "none"
}
]
}

View File

@@ -0,0 +1,68 @@
#10000=@"/xs-app.json;sourcefile"
files(#10000,"/xs-app.json")
#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=*
json(#20000,5,#10000,0,"{\n "" ... ]\n}")
#20001=@"loc,{#10000},1,1,12,1"
locations_default(#20001,#10000,1,1,12,1)
json_locations(#20000,#20001)
#20002=*
json(#20002,3,#20000,0,"""index.html""")
#20003=@"loc,{#10000},2,20,2,31"
locations_default(#20003,#10000,2,20,2,31)
json_locations(#20002,#20003)
json_literals("index.html","""index.html""",#20002)
json_properties(#20000,"welcomeFile",#20002)
#20004=*
json(#20004,3,#20000,1,"""none""")
#20005=@"loc,{#10000},3,29,3,34"
locations_default(#20005,#10000,3,29,3,34)
json_locations(#20004,#20005)
json_literals("none","""none""",#20004)
json_properties(#20000,"authenticationMethod",#20004)
#20006=*
json(#20006,4,#20000,2,"[\n ... }\n ]")
#20007=@"loc,{#10000},4,15,11,5"
locations_default(#20007,#10000,4,15,11,5)
json_locations(#20006,#20007)
#20008=*
json(#20008,5,#20006,0,"{\n ... }")
#20009=@"loc,{#10000},5,9,10,9"
locations_default(#20009,#10000,5,9,10,9)
json_locations(#20008,#20009)
#20010=*
json(#20010,3,#20008,0,"""/bad/(.*)""")
#20011=@"loc,{#10000},6,23,6,33"
locations_default(#20011,#10000,6,23,6,33)
json_locations(#20010,#20011)
json_literals("/bad/(.*)","""/bad/(.*)""",#20010)
json_properties(#20008,"source",#20010)
#20012=*
json(#20012,3,#20008,1,"""srv_api""")
#20013=@"loc,{#10000},7,28,7,36"
locations_default(#20013,#10000,7,28,7,36)
json_locations(#20012,#20013)
json_literals("srv_api","""srv_api""",#20012)
json_properties(#20008,"destination",#20012)
#20014=*
json(#20014,1,#20008,2,"false")
#20015=@"loc,{#10000},8,31,8,35"
locations_default(#20015,#10000,8,31,8,35)
json_locations(#20014,#20015)
json_literals("false","false",#20014)
json_properties(#20008,"csrfProtection",#20014)
#20016=*
json(#20016,3,#20008,3,"""none""")
#20017=@"loc,{#10000},9,35,9,40"
locations_default(#20017,#10000,9,35,9,40)
json_locations(#20016,#20017)
json_literals("none","""none""",#20016)
json_properties(#20008,"authenticationType",#20016)
json_properties(#20000,"routes",#20006)
numlines(#10000,12,0,0)
filetype(#10000,"json")

View File

@@ -1,3 +1,35 @@
## 2.6.0
### New Features
* Extraction now supports regular expressions with the `v` flag, using the new operators:
- Intersection `&&`
- Subtraction `--`
- `\q` quoted string
### Major Analysis Improvements
* Added support for TypeScript 5.8.
### Minor Analysis Improvements
* Added support for additional `fs-extra` methods as sinks in path-injection queries.
* Added support for the newer version of `Hapi` with the `@hapi/hapi` import and `server` function.
* Improved modeling of the `node:fs` module: `await`-ed calls to `read` and `readFile` are now supported.
* Added support for the `@sap/hana-client`, `@sap/hdbext` and `hdb` packages.
* Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`.
* Improved support for `got` package with `Options`, `paginate()` and `extend()`
* Added support for the `ApolloServer` class from `@apollo/server` and similar packages. In particular, the incoming data in a GraphQL resolver is now seen as a source of untrusted user input.
* Improved support for `superagent` to handle the case where the package is directly called as a function, or via the `.del()` or `.agent()` method.
* Added support for the `underscore.string` package.
* Added additional flow step for `unescape()` and `escape()`.
* Added support for the `@tanstack/vue-query` package.
* Added taint-steps for `unescape()`.
* Added support for the `@tanstack/angular-query-experimental` package.
* Improved support for the `@angular/common/http` package, detecting outgoing HTTP requests in more cases.
* Improved the modeling of the `markdown-table` package to ensure it handles nested arrays properly.
* Added support for the `react-relay` library.
## 2.5.1
No user-facing changes.

View File

@@ -0,0 +1,31 @@
## 2.6.0
### New Features
* Extraction now supports regular expressions with the `v` flag, using the new operators:
- Intersection `&&`
- Subtraction `--`
- `\q` quoted string
### Major Analysis Improvements
* Added support for TypeScript 5.8.
### Minor Analysis Improvements
* Added support for additional `fs-extra` methods as sinks in path-injection queries.
* Added support for the newer version of `Hapi` with the `@hapi/hapi` import and `server` function.
* Improved modeling of the `node:fs` module: `await`-ed calls to `read` and `readFile` are now supported.
* Added support for the `@sap/hana-client`, `@sap/hdbext` and `hdb` packages.
* Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`.
* Improved support for `got` package with `Options`, `paginate()` and `extend()`
* Added support for the `ApolloServer` class from `@apollo/server` and similar packages. In particular, the incoming data in a GraphQL resolver is now seen as a source of untrusted user input.
* Improved support for `superagent` to handle the case where the package is directly called as a function, or via the `.del()` or `.agent()` method.
* Added support for the `underscore.string` package.
* Added additional flow step for `unescape()` and `escape()`.
* Added support for the `@tanstack/vue-query` package.
* Added taint-steps for `unescape()`.
* Added support for the `@tanstack/angular-query-experimental` package.
* Improved support for the `@angular/common/http` package, detecting outgoing HTTP requests in more cases.
* Improved the modeling of the `markdown-table` package to ensure it handles nested arrays properly.
* Added support for the `react-relay` library.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 2.5.1
lastReleaseVersion: 2.6.0

View File

@@ -0,0 +1,15 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sourceModel
data:
- ["@apollo/server", "Member[ApolloServer,ApolloServerBase].Argument[0].AnyMember.AnyMember.AnyMember.Parameter[1]", "remote"]
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["@apollo/server", "@apollo/server/standalone", ""]
- ["@apollo/server", "apollo-server-express", ""]
- ["@apollo/server", "apollo-server-core", ""]
- ["@apollo/server", "apollo-server", ""]

View File

@@ -0,0 +1,12 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["axios", "Member[interceptors].Member[request].Member[use].Argument[0].Parameter[0].Member[url]", "request-forgery"]
- addsTo:
pack: codeql/javascript-all
extensible: sourceModel
data:
- ["axios", "Member[interceptors].Member[response].Member[use].Argument[0].Parameter[0]", "response"]

View File

@@ -0,0 +1,27 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["@sap/hana-client", "Member[createConnection].ReturnValue.Member[exec,prepare].Argument[0]", "sql-injection"]
- ["hdb.Client", "Member[exec,prepare,execute].Argument[0]", "sql-injection"]
- ["@sap/hdbext", "Member[loadProcedure].Argument[2]", "sql-injection"]
- ["@sap/hana-client/extension/Stream", "Member[createProcStatement].Argument[1]", "sql-injection"]
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["hdb.Client", "hdb", "Member[createClient].ReturnValue"]
- ["hdb.Client", "@sap/hdbext", "Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[0].Member[db]"]
- addsTo:
pack: codeql/javascript-all
extensible: sourceModel
data:
- ['@sap/hana-client', 'Member[createConnection].ReturnValue.Member[exec].Argument[1].Parameter[1]', 'database-access-result']
- ['@sap/hana-client', 'Member[createConnection].ReturnValue.Member[prepare].ReturnValue.Member[execBatch,exec,execQuery].Argument[1].Parameter[1]', 'database-access-result']
- ['hdb.Client', 'Member[exec,execute].Argument[1..2].Parameter[1]', 'database-access-result']
- ['hdb.Client', 'Member[prepare].Argument[1].Parameter[1].Member[exec].Argument[1].Parameter[2..]', 'database-access-result']
- ["@sap/hana-client/extension/Stream", "Member[createProcStatement].Argument[2].Parameter[1].Member[exec].Argument[1].Parameter[2..]", "database-access-result"]
- ['@sap/hdbext', 'Member[loadProcedure].Argument[3].Parameter[1].Argument[2].Parameter[2..]', 'database-access-result']

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: summaryModel
data:
- ["markdown-table", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue", "taint"]

View File

@@ -0,0 +1,15 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sourceModel
data:
- ["react-relay", "Member[useFragment].ReturnValue", "response"]
- ["react-relay", "Member[useLazyLoadQuery].ReturnValue", "response"]
- ["react-relay", "Member[usePreloadedQuery].ReturnValue", "response"]
- ["react-relay", "Member[useClientQuery].ReturnValue", "response"]
- ["react-relay", "Member[useRefetchableFragment].ReturnValue.Member[0]", "response"]
- ["react-relay", "Member[usePaginationFragment].ReturnValue.Member[data]", "response"]
- ["react-relay", "Member[useMutation].ReturnValue.Member[0].Argument[0].Member[onCompleted].Parameter[0]", "response"]
- ["react-relay", "Member[useSubscription].Argument[0].Member[onNext].Parameter[0]", "response"]
- ["react-relay", "Member[fetchQuery].ReturnValue.Member[subscribe].Argument[0].Member[next].Parameter[0]", "response"]
- ["relay-runtime", "Member[readFragment].ReturnValue", "response"]

View File

@@ -0,0 +1,11 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: summaryModel
data:
- ["@tanstack/angular-query-experimental", "Member[injectQuery]", "Argument[0].ReturnValue.Member[queryFn].ReturnValue", "ReturnValue.Member[data].Awaited", "value"]
- ["@tanstack/angular-query", "Member[injectQuery]", "Argument[0].ReturnValue.Member[queryFn].ReturnValue", "ReturnValue.Member[data].Awaited", "value"]
- ["@tanstack/vue-query", "Member[useQuery]", "Argument[0].Member[queryFn].ReturnValue.Awaited", "ReturnValue.Member[data]", "value"]
- ["@tanstack/vue-query", "Member[useQueries]", "Argument[0].Member[queries].ArrayElement.Member[queryFn].ReturnValue.Awaited", "ReturnValue.ArrayElement.Member[data]", "value"]
- ["@tanstack/react-query", "Member[useQueries]", "Argument[0].Member[queries].ArrayElement.Member[queryFn].ReturnValue.Awaited", "ReturnValue.ArrayElement.Member[data]", "value"]
- ["@tanstack/react-query", "Member[useQuery]", "Argument[0].Member[queryFn].ReturnValue.Awaited", "ReturnValue.Member[data]", "value"]

View File

@@ -0,0 +1,35 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["'underscore.string'.Wrapper", "'underscore.string'", "ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[slugify,capitalize,decapitalize,clean,cleanDiacritics,swapCase,escapeHTML,unescapeHTML,wrap,dedent,reverse,pred,succ,titleize,camelize,classify,underscored,dasherize,humanize,trim,ltrim,rtrim,truncate,sprintf,strRight,strRightBack,strLeft,strLeftBack,stripTags,unquote,strip,lstrip,rstrip,camelcase].ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[insert,replaceAll,join,splice,prune,pad,lpad,rpad,repeat,surround,quote,q,rjust,ljust].ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[toUpperCase,toLowerCase,replace,slice,substring,substr,concat].ReturnValue"]
- ["'underscore.string'.Wrapper", "'underscore.string'.Wrapper", "Member[tap].ReturnValue"]
- addsTo:
pack: codeql/javascript-all
extensible: summaryModel
data:
- ["'underscore.string'", "Member[slugify,capitalize,decapitalize,clean,cleanDiacritics,swapCase,escapeHTML,unescapeHTML,wrap,dedent,reverse,pred,succ,titleize,camelize,classify,underscored,dasherize,humanize,trim,ltrim,rtrim,truncate,sprintf,strRight,strRightBack,strLeft,strLeftBack,stripTags,unquote,strip,lstrip,rstrip,camelcase]", "Argument[0]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[chop,chars,words,lines]", "Argument[0]", "ReturnValue.ArrayElement", "taint"]
- ["'underscore.string'", "Member[toSentence,toSentenceSerial]", "Argument[0].ArrayElement", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[insert,replaceAll,splice,prune,pad,lpad,rpad,repeat,rjust,ljust]", "Argument[0,2]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[splice]", "Argument[0,3]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[join]", "Argument[0..]", "ReturnValue", "taint"]
- ["'underscore.string'", "Member[surround,quote,q]", "Argument[0,1]", "ReturnValue", "taint"]
- ["'underscore.string'", "", "Argument[0]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[slugify,capitalize,decapitalize,clean,cleanDiacritics,swapCase,escapeHTML,unescapeHTML,wrap,dedent,reverse,pred,succ,titleize,camelize,classify,underscored,dasherize,humanize,trim,ltrim,rtrim,truncate,sprintf,strRight,strRightBack,strLeft,strLeftBack,stripTags,unquote,value,strip,lstrip,rstrip,camelcase]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[insert,replaceAll,join,splice,prune,pad,lpad,rpad,repeat,surround,quote,q,rjust,ljust]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[insert,replaceAll,prune,pad,lpad,rpad,repeat,rjust,ljust]", "Argument[1]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[surround,quote,q]", "Argument[0]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[splice]", "Argument[2]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[join,concat]", "Argument[0..]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[toUpperCase,toLowerCase,replace,slice,substring,substr,split]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[tap]", "Argument[this]", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[tap]", "Argument[0].ReturnValue", "ReturnValue", "taint"]
- ["'underscore.string'.Wrapper", "Member[tap]", "Argument[this]", "Argument[0].Parameter[1]", "taint"]
- ["'underscore.string'", "Member[map]", "Argument[0]", "Argument[1].Parameter[0]", "taint"]
- ["'underscore.string'", "Member[map]", "Argument[1].ReturnValue", "ReturnValue", "taint"]

View File

@@ -139,8 +139,8 @@ import semmle.javascript.frameworks.Webix
import semmle.javascript.frameworks.WebSocket
import semmle.javascript.frameworks.XmlParsers
import semmle.javascript.frameworks.xUnit
import semmle.javascript.frameworks.Tanstack
import semmle.javascript.linters.ESLint
import semmle.javascript.linters.JSLint
import semmle.javascript.linters.Linting
import semmle.javascript.security.dataflow.RemoteFlowSources
import semmle.javascript.frameworks.UnderscoreDotString

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 2.5.1
version: 2.6.0
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -8,6 +8,10 @@
import javascript
private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps
private import semmle.javascript.dataflow.internal.PreCallGraphStep
private import semmle.javascript.dataflow.internal.StepSummary
private import semmle.javascript.dataflow.internal.sharedlib.SummaryTypeTracker as SummaryTypeTracker
private import semmle.javascript.dataflow.internal.Contents::Private as ContentPrivate
private import semmle.javascript.DynamicPropertyAccess
private import internal.CachedStages
/**
@@ -220,15 +224,53 @@ module API {
}
/**
* Gets a node representing a member of this API component where the name of the member is
* not known statically.
* DEPRECATED. Use either `getArrayElement()` or `getAMember()` instead.
*/
deprecated Node getUnknownMember() { result = this.getArrayElement() }
/**
* Gets an array element of unknown index.
*/
cached
Node getUnknownMember() {
Node getUnknownArrayElement() {
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::unknownMember())
result = this.getASuccessor(Label::content(ContentPrivate::MkArrayElementUnknown()))
}
cached
private Node getContentRaw(DataFlow::Content content) {
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::content(content))
}
/**
* Gets a representative for the `content` of this value.
*
* When possible, it is preferrable to use one of the specialized variants of this predicate, such as `getMember`.
*/
pragma[inline]
Node getContent(DataFlow::Content content) {
result = this.getContentRaw(content)
or
result = this.getMember(content.asPropertyName())
}
/**
* Gets a representative for the `contents` of this value.
*/
bindingset[contents]
pragma[inline_late]
private Node getContents(DataFlow::ContentSet contents) {
// We always use getAStoreContent when generating content edges, and we always use getAReadContent when querying the graph.
result = this.getContent(contents.getAReadContent())
}
/**
* Gets a node representing an arbitrary array element in the array represented by this node.
*/
cached
Node getArrayElement() { result = this.getContents(DataFlow::ContentSet::arrayElement()) }
/**
* Gets a node representing a member of this API component where the name of the member may
* or may not be known statically.
@@ -238,7 +280,7 @@ module API {
Stages::ApiStage::ref() and
result = this.getMember(_)
or
result = this.getUnknownMember()
result = this.getUnknownArrayElement()
}
/**
@@ -790,6 +832,11 @@ module API {
not DataFlow::PseudoProperties::isPseudoProperty(prop)
)
or
exists(DataFlow::ContentSet contents |
SummaryTypeTracker::basicStoreStep(rhs, pred.getALocalUse(), contents) and
lbl = Label::content(contents.getAStoreContent())
)
or
exists(DataFlow::FunctionNode fn |
fn = pred and
lbl = Label::return()
@@ -982,6 +1029,11 @@ module API {
// avoid generating member edges like "$arrayElement$"
not DataFlow::PseudoProperties::isPseudoProperty(prop)
)
or
exists(DataFlow::ContentSet contents |
SummaryTypeTracker::basicLoadStep(pred.getALocalUse(), ref, contents) and
lbl = Label::content(contents.getAStoreContent())
)
)
or
exists(DataFlow::Node def, DataFlow::FunctionNode fn |
@@ -1199,8 +1251,6 @@ module API {
t = useStep(nd, promisified, boundArgs, prop, result)
}
private import semmle.javascript.dataflow.internal.StepSummary
/**
* Holds if `nd`, which is a use of an API-graph node, flows in zero or more potentially
* inter-procedural steps to some intermediate node, and then from that intermediate node to
@@ -1458,8 +1508,21 @@ module API {
bindingset[result]
LabelMember member(string m) { result.getProperty() = m }
/** Gets the `member` edge label for the unknown member. */
LabelUnknownMember unknownMember() { any() }
/** Gets the `content` edge label for content `c`. */
LabelContent content(ContentPrivate::Content c) { result.getContent() = c }
/**
* Gets the edge label for an unknown member.
*
* Currently this is represented the same way as an unknown array element, but this may
* change in the future.
*/
ApiLabel unknownMember() { result = arrayElement() }
/**
* Gets the edge label for an unknown array element.
*/
LabelContent arrayElement() { result.getContent().isUnknownArrayElement() }
/**
* Gets a property name referred to by the given dynamic property access,
@@ -1482,6 +1545,11 @@ module API {
result = unique(string s | s = getAnIndirectPropName(ref))
}
pragma[nomagic]
private predicate isEnumeratedPropName(DataFlow::Node node) {
node.getAPredecessor*() instanceof EnumeratedPropName
}
/** Gets the `member` edge label for the given property reference. */
ApiLabel memberFromRef(DataFlow::PropRef pr) {
exists(string pn | pn = pr.getPropertyName() or pn = getIndirectPropName(pr) |
@@ -1493,7 +1561,9 @@ module API {
or
not exists(pr.getPropertyName()) and
not exists(getIndirectPropName(pr)) and
result = unknownMember()
// Avoid assignments in an extend-like pattern
not isEnumeratedPropName(pr.getPropertyNameExpr().flow()) and
result = arrayElement()
}
/** Gets the `instance` edge label. */
@@ -1516,10 +1586,10 @@ module API {
LabelForwardingFunction forwardingFunction() { any() }
/** Gets the `promised` edge label connecting a promise to its contained value. */
LabelPromised promised() { any() }
LabelContent promised() { result.getContent() = ContentPrivate::MkPromiseValue() }
/** Gets the `promisedError` edge label connecting a promise to its rejected value. */
LabelPromisedError promisedError() { any() }
LabelContent promisedError() { result.getContent() = ContentPrivate::MkPromiseError() }
/** Gets the label for an edge leading from a value `D` to any class that has `D` as a decorator. */
LabelDecoratedClass decoratedClass() { any() }
@@ -1542,18 +1612,12 @@ module API {
exists(Impl::MkModuleImport(mod))
} or
MkLabelInstance() or
MkLabelMember(string prop) {
exports(_, prop, _) or
exists(any(DataFlow::ClassNode c).getInstanceMethod(prop)) or
prop = "exports" or
prop = any(CanonicalName c).getName() or
prop = any(DataFlow::PropRef p).getPropertyName() or
exists(Impl::MkTypeUse(_, prop)) or
exists(any(Module m).getAnExportedValue(prop)) or
PreCallGraphStep::loadStep(_, _, prop) or
PreCallGraphStep::storeStep(_, _, prop)
MkLabelContent(DataFlow::Content content) or
MkLabelMember(string name) {
name instanceof PropertyName
or
exists(Impl::MkTypeUse(_, name))
} or
MkLabelUnknownMember() or
MkLabelParameter(int i) {
i =
[0 .. max(int args |
@@ -1564,8 +1628,6 @@ module API {
} or
MkLabelReceiver() or
MkLabelReturn() or
MkLabelPromised() or
MkLabelPromisedError() or
MkLabelDecoratedClass() or
MkLabelDecoratedMember() or
MkLabelDecoratedParameter() or
@@ -1585,13 +1647,13 @@ module API {
}
/** A label that gets a promised value. */
class LabelPromised extends ApiLabel, MkLabelPromised {
override string toString() { result = "getPromised()" }
deprecated class LabelPromised extends ApiLabel {
LabelPromised() { this = MkLabelContent(ContentPrivate::MkPromiseValue()) }
}
/** A label that gets a rejected promise. */
class LabelPromisedError extends ApiLabel, MkLabelPromisedError {
override string toString() { result = "getPromisedError()" }
deprecated class LabelPromisedError extends ApiLabel {
LabelPromisedError() { this = MkLabelContent(ContentPrivate::MkPromiseError()) }
}
/** A label that gets the return value of a function. */
@@ -1617,9 +1679,39 @@ module API {
override string toString() { result = "getInstance()" }
}
/** A label for a content. */
class LabelContent extends ApiLabel, MkLabelContent {
private DataFlow::Content content;
LabelContent() {
this = MkLabelContent(content) and
// Property names are represented by LabelMember to ensure additional property
// names from PreCallGraph step are included, as well as those from MkTypeUse.
not content instanceof ContentPrivate::MkPropertyContent
}
/** Gets the content associated with this label. */
DataFlow::Content getContent() { result = content }
private string specialisedToString() {
content instanceof ContentPrivate::MkPromiseValue and result = "getPromised()"
or
content instanceof ContentPrivate::MkPromiseError and result = "getPromisedError()"
or
content instanceof ContentPrivate::MkArrayElementUnknown and result = "getArrayElement()"
}
override string toString() {
result = this.specialisedToString()
or
not exists(this.specialisedToString()) and
result = "getContent(" + content + ")"
}
}
/** A label for the member named `prop`. */
class LabelMember extends ApiLabel, MkLabelMember {
string prop;
private string prop;
LabelMember() { this = MkLabelMember(prop) }
@@ -1630,10 +1722,8 @@ module API {
}
/** A label for a member with an unknown name. */
class LabelUnknownMember extends ApiLabel, MkLabelUnknownMember {
LabelUnknownMember() { this = MkLabelUnknownMember() }
override string toString() { result = "getUnknownMember()" }
deprecated class LabelUnknownMember extends LabelContent {
LabelUnknownMember() { this.getContent().isUnknownArrayElement() }
}
/** A label for parameter `i`. */

View File

@@ -296,7 +296,7 @@ module DOM {
.getType()
.getAnUnderlyingType()
.(JSDocNamedTypeExpr)
.getName())
.getRawName())
)
}

View File

@@ -400,8 +400,8 @@ class ConstructorTag extends JSDocTag {
abstract private class NamedTypeReferent extends JSDocTag {
/** Gets the name of the type to which this tag refers. */
string getTarget() {
result = this.getType().(JSDocNamedTypeExpr).getName() or
result = this.getType().(JSDocAppliedTypeExpr).getHead().(JSDocNamedTypeExpr).getName()
result = this.getType().(JSDocNamedTypeExpr).getRawName() or
result = this.getType().(JSDocAppliedTypeExpr).getHead().(JSDocNamedTypeExpr).getRawName()
}
/**
@@ -423,7 +423,7 @@ abstract private class NamedTypeReferent extends JSDocTag {
* Gets the source declaration of the type to which `tp` refers, if any.
*/
private ExternalType sourceDecl(JSDocTypeExpr tp) {
result.getQualifiedName() = tp.(JSDocNamedTypeExpr).getName() or
result.getQualifiedName() = tp.(JSDocNamedTypeExpr).getRawName() or
result = sourceDecl(tp.(JSDocAppliedTypeExpr).getHead()) or
result = sourceDecl(tp.(JSDocNullableTypeExpr).getTypeExpr()) or
result = sourceDecl(tp.(JSDocNonNullableTypeExpr).getTypeExpr()) or

View File

@@ -261,17 +261,14 @@ class JSDocVoidTypeExpr extends @jsdoc_void_type_expr, JSDocTypeExpr {
}
/**
* A type expression referring to a named type.
* An identifier in a JSDoc type expression, such as `Object` or `string`.
*
* Example:
*
* ```
* string
* Object
* ```
* Note that qualified names consist of multiple identifier nodes.
*/
class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
/** Gets the name of the type the expression refers to. */
class JSDocIdentifierTypeExpr extends @jsdoc_identifier_type_expr, JSDocTypeExpr {
/**
* Gets the name of the identifier.
*/
string getName() { result = this.toString() }
override predicate isString() { this.getName() = "string" }
@@ -300,6 +297,71 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
}
override predicate isRawFunction() { this.getName() = "Function" }
}
/**
* An unqualified identifier in a JSDoc type expression.
*
* Example:
*
* ```
* string
* Object
* ```
*/
class JSDocLocalTypeAccess extends JSDocIdentifierTypeExpr {
JSDocLocalTypeAccess() { not this = any(JSDocQualifiedTypeAccess a).getNameNode() }
}
/**
* A qualified type name in a JSDoc type expression, such as `X.Y`.
*/
class JSDocQualifiedTypeAccess extends @jsdoc_qualified_type_expr, JSDocTypeExpr {
/**
* Gets the base of this access, such as the `X` in `X.Y`.
*/
JSDocTypeExpr getBase() { result = this.getChild(0) }
/**
* Gets the node naming the member being accessed, such as the `Y` node in `X.Y`.
*/
JSDocIdentifierTypeExpr getNameNode() { result = this.getChild(1) }
/**
* Gets the name being accessed, such as `Y` in `X.Y`.
*/
string getName() { result = this.getNameNode().getName() }
}
/**
* A type expression referring to a named type.
*
* Example:
*
* ```
* string
* Object
* Namespace.Type
* ```
*/
class JSDocNamedTypeExpr extends JSDocTypeExpr {
JSDocNamedTypeExpr() {
this instanceof JSDocLocalTypeAccess
or
this instanceof JSDocQualifiedTypeAccess
}
/**
* Gets the name directly as it appears in this type, including any qualifiers.
*
* For example, for `X.Y` this gets the string `"X.Y"`.
*/
string getRawName() { result = this.toString() }
/**
* DEPRECATED. Use `getRawName()` instead.
*/
deprecated string getName() { result = this.toString() }
/**
* Holds if this name consists of the unqualified name `prefix`
@@ -310,8 +372,9 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
* - `Baz` has prefix `Baz` and an empty suffix.
*/
predicate hasNameParts(string prefix, string suffix) {
not this = any(JSDocQualifiedTypeAccess a).getBase() and // restrict size of predicate
exists(string regex, string name | regex = "([^.]+)(.*)" |
name = this.getName() and
name = this.getRawName() and
prefix = name.regexpCapture(regex, 1) and
suffix = name.regexpCapture(regex, 2)
)
@@ -340,7 +403,7 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
globalName = this.resolvedName()
or
not exists(this.resolvedName()) and
globalName = this.getName()
globalName = this.getRawName()
}
override DataFlow::ClassNode getClass() {

View File

@@ -140,22 +140,17 @@ module MembershipCandidate {
EnumerationRegExp() {
this.isRootTerm() and
RegExp::isFullyAnchoredTerm(this) and
exists(RegExpTerm child | this.getAChild*() = child |
child instanceof RegExpSequence or
child instanceof RegExpCaret or
child instanceof RegExpDollar or
child instanceof RegExpConstant or
child instanceof RegExpAlt or
child instanceof RegExpGroup
) and
// exclude "length matches" that match every string
not this.getAChild*() instanceof RegExpDot
not exists(RegExpTerm child | child.getRootTerm() = this |
child instanceof RegExpDot or
child instanceof RegExpCharacterClass or
child instanceof RegExpUnicodePropertyEscape
)
}
/**
* Gets a string matched by this regular expression.
*/
string getAMember() { result = this.getAChild*().getAMatchedString() }
string getAMember() { result = any(RegExpTerm t | t.getRootTerm() = this).getAMatchedString() }
}
/**

View File

@@ -4,6 +4,7 @@
import javascript
private import dataflow.internal.StepSummary
private import semmle.javascript.dataflow.internal.FlowSteps
/**
* A call to the `Promise` constructor, such as `new Promise((resolve, reject) => { ... })`.
@@ -397,6 +398,17 @@ module PromiseFlow {
value = call.getCallback(0).getExceptionalReturn() and
obj = call
)
or
exists(DataFlow::FunctionNode f | f.getFunction().isAsync() |
// ordinary return
prop = valueProp() and
value = f.getAReturn() and
obj = f.getReturnNode()
or
// exceptional return
prop = errorProp() and
localExceptionStepWithAsyncFlag(value, obj, true)
)
}
/**
@@ -525,30 +537,6 @@ private class PromiseTaintStep extends TaintTracking::LegacyTaintStep {
* Defines flow steps for return on async functions.
*/
private module AsyncReturnSteps {
private predicate valueProp = Promises::valueProp/0;
private predicate errorProp = Promises::errorProp/0;
private import semmle.javascript.dataflow.internal.FlowSteps
/**
* A data-flow step for ordinary and exceptional returns from async functions.
*/
private class AsyncReturn extends LegacyPreCallGraphStep {
override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
exists(DataFlow::FunctionNode f | f.getFunction().isAsync() |
// ordinary return
prop = valueProp() and
pred = f.getAReturn() and
succ = f.getReturnNode()
or
// exceptional return
prop = errorProp() and
localExceptionStepWithAsyncFlag(pred, succ, true)
)
}
}
/**
* A data-flow step for ordinary return from an async function in a taint configuration.
*/

View File

@@ -301,6 +301,51 @@ class RegExpAlt extends RegExpTerm, @regexp_alt {
override string getAPrimaryQlClass() { result = "RegExpAlt" }
}
/**
* An intersection term, that is, a term of the form `[[a]&&[ab]]`.
*
* Example:
*
* ```
* /[[abc]&&[bcd]]/v - which matches 'b' and 'c' only.
* ```
*/
class RegExpIntersection extends RegExpTerm, @regexp_intersection {
/** Gets an intersected term of this term. */
RegExpTerm getAnElement() { result = this.getAChild() }
/** Gets the number of intersected terms of this term. */
int getNumIntersectedTerm() { result = this.getNumChild() }
override predicate isNullable() { this.getAnElement().isNullable() }
override string getAPrimaryQlClass() { result = "RegExpIntersection" }
}
/**
* A subtraction term, that is, a term of the form `[[a]--[ab]]`.
*
* Example:
*
* ```
* /[[abc]--[bc]]/v - which matches 'a' only.
* ```
*/
class RegExpSubtraction extends RegExpTerm, @regexp_subtraction {
/** Gets the minuend (left operand) of this subtraction. */
RegExpTerm getFirstTerm() { result = this.getChild(0) }
/** Gets the number of subtractions terms of this term. */
int getNumSubtractedTerm() { result = this.getNumChild() - 1 }
/** Gets a subtrahend (right operand) of this subtraction. */
RegExpTerm getASubtractedTerm() { exists(int i | i > 0 and result = this.getChild(i)) }
override predicate isNullable() { none() }
override string getAPrimaryQlClass() { result = "RegExpSubtraction" }
}
/**
* A sequence term.
*
@@ -1142,6 +1187,28 @@ private class StringConcatRegExpPatternSource extends RegExpPatternSource {
override RegExpTerm getRegExpTerm() { result = this.asExpr().(AddExpr).asRegExp() }
}
/**
* A quoted string escape in a regular expression, using the `\q` syntax.
* The only operation supported inside a quoted string is alternation, using `|`.
*
* Example:
*
* ```
* \q{foo}
* \q{a|b|c}
* ```
*/
class RegExpQuotedString extends RegExpTerm, @regexp_quoted_string {
/** Gets the term representing the contents of this quoted string. */
RegExpTerm getTerm() { result = this.getAChild() }
override predicate isNullable() { none() }
override string getAMatchedString() { result = this.getTerm().getAMatchedString() }
override string getAPrimaryQlClass() { result = "RegExpQuotedString" }
}
module RegExp {
/** Gets the string `"?"` used to represent a regular expression whose flags are unknown. */
string unknownFlag() { result = "?" }

View File

@@ -188,27 +188,35 @@ module Routing {
)
}
/**
* Gets the path prefix needed to reach this node from the given ancestor, that is, the concatenation
* of all relative paths between this node and the ancestor.
*
* To restrict the size of the predicate, this is only available for the ancestors that are "fork" nodes,
* that is, a node that has siblings (i.e. multiple children).
*/
private string getPathFromFork(Node fork) {
private string getPathFromForkInternal(Node fork) {
this.isFork() and
this = fork and
result = ""
or
exists(Node parent | parent = this.getParent() |
not exists(parent.getRelativePath()) and
result = parent.getPathFromFork(fork)
result = parent.getPathFromForkInternal(fork)
or
result = parent.getPathFromFork(fork) + parent.getRelativePath() and
result = parent.getPathFromForkInternal(fork) + parent.getRelativePath() and
result.length() < 100
)
}
/**
* Gets the path prefix needed to reach this node from the given ancestor, that is, the concatenation
* of all relative paths between this node and the ancestor.
*
* To restrict the size of the predicate, this is only available for the ancestors that are "fork" nodes,
* that is, a node that has siblings (i.e. multiple children).
* And only a single (shortest) path is returned, even if there are multiple paths
* leading to this node.
*/
pragma[nomagic]
private string getPathFromFork(Node fork) {
result =
min(string res | res = this.getPathFromForkInternal(fork) | res order by res.length(), res)
}
/**
* Gets an HTTP method required to reach this node from the given ancestor, or `*` if any method
* can be used.

View File

@@ -773,6 +773,17 @@ class LocalTypeAccess extends @local_type_access, TypeAccess, Identifier, Lexica
*/
LocalTypeName getLocalTypeName() { result.getAnAccess() = this }
private TypeAliasDeclaration getAlias() {
this.getLocalTypeName().getADeclaration() = result.getIdentifier()
}
override TypeExpr getAnUnderlyingType() {
result = this.getAlias().getDefinition().getAnUnderlyingType()
or
not exists(this.getAlias()) and
result = this
}
override string getAPrimaryQlClass() { result = "LocalTypeAccess" }
}

View File

@@ -494,7 +494,8 @@ module TaintTracking {
succ = c and
c =
DataFlow::globalVarRef([
"encodeURI", "decodeURI", "encodeURIComponent", "decodeURIComponent"
"encodeURI", "decodeURI", "encodeURIComponent", "decodeURIComponent", "unescape",
"escape"
]).getACall() and
pred = c.getArgument(0)
)

View File

@@ -57,6 +57,16 @@ module Private {
this = getAPreciseArrayIndex().toString()
or
isAccessPathTokenPresent("Member", this)
or
this = any(ImportSpecifier spec).getImportedName()
or
this = any(ExportSpecifier n).getExportedName()
or
this = any(ExportNamedDeclaration d).getAnExportedDecl().getName()
or
this = any(MemberDefinition m).getName()
or
this = ["exports", "default"]
}
/** Gets the array index corresponding to this property name. */

View File

@@ -372,10 +372,11 @@ class CastNode extends DataFlow::Node {
cached
newtype TDataFlowCallable =
MkSourceCallable(StmtContainer container) or
MkLibraryCallable(LibraryCallable callable)
MkLibraryCallable(LibraryCallable callable) or
MkFileCallable(File file)
/**
* A callable entity. This is a wrapper around either a `StmtContainer` or a `LibraryCallable`.
* A callable entity. This is a wrapper around either a `StmtContainer`, `LibraryCallable`, or `File`.
*/
class DataFlowCallable extends TDataFlowCallable {
/** Gets a string representation of this callable. */
@@ -383,14 +384,21 @@ class DataFlowCallable extends TDataFlowCallable {
result = this.asSourceCallable().toString()
or
result = this.asLibraryCallable()
or
result = this.asFileCallable().toString()
}
/** Gets the location of this callable, if it is present in the source code. */
Location getLocation() { result = this.asSourceCallable().getLocation() }
Location getLocation() {
result = this.asSourceCallable().getLocation() or result = this.asFileCallable().getLocation()
}
/** Gets the corresponding `StmtContainer` if this is a source callable. */
StmtContainer asSourceCallable() { this = MkSourceCallable(result) }
/** Gets the corresponding `File` if this is a file representing a callable. */
File asFileCallable() { this = MkFileCallable(result) }
/** Gets the corresponding `StmtContainer` if this is a source callable. */
pragma[nomagic]
StmtContainer asSourceCallableNotExterns() {
@@ -537,6 +545,10 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) {
result.asLibraryCallable() = node.(FlowSummaryDefaultExceptionalReturn).getSummarizedCallable()
or
node = TGenericSynthesizedNode(_, _, result)
or
node instanceof DataFlow::HtmlAttributeNode and result.asFileCallable() = node.getFile()
or
node instanceof DataFlow::XmlAttributeNode and result.asFileCallable() = node.getFile()
}
newtype TDataFlowType =

View File

@@ -56,14 +56,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) }
}
predicate ssaDefAssigns(WriteDefinition def, Expr value) {
// This library only handles use-use flow after a post-update, there are no definitions, only uses.
none()
}
class Parameter = js::Parameter;
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) {
predicate ssaDefHasSource(WriteDefinition def) {
// This library only handles use-use flow after a post-update, there are no definitions, only uses.
none()
}
@@ -81,25 +74,29 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
class Guard extends js::ControlFlowNode {
Guard() { this = any(js::ConditionGuardNode g).getTest() }
predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) }
/**
* Holds if the control flow branching from `bb1` is dependent on this guard,
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
* guard to `branch`.
*/
predicate controlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) {
exists(js::ConditionGuardNode g |
g.getTest() = this and
bb1 = this.getBasicBlock() and
bb2 = g.getBasicBlock() and
branch = g.getOutcome()
)
}
}
pragma[inline]
predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
exists(js::ConditionGuardNode g |
g.getTest() = guard and
g.dominates(bb) and
branch = g.getOutcome()
)
}
js::BasicBlock getAConditionalBasicBlockSuccessor(js::BasicBlock bb, boolean branch) {
exists(js::ConditionGuardNode g |
bb = g.getTest().getBasicBlock() and
result = g.getBasicBlock() and
branch = g.getOutcome()
)
}
}
import DataFlowIntegration<SsaDataflowInput>

View File

@@ -190,13 +190,16 @@ module Angular2 {
result.hasUnderlyingType("@angular/common/http", "HttpClient")
}
/** Gets a reference to an `HttpClient` object using the API graph. */
API::Node httpClientApiNode() { result = API::Node::ofType("@angular/common/http", "HttpClient") }
private class AngularClientRequest extends ClientRequest::Range, DataFlow::MethodCallNode {
int argumentOffset;
AngularClientRequest() {
this = httpClient().getAMethodCall("request") and argumentOffset = 1
this = httpClientApiNode().getMember("request").getACall() and argumentOffset = 1
or
this = httpClient().getAMethodCall() and
this = httpClientApiNode().getAMember().getACall() and
not this.getMethodName() = "request" and
argumentOffset = 0
}

View File

@@ -222,7 +222,10 @@ module ClientRequest {
method = "request"
or
this = axios().getMember(method).getACall() and
method = [httpMethodName(), "request"]
method = [httpMethodName(), "request", "postForm", "putForm", "patchForm", "getUri"]
or
this = axios().getMember("create").getReturn().getACall() and
method = "request"
}
private int getOptionsArgIndex() {
@@ -254,6 +257,8 @@ module ClientRequest {
method = ["post", "put"] and
result = [this.getArgument(1), this.getOptionArgument(2, "data")]
or
method = ["postForm", "putForm", "patchForm"] and result = this.getArgument(1)
or
result = this.getOptionArgument([0 .. 2], ["headers", "params"])
}
@@ -414,20 +419,74 @@ module ClientRequest {
}
}
/**
* Represents an instance of the `got` HTTP client library.
*/
abstract private class GotInstance extends API::Node {
/**
* Gets the options object associated with this instance of `got`.
*/
API::Node getOptions() { none() }
}
/**
* Represents the root `got` module import.
* For example: `const got = require('got')`.
*/
private class RootGotInstance extends GotInstance {
RootGotInstance() { this = API::moduleImport("got") }
}
/**
* Represents an instance of `got` created by calling the `extend()` method.
* It may also be chained with multiple calls to `extend()`.
*
* For example: `const client = got.extend({ prefixUrl: 'https://example.com' })`.
*/
private class ExtendGotInstance extends GotInstance {
private GotInstance base;
private API::CallNode extendCall;
ExtendGotInstance() {
extendCall = base.getMember("extend").getACall() and
this = extendCall.getReturn()
}
override API::Node getOptions() {
result = extendCall.getParameter(0) or result = base.getOptions()
}
}
/**
* A model of a URL request made using the `got` library.
*/
class GotUrlRequest extends ClientRequest::Range {
GotInstance got;
GotUrlRequest() {
exists(API::Node callee, API::Node got | this = callee.getACall() |
got = [API::moduleImport("got"), API::moduleImport("got").getMember("extend").getReturn()] and
callee = [got, got.getMember(["stream", "get", "post", "put", "patch", "head", "delete"])]
exists(API::Node callee | this = callee.getACall() |
callee =
[
got,
got.getMember(["stream", "get", "post", "put", "patch", "head", "delete", "paginate"])
]
)
}
override DataFlow::Node getUrl() {
result = this.getArgument(0) and
not exists(this.getOptionArgument(1, "baseUrl"))
or
// Handle URL from options passed to extend()
result = got.getOptions().getMember("url").asSink() and
not exists(this.getArgument(0))
or
// Handle URL from options passed as third argument when first arg is undefined/missing
exists(API::InvokeNode optionsCall |
optionsCall = API::moduleImport("got").getMember("Options").getAnInvocation() and
optionsCall.getReturn().getAValueReachableFromSource() = this.getAnArgument() and
result = optionsCall.getParameter(0).getMember("url").asSink()
)
}
override DataFlow::Node getHost() {
@@ -513,6 +572,13 @@ module ClientRequest {
}
}
/**
* Gets the name of a superagent request method.
*/
private string getSuperagentRequestMethodName() {
result = [httpMethodName(), any(Http::RequestMethodName m), "del", "DEL"]
}
/**
* A model of a URL request made using the `superagent` library.
*/
@@ -520,10 +586,22 @@ module ClientRequest {
DataFlow::Node url;
SuperAgentUrlRequest() {
exists(string moduleName, DataFlow::SourceNode callee | this = callee.getACall() |
moduleName = "superagent" and
callee = DataFlow::moduleMember(moduleName, httpMethodName()) and
exists(string moduleName | moduleName = "superagent" |
// Handle method calls like superagent.get(url)
this = API::moduleImport(moduleName).getMember(getSuperagentRequestMethodName()).getACall() and
url = this.getArgument(0)
or
// Handle direct calls like superagent('GET', url)
this = API::moduleImport(moduleName).getACall() and
this.getArgument(0).mayHaveStringValue(getSuperagentRequestMethodName()) and
url = this.getArgument(1)
or
// Handle agent calls like superagent.agent().get(url)
exists(DataFlow::SourceNode agent |
agent = API::moduleImport(moduleName).getMember("agent").getACall() and
this = agent.getAMethodCall(httpMethodName()) and
url = this.getArgument(0)
)
)
}

View File

@@ -80,7 +80,7 @@ module D3 {
or
this = d3Selection().getMember("node").getReturn().asSource()
or
this = d3Selection().getMember("nodes").getReturn().getUnknownMember().asSource()
this = d3Selection().getMember("nodes").getReturn().getArrayElement().asSource()
}
}

View File

@@ -11,8 +11,8 @@ module Hapi {
*/
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::Node {
ServerDefinition() {
// `server = new Hapi.Server()`
this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation()
// `server = new Hapi.Server()`, `server = Hapi.server()`
this = DataFlow::moduleMember(["hapi", "@hapi/hapi"], ["Server", "server"]).getAnInvocation()
or
// `server = Glue.compose(manifest, composeOptions)`
this = DataFlow::moduleMember("@hapi/glue", "compose").getAnInvocation()

View File

@@ -46,19 +46,6 @@ module Markdown {
}
}
/**
* A taint step for the `markdown-table` library.
*/
private class MarkdownTableStep extends MarkdownStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::CallNode call | call = DataFlow::moduleImport("markdown-table").getACall() |
// TODO: needs a flow summary to ensure ArrayElement content is unfolded
succ = call and
pred = call.getArgument(0)
)
}
}
/**
* A taint step for the `showdown` library.
*/

View File

@@ -434,7 +434,7 @@ module NodeJSLib {
* method might represent a file path.
*/
private predicate fsExtraExtensionFileParam(string methodName, int i) {
methodName = ["copy", "copySync", "copyFile"] and i = [0, 1]
methodName = ["copy", "copySync", "copyFile", "cp", "copyFileSync", "cpSync"] and i = [0, 1]
or
methodName = ["move", "moveSync"] and i = [0, 1]
or
@@ -450,10 +450,13 @@ module NodeJSLib {
or
methodName = ["readJson", "readJSON", "readJsonSync", "readJSONSync"] and i = 0
or
methodName = ["remove", "removeSync"] and i = 0
methodName = ["remove", "removeSync", "rmSync", "rm", "rmdir", "rmdirSync"] and i = 0
or
methodName =
["outputJSON", "outputJson", "writeJSON", "writeJson", "writeJSONSync", "writeJsonSync"] and
[
"outputJSON", "outputJson", "writeJSON", "writeJson", "writeJSONSync", "writeJsonSync",
"outputJSONSync", "outputJsonSync"
] and
i = 0
or
methodName = ["ensureFile", "ensureFileSync"] and i = 0
@@ -462,9 +465,15 @@ module NodeJSLib {
or
methodName = ["ensureSymlink", "ensureSymlinkSync"] and i = [0, 1]
or
methodName = ["emptyDir", "emptyDirSync"] and i = 0
methodName = ["emptyDir", "emptyDirSync", "emptydir", "emptydirSync"] and i = 0
or
methodName = ["pathExists", "pathExistsSync"] and i = 0
or
methodName = ["lutimes", "lutimesSync"] and i = 0
or
methodName =
["opendir", "opendirSync", "openAsBlob", "statfs", "statfsSync", "open", "openSync"] and
i = 0
}
/**
@@ -592,6 +601,13 @@ module NodeJSLib {
}
}
/** A vectored write to the file system using `writev` or `writevSync` methods. */
private class NodeJSFileSystemVectorWrite extends FileSystemWriteAccess, NodeJSFileSystemAccess {
NodeJSFileSystemVectorWrite() { methodName = ["writev", "writevSync"] }
override DataFlow::Node getADataNode() { result = this.getArgument(1) }
}
/** A file system read. */
private class NodeJSFileSystemAccessRead extends FileSystemReadAccess, NodeJSFileSystemAccess {
NodeJSFileSystemAccessRead() { methodName = ["read", "readSync", "readFile", "readFileSync"] }
@@ -599,7 +615,7 @@ module NodeJSLib {
override DataFlow::Node getADataNode() {
if methodName.matches("%Sync")
then result = this
else
else (
exists(int i, string paramName | fsDataParam(methodName, i, paramName) |
if paramName = "callback"
then
@@ -610,6 +626,28 @@ module NodeJSLib {
)
else result = this.getArgument(i)
)
or
exists(AwaitExpr await |
this.getEnclosingExpr() = await.getOperand() and
result = DataFlow::valueNode(await)
)
)
}
}
/** A vectored read to the file system. */
private class NodeJSFileSystemAccessVectorRead extends FileSystemReadAccess,
NodeJSFileSystemAccess
{
NodeJSFileSystemAccessVectorRead() { methodName = ["readv", "readvSync"] }
override DataFlow::Node getADataNode() {
result = this.getArgument(1)
or
exists(DataFlow::ArrayCreationNode array |
array.flowsTo(this.getArgument(1)) and
result = array.getAnElement()
)
}
}

View File

@@ -32,7 +32,7 @@ module Puppeteer {
or
result = [browser(), context()].getMember("newPage").getReturn().getPromised()
or
result = [browser(), context()].getMember("pages").getReturn().getPromised().getUnknownMember()
result = [browser(), context()].getMember("pages").getReturn().getPromised().getArrayElement()
or
result = target().getMember("page").getReturn().getPromised()
}
@@ -45,7 +45,7 @@ module Puppeteer {
or
result = [page(), browser()].getMember("target").getReturn()
or
result = context().getMember("targets").getReturn().getUnknownMember()
result = context().getMember("targets").getReturn().getArrayElement()
or
result = target().getMember("opener").getReturn()
}
@@ -58,7 +58,7 @@ module Puppeteer {
or
result = [page(), target()].getMember("browserContext").getReturn()
or
result = browser().getMember("browserContexts").getReturn().getUnknownMember()
result = browser().getMember("browserContexts").getReturn().getArrayElement()
or
result = browser().getMember("createIncognitoBrowserContext").getReturn().getPromised()
or

View File

@@ -221,7 +221,10 @@ private module Postgres {
/** Gets a value that is plugged into a raw placeholder variable, making it a sink for SQL injection. */
private DataFlow::Node getARawValue() {
result = this.getValues() and this.getARawParameterName() = "1" // Special case: if the argument is not an array or object, it's just plugged into $1
result = this.getValues() and
this.getARawParameterName() = "1" and // Special case: if the argument is not an array or object, it's just plugged into $1
not result instanceof DataFlow::ArrayCreationNode and
not result instanceof DataFlow::ObjectLiteralNode
or
exists(DataFlow::SourceNode values | values = this.getValues().getALocalSource() |
result = values.getAPropertyWrite(this.getARawParameterName()).getRhs()

View File

@@ -1,26 +0,0 @@
/**
* Provides classes and predicates modeling the Tanstack/react-query library.
*/
private import javascript
/**
* An additional flow step that propagates data from the return value of the query function,
* defined in a useQuery call from the '@tanstack/react-query' module, to the 'data' property.
*/
private class TanstackStep extends DataFlow::AdditionalFlowStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(API::CallNode useQuery |
useQuery = useQueryCall() and
node1 = useQuery.getParameter(0).getMember("queryFn").getReturn().getPromised().asSink() and
node2 = useQuery.getReturn().getMember("data").asSource()
)
}
}
/**
* Retrieves a call node representing a useQuery invocation from the '@tanstack/react-query' module.
*/
private API::CallNode useQueryCall() {
result = API::moduleImport("@tanstack/react-query").getMember("useQuery").getACall()
}

View File

@@ -0,0 +1,26 @@
/**
* Provides classes for modeling data flow behavior of the Underscore.string library (https://www.npmjs.com/package/underscore.string).
*/
private import javascript
private import semmle.javascript.dataflow.internal.AdditionalFlowInternal
/**
* Models data flow for the Underscore.string library.
*/
private class UnderscoreDotString extends AdditionalFlowInternal {
/**
* Some of the methods in `underscore.string` have the same name as methods from `Array.prototype`.
* This prevents methods like `splice` from propagating into Argument[this].ArrayElement.
*/
override predicate clearsContent(DataFlow::Node node, DataFlow::ContentSet contents) {
exists(DataFlow::CallNode call |
call =
ModelOutput::getATypeNode(["'underscore.string'.Wrapper", "'underscore.string'"])
.getAMember()
.getACall() and
node = call.getReceiver().getPostUpdateNode() and
contents = DataFlow::ContentSet::arrayElement()
)
}
}

View File

@@ -421,3 +421,22 @@ private module ClosureLibraryUri {
}
}
}
private class QueryStringStringification extends DataFlow::SummarizedCallable {
QueryStringStringification() { this = "query-string stringification" }
override DataFlow::InvokeNode getACall() {
result =
API::moduleImport(["querystring", "query-string", "querystringify", "qs"])
.getMember("stringify")
.getACall() or
result = API::moduleImport("url-parse").getMember("qs").getMember("stringify").getACall() or
result = API::moduleImport("parseqs").getMember("encode").getACall()
}
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
preservesValue = false and
input = ["Argument[0]", "Argument[0].AnyMemberDeep"] and
output = "ReturnValue"
}
}

View File

@@ -104,8 +104,7 @@ module Vuex {
storeName = this.getNamespace() + localName
or
// mapGetters(['foo', 'bar'])
this.getLastParameter().getUnknownMember().getAValueReachingSink().getStringValue() =
localName and
this.getLastParameter().getArrayElement().getAValueReachingSink().getStringValue() = localName and
storeName = this.getNamespace() + localName
or
// mapGetters({foo: 'bar'})

View File

@@ -162,8 +162,8 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathTokenBase token) {
token.getName() = "Awaited" and
result = node.getPromised()
or
token.getName() = "ArrayElement" and
result = node.getMember(DataFlow::PseudoProperties::arrayElement())
token.getName() = ["ArrayElement", "Element"] and
result = node.getArrayElement()
or
token.getName() = "Element" and
result = node.getMember(DataFlow::PseudoProperties::arrayLikeElement())
@@ -172,11 +172,6 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathTokenBase token) {
token.getName() = "MapValue" and
result = node.getMember(DataFlow::PseudoProperties::mapValueAll())
or
// Currently we need to include the "unknown member" for ArrayElement and Element since
// API graphs do not use store/load steps for arrays
token.getName() = ["ArrayElement", "Element"] and
result = node.getUnknownMember()
or
token.getName() = "Parameter" and
token.getAnArgument() = "this" and
result = node.getReceiver()
@@ -189,6 +184,20 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathTokenBase token) {
or
token.getName() = "DecoratedParameter" and
result = node.getADecoratedParameter()
or
token.getName() = "GuardedRouteHandler" and
result = getAGuardedRouteHandlerApprox(node)
}
bindingset[node]
pragma[inline_late]
private API::Node getAGuardedRouteHandlerApprox(API::Node node) {
// For now just get any routing node with the same root (i.e. the same web app), as
// there are some known performance issues when checking if it is actually guarded by the given node.
exists(JS::Routing::Node root |
root = JS::Routing::getNode(node.getAValueReachableFromSource()).getRootNode() and
root = JS::Routing::getNode(result.asSink()).getRootNode()
)
}
/**
@@ -322,7 +331,7 @@ predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
[
"Member", "AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue",
"NewCall", "Call", "DecoratedClass", "DecoratedMember", "DecoratedParameter",
"WithStringArgument"
"WithStringArgument", "GuardedRouteHandler"
]
}
@@ -334,7 +343,7 @@ predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
name =
[
"AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
"DecoratedClass", "DecoratedMember", "DecoratedParameter"
"DecoratedClass", "DecoratedMember", "DecoratedParameter", "GuardedRouteHandler"
]
}
@@ -373,7 +382,7 @@ bindingset[pred]
predicate apiGraphHasEdge(API::Node pred, string path, API::Node succ) {
exists(string name | succ = pred.getMember(name) and path = "Member[" + name + "]")
or
succ = pred.getUnknownMember() and path = "AnyMember"
succ = pred.getUnknownArrayElement() and path = "ArrayElement"
or
succ = pred.getInstance() and path = "Instance"
or

View File

@@ -297,13 +297,12 @@ module Stages {
exists(
API::moduleImport("foo")
.getMember("bar")
.getUnknownMember()
.getArrayElement()
.getAMember()
.getAParameter()
.getPromised()
.getReturn()
.getParameter(2)
.getUnknownMember()
.getInstance()
.getReceiver()
.getForwardingFunction()

View File

@@ -96,7 +96,8 @@ class ArrayConstructorSummary extends SummarizedCallable {
ArrayConstructorSummary() { this = "Array constructor" }
override DataFlow::InvokeNode getACallSimple() {
result = arrayConstructorRef().getAnInvocation()
result = arrayConstructorRef().getAnInvocation() and
result.getNumArgument() > 1
}
override predicate propagatesFlow(string input, string output, boolean preservesValue) {

View File

@@ -179,7 +179,6 @@ module ExternalApiUsedWithUntrustedData {
or
exists(string member |
node = base.getMember(member) and
not node = base.getUnknownMember() and
not isNumericString(member) and
not (member = "default" and base = API::moduleImport(_)) and
not member = "then" // use the 'promised' edges for .then callbacks
@@ -189,10 +188,7 @@ module ExternalApiUsedWithUntrustedData {
else result = basename + "['" + member.regexpReplaceAll("'", "\\'") + "']"
)
or
(
node = base.getUnknownMember() or
node = base.getMember(any(string s | isNumericString(s)))
) and
node = base.getArrayElement() and
result = basename + "[]"
or
// just collapse promises

View File

@@ -20,7 +20,11 @@ module ServerSideUrlRedirectConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
predicate isBarrier(DataFlow::Node node) {
node instanceof Sanitizer
or
node = HostnameSanitizerGuard::getABarrierNode()
}
predicate isBarrierOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) }
@@ -69,10 +73,12 @@ deprecated class Configuration extends TaintTracking::Configuration {
}
/**
* DEPRECATED. This is no longer used as a sanitizer guard.
*
* A call to a function called `isLocalUrl` or similar, which is
* considered to sanitize a variable for purposes of URL redirection.
*/
class LocalUrlSanitizingGuard extends DataFlow::CallNode {
deprecated class LocalUrlSanitizingGuard extends DataFlow::CallNode {
LocalUrlSanitizingGuard() { this.getCalleeName().regexpMatch("(?i)(is_?)?local_?url") }
/** DEPRECATED. Use `blocksExpr` instead. */

View File

@@ -892,7 +892,13 @@ module TaintedPath {
TaintTracking::uriStep(node1, node2)
or
exists(DataFlow::CallNode decode |
decode.getCalleeName() = "decodeURIComponent" or decode.getCalleeName() = "decodeURI"
decode =
DataFlow::globalVarRef([
"decodeURIComponent",
"decodeURI",
"escape",
"unescape"
]).getACall()
|
node1 = decode.getArgument(0) and
node2 = decode

View File

@@ -53,7 +53,7 @@ module Shared {
class UriEncodingSanitizer extends Sanitizer, DataFlow::CallNode {
UriEncodingSanitizer() {
exists(string name | this = DataFlow::globalVarRef(name).getACall() |
name = "encodeURI" or name = "encodeURIComponent"
name in ["encodeURI", "encodeURIComponent", "escape"]
)
}
}

View File

@@ -859,7 +859,10 @@ case @regexpterm.kind of
| 24 = @regexp_char_range
| 25 = @regexp_positive_lookbehind
| 26 = @regexp_negative_lookbehind
| 27 = @regexp_unicode_property_escape;
| 27 = @regexp_unicode_property_escape
| 28 = @regexp_quoted_string
| 29 = @regexp_intersection
| 30 = @regexp_subtraction;
regexp_parse_errors (unique int id: @regexp_parse_error,
int regexp: @regexpterm ref,
@@ -998,7 +1001,7 @@ case @jsdoc_type_expr.kind of
| 2 = @jsdoc_undefined_type_expr
| 3 = @jsdoc_unknown_type_expr
| 4 = @jsdoc_void_type_expr
| 5 = @jsdoc_named_type_expr
| 5 = @jsdoc_identifier_type_expr
| 6 = @jsdoc_applied_type_expr
| 7 = @jsdoc_nullable_type_expr
| 8 = @jsdoc_non_nullable_type_expr
@@ -1008,6 +1011,7 @@ case @jsdoc_type_expr.kind of
| 12 = @jsdoc_function_type_expr
| 13 = @jsdoc_optional_type_expr
| 14 = @jsdoc_rest_type_expr
| 15 = @jsdoc_qualified_type_expr
;
#keyset[id, idx]

View File

@@ -1194,6 +1194,18 @@
<v>12</v>
</e>
<e>
<k>@regexp_quoted_string</k>
<v>12</v>
</e>
<e>
<k>@regexp_intersection</k>
<v>12</v>
</e>
<e>
<k>@regexp_subtraction</k>
<v>12</v>
</e>
<e>
<k>@regexp_parse_error</k>
<v>122</v>
</e>
@@ -1322,10 +1334,14 @@
<v>8</v>
</e>
<e>
<k>@jsdoc_named_type_expr</k>
<k>@jsdoc_identifier_type_expr</k>
<v>18639</v>
</e>
<e>
<k>@jsdoc_qualified_type_expr</k>
<v>1000</v>
</e>
<e>
<k>@jsdoc_applied_type_expr</k>
<v>303</v>
</e>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: split up qualified names in jsdoc type exprs
compatibility: partial

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More