From 12305aae4249a107ecff4de82cd97db2786f1198 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Fri, 24 Sep 2021 18:41:03 +0200 Subject: [PATCH 01/10] extract regexp literals from string concatenations --- .../com/semmle/js/extractor/ASTExtractor.java | 76 +- .../src/com/semmle/js/extractor/Main.java | 2 +- .../semmle/js/extractor/RegExpExtractor.java | 25 +- .../tests/jsx/output/trap/tst.js.trap | 260 ++-- .../extractor/tests/regexp/input/multipart.js | 14 + .../regexp/output/trap/multipart.js.trap | 727 ++++++++++ javascript/ql/lib/semmle/javascript/Expr.qll | 8 + .../ql/lib/semmle/javascript/Regexp.qll | 26 +- .../ql/lib/semmlecode.javascript.dbscheme | 2 +- .../ReDoS/PolynomialBackTracking.expected | 5 + .../Performance/ReDoS/ReDoS.expected | 5 + .../test/query-tests/Performance/ReDoS/tst.js | 19 +- .../CWE-020/IncompleteHostnameRegExp.expected | 4 + .../old.dbscheme | 1217 +++++++++++++++++ .../semmlecode.javascript.dbscheme | 1217 +++++++++++++++++ .../upgrade.properties | 2 + 16 files changed, 3460 insertions(+), 149 deletions(-) create mode 100644 javascript/extractor/tests/regexp/input/multipart.js create mode 100644 javascript/extractor/tests/regexp/output/trap/multipart.js.trap create mode 100644 javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/old.dbscheme create mode 100644 javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/semmlecode.javascript.dbscheme create mode 100644 javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/upgrade.properties diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 158a33030a4..ff660303702 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -3,6 +3,8 @@ package com.semmle.js.extractor; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; +import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.Stack; @@ -164,6 +166,9 @@ import com.semmle.util.locations.SourceMap; import com.semmle.util.trap.TrapWriter; import com.semmle.util.trap.TrapWriter.Label; +import com.semmle.util.files.FileLineOffsetCache; + + /** Extractor for AST-based information; invoked by the {@link JSExtractor}. */ public class ASTExtractor { private final TrapWriter trapwriter; @@ -567,12 +572,17 @@ public class ASTExtractor { String valueString = nd.getStringValue(); trapwriter.addTuple("literals", valueString, source, key); + Position start = nd.getLoc().getStart(); + com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn(), start.getOffset()); + if (nd.isRegExp()) { OffsetTranslation offsets = new OffsetTranslation(); offsets.set(0, 1); // skip the initial '/' - regexpExtractor.extract(source.substring(1, source.lastIndexOf('/')), offsets, nd, false); + SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getRaw()).offsetBy(0, offsets), startPos); + regexpExtractor.extract(source.substring(1, source.lastIndexOf('/')), sourceMap, nd, false); } else if (nd.isStringLiteral() && !c.isInsideType() && nd.getRaw().length() < 1000) { - regexpExtractor.extract(valueString, makeStringLiteralOffsets(nd.getRaw()), nd, true); + SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getRaw()).offsetBy(0, makeStringLiteralOffsets(nd.getRaw())), startPos); + regexpExtractor.extract(valueString, sourceMap, nd, true); // Scan the string for template tags, if we're in a context where such tags are relevant. if (scopeManager.isInTemplateFile()) { @@ -593,6 +603,48 @@ public class ASTExtractor { return '0' <= ch && ch <= '7'; } + private String getStringConcatResult(Expression exp) { + if (exp instanceof BinaryExpression) { + BinaryExpression be = (BinaryExpression) exp; + if (be.getOperator().equals("+")) { + String left = getStringConcatResult(be.getLeft()); + String right = getStringConcatResult(be.getRight()); + if (left != null && right != null) { + return left + right; + } + } + } else if (exp instanceof Literal) { + Literal lit = (Literal) exp; + if (!lit.isStringLiteral()) { + return null; + } + return lit.getStringValue(); + } + return null; + } + + private OffsetTranslation computeStringConcatOffset(Expression exp) { + if (exp instanceof Literal && ((Literal)exp).isStringLiteral()) { + String raw = ((Literal) exp).getRaw(); + return makeStringLiteralOffsets(raw); + } + + if (exp instanceof BinaryExpression) { + BinaryExpression be = (BinaryExpression) exp; + OffsetTranslation left = computeStringConcatOffset(be.getLeft()); + OffsetTranslation right = computeStringConcatOffset(be.getRight()); + + if (left == null || right == null) { + return null; + } + int delta = be.getRight().getLoc().getStart().getOffset() - be.getLeft().getLoc().getStart().getOffset(); + int offset = getStringConcatResult(be.getLeft()).length(); + return left.append(right, offset, delta); + } + + return null; + } + /** * Builds a translation from offsets in a string value back to its original raw literal text * (including quotes). @@ -786,11 +838,31 @@ public class ASTExtractor { return key; } + // set to determine which BinaryExpression has been extracted as regexp + private Set extractedAsRegexp = new HashSet<>(); + @Override public Label visit(BinaryExpression nd, Context c) { Label key = super.visit(nd, c); + extractedAsRegexp.add(nd.getLeft()); + extractedAsRegexp.add(nd.getRight()); visit(nd.getLeft(), key, 0); visit(nd.getRight(), key, 1); + if (extractedAsRegexp.contains(nd)) { + return key; + } + String rawString = getStringConcatResult(nd); + if (rawString == null) { + return key; + } + if (rawString.length() > 1000 && !rawString.trim().isEmpty()) { + return key; + } + OffsetTranslation offsets = computeStringConcatOffset(nd); + Position start = nd.getLoc().getStart(); + com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn(), start.getOffset()); + SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getLoc().getSource()).offsetBy(0, offsets), startPos); + regexpExtractor.extract(rawString, sourceMap, nd, true); return key; } diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index 7132ba9cc2b..28b01815aaa 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -43,7 +43,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2021-10-25"; + public static final String EXTRACTOR_VERSION = "2021-10-28"; public static final Pattern NEWLINE = Pattern.compile("\n"); diff --git a/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java index 72f0e48bec0..f94166b45ad 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java @@ -43,7 +43,7 @@ import com.semmle.js.ast.regexp.ZeroWidthPositiveLookahead; import com.semmle.js.ast.regexp.ZeroWidthPositiveLookbehind; import com.semmle.js.parser.RegExpParser; import com.semmle.js.parser.RegExpParser.Result; -import com.semmle.util.locations.OffsetTranslation; +import com.semmle.util.locations.SourceMap; import com.semmle.util.trap.TrapWriter; import com.semmle.util.trap.TrapWriter.Label; @@ -52,8 +52,7 @@ public class RegExpExtractor { private final TrapWriter trapwriter; private final LocationManager locationManager; private final RegExpParser parser = new RegExpParser(); - private Position literalStart; - private OffsetTranslation offsets; + private SourceMap sourceMap; public RegExpExtractor(TrapWriter trapwriter, LocationManager locationManager) { this.trapwriter = trapwriter; @@ -122,17 +121,14 @@ public class RegExpExtractor { } public void emitLocation(SourceElement term, Label lbl) { - int col = literalStart.getColumn(); - int sl, sc, el, ec; - sl = el = literalStart.getLine(); - sc = col + offsets.get(term.getLoc().getStart().getColumn()); - ec = col + offsets.get(term.getLoc().getEnd().getColumn()); - sc += 1; // convert to 1-based - ec += 1; // convert to 1-based - ec -= 1; // convert to inclusive + int sl = sourceMap.getStart(term.getLoc().getStart().getColumn()).getLine(); + int sc = sourceMap.getStart(term.getLoc().getStart().getColumn()).getColumn() + 1; // convert to 1-based + int el = sourceMap.getEnd(term.getLoc().getEnd().getColumn()).getLine(); + int ec = sourceMap.getEnd(term.getLoc().getEnd().getColumn()).getColumn() - 1; // convert to inclusive locationManager.emitSnippetLocation(lbl, sl, sc, el, ec); } + private class V implements Visitor { private Label parent; private int idx; @@ -348,16 +344,13 @@ public class RegExpExtractor { } } - public void extract( - String src, OffsetTranslation offsets, Node parent, boolean isSpeculativeParsing) { + public void extract(String src, SourceMap sourceMap, Node parent, boolean isSpeculativeParsing) { Result res = parser.parse(src); - if (isSpeculativeParsing && res.getErrors().size() > 0) { return; } - this.literalStart = parent.getLoc().getStart(); - this.offsets = offsets; + this.sourceMap = sourceMap; RegExpTerm ast = res.getAST(); new V().visit(ast, trapwriter.localID(parent), 0); diff --git a/javascript/extractor/tests/jsx/output/trap/tst.js.trap b/javascript/extractor/tests/jsx/output/trap/tst.js.trap index 874901be084..9ae7c3b06a1 100644 --- a/javascript/extractor/tests/jsx/output/trap/tst.js.trap +++ b/javascript/extractor/tests/jsx/output/trap/tst.js.trap @@ -589,170 +589,176 @@ locations_default(#20204,#10000,3,26,3,26) hasLocation(#20203,#20204) regexp_const_value(#20203,"b") #20205=* -exprs(#20205,79,#20182,-2,"j") -hasLocation(#20205,#20075) -enclosing_stmt(#20205,#20181) -expr_containers(#20205,#20001) -literals("j","j",#20205) -#20206=@"var;{j};{#20000}" -variables(#20206,"j",#20000) -bind(#20205,#20206) +regexpterm(#20205,14,#20197,0,"ab") +#20206=@"loc,{#10000},3,22,3,26" +locations_default(#20206,#10000,3,22,3,26) +hasLocation(#20205,#20206) +regexp_const_value(#20205,"ab") #20207=* -exprs(#20207,89,#20182,-3,"") -#20208=@"loc,{#10000},3,33,3,47" -locations_default(#20208,#10000,3,33,3,47) -hasLocation(#20207,#20208) +exprs(#20207,79,#20182,-2,"j") +hasLocation(#20207,#20075) enclosing_stmt(#20207,#20181) expr_containers(#20207,#20001) +literals("j","j",#20207) +#20208=@"var;{j};{#20000}" +variables(#20208,"j",#20000) +bind(#20207,#20208) #20209=* -exprs(#20209,14,#20207,-1,"k.l") -#20210=@"loc,{#10000},3,34,3,36" -locations_default(#20210,#10000,3,34,3,36) +exprs(#20209,89,#20182,-3,"") +#20210=@"loc,{#10000},3,33,3,47" +locations_default(#20210,#10000,3,33,3,47) hasLocation(#20209,#20210) enclosing_stmt(#20209,#20181) expr_containers(#20209,#20001) #20211=* -exprs(#20211,79,#20209,0,"k") -hasLocation(#20211,#20081) +exprs(#20211,14,#20209,-1,"k.l") +#20212=@"loc,{#10000},3,34,3,36" +locations_default(#20212,#10000,3,34,3,36) +hasLocation(#20211,#20212) enclosing_stmt(#20211,#20181) expr_containers(#20211,#20001) -literals("k","k",#20211) -#20212=@"var;{k};{#20000}" -variables(#20212,"k",#20000) -bind(#20211,#20212) #20213=* -exprs(#20213,0,#20209,1,"l") -hasLocation(#20213,#20085) +exprs(#20213,79,#20211,0,"k") +hasLocation(#20213,#20081) enclosing_stmt(#20213,#20181) expr_containers(#20213,#20001) -literals("l","l",#20213) -#20214=* -exprs(#20214,89,#20207,-2,"") -#20215=@"loc,{#10000},3,38,3,41" -locations_default(#20215,#10000,3,38,3,41) -hasLocation(#20214,#20215) -enclosing_stmt(#20214,#20181) -expr_containers(#20214,#20001) +literals("k","k",#20213) +#20214=@"var;{k};{#20000}" +variables(#20214,"k",#20000) +bind(#20213,#20214) +#20215=* +exprs(#20215,0,#20211,1,"l") +hasLocation(#20215,#20085) +enclosing_stmt(#20215,#20181) +expr_containers(#20215,#20001) +literals("l","l",#20215) #20216=* -exprs(#20216,79,#20214,-1,"M") -hasLocation(#20216,#20091) +exprs(#20216,89,#20209,-2,"") +#20217=@"loc,{#10000},3,38,3,41" +locations_default(#20217,#10000,3,38,3,41) +hasLocation(#20216,#20217) enclosing_stmt(#20216,#20181) expr_containers(#20216,#20001) -literals("M","M",#20216) -#20217=@"var;{M};{#20000}" -variables(#20217,"M",#20000) -bind(#20216,#20217) #20218=* -stmts(#20218,2,#20001,3,";") -hasLocation(#20218,#20009) -stmt_containers(#20218,#20001) -#20219=* -exprs(#20219,89,#20218,0,"") -#20220=@"loc,{#10000},4,1,4,15" -locations_default(#20220,#10000,4,1,4,15) -hasLocation(#20219,#20220) -enclosing_stmt(#20219,#20218) -expr_containers(#20219,#20001) +exprs(#20218,79,#20216,-1,"M") +hasLocation(#20218,#20091) +enclosing_stmt(#20218,#20181) +expr_containers(#20218,#20001) +literals("M","M",#20218) +#20219=@"var;{M};{#20000}" +variables(#20219,"M",#20000) +bind(#20218,#20219) +#20220=* +stmts(#20220,2,#20001,3,";") +hasLocation(#20220,#20009) +stmt_containers(#20220,#20001) #20221=* -exprs(#20221,0,#20219,-1,"n") -hasLocation(#20221,#20121) -enclosing_stmt(#20221,#20218) +exprs(#20221,89,#20220,0,"") +#20222=@"loc,{#10000},4,1,4,15" +locations_default(#20222,#10000,4,1,4,15) +hasLocation(#20221,#20222) +enclosing_stmt(#20221,#20220) expr_containers(#20221,#20001) -literals("n","n",#20221) -#20222=* -properties(#20222,#20219,0,3,"{...props}") -#20223=@"loc,{#10000},4,4,4,13" -locations_default(#20223,#10000,4,4,4,13) -hasLocation(#20222,#20223) +#20223=* +exprs(#20223,0,#20221,-1,"n") +hasLocation(#20223,#20121) +enclosing_stmt(#20223,#20220) +expr_containers(#20223,#20001) +literals("n","n",#20223) #20224=* -exprs(#20224,66,#20222,1,"...props") -hasLocation(#20224,#20223) -enclosing_stmt(#20224,#20218) -expr_containers(#20224,#20001) -#20225=* -exprs(#20225,79,#20224,0,"props") -hasLocation(#20225,#20127) -enclosing_stmt(#20225,#20218) -expr_containers(#20225,#20001) -literals("props","props",#20225) -#20226=@"var;{props};{#20000}" -variables(#20226,"props",#20000) -bind(#20225,#20226) +properties(#20224,#20221,0,3,"{...props}") +#20225=@"loc,{#10000},4,4,4,13" +locations_default(#20225,#10000,4,4,4,13) +hasLocation(#20224,#20225) +#20226=* +exprs(#20226,66,#20224,1,"...props") +hasLocation(#20226,#20225) +enclosing_stmt(#20226,#20220) +expr_containers(#20226,#20001) #20227=* -stmts(#20227,2,#20001,4,"<>") -hasLocation(#20227,#20011) -stmt_containers(#20227,#20001) -#20228=* -exprs(#20228,89,#20227,0,"<>") -hasLocation(#20228,#20011) -enclosing_stmt(#20228,#20227) -expr_containers(#20228,#20001) +exprs(#20227,79,#20226,0,"props") +hasLocation(#20227,#20127) +enclosing_stmt(#20227,#20220) +expr_containers(#20227,#20001) +literals("props","props",#20227) +#20228=@"var;{props};{#20000}" +variables(#20228,"props",#20000) +bind(#20227,#20228) #20229=* -exprs(#20229,89,#20228,-2,"") -#20230=@"loc,{#10000},5,3,5,6" -locations_default(#20230,#10000,5,3,5,6) -hasLocation(#20229,#20230) -enclosing_stmt(#20229,#20227) -expr_containers(#20229,#20001) +stmts(#20229,2,#20001,4,"<>") +hasLocation(#20229,#20011) +stmt_containers(#20229,#20001) +#20230=* +exprs(#20230,89,#20229,0,"<>") +hasLocation(#20230,#20011) +enclosing_stmt(#20230,#20229) +expr_containers(#20230,#20001) #20231=* -exprs(#20231,0,#20229,-1,"a") -hasLocation(#20231,#20143) -enclosing_stmt(#20231,#20227) +exprs(#20231,89,#20230,-2,"") +#20232=@"loc,{#10000},5,3,5,6" +locations_default(#20232,#10000,5,3,5,6) +hasLocation(#20231,#20232) +enclosing_stmt(#20231,#20229) expr_containers(#20231,#20001) -literals("a","a",#20231) -#20232=* -exprs(#20232,89,#20228,-3,"") -#20233=@"loc,{#10000},5,7,5,10" -locations_default(#20233,#10000,5,7,5,10) -hasLocation(#20232,#20233) -enclosing_stmt(#20232,#20227) -expr_containers(#20232,#20001) +#20233=* +exprs(#20233,0,#20231,-1,"a") +hasLocation(#20233,#20143) +enclosing_stmt(#20233,#20229) +expr_containers(#20233,#20001) +literals("a","a",#20233) #20234=* -exprs(#20234,0,#20232,-1,"b") -hasLocation(#20234,#20151) -enclosing_stmt(#20234,#20227) +exprs(#20234,89,#20230,-3,"") +#20235=@"loc,{#10000},5,7,5,10" +locations_default(#20235,#10000,5,7,5,10) +hasLocation(#20234,#20235) +enclosing_stmt(#20234,#20229) expr_containers(#20234,#20001) -literals("b","b",#20234) -#20235=* -entry_cfg_node(#20235,#20001) -#20236=@"loc,{#10000},1,1,1,0" -locations_default(#20236,#10000,1,1,1,0) -hasLocation(#20235,#20236) +#20236=* +exprs(#20236,0,#20234,-1,"b") +hasLocation(#20236,#20151) +enclosing_stmt(#20236,#20229) +expr_containers(#20236,#20001) +literals("b","b",#20236) #20237=* -exit_cfg_node(#20237,#20001) -hasLocation(#20237,#20163) -successor(#20227,#20231) -successor(#20234,#20232) -successor(#20232,#20228) -successor(#20231,#20229) -successor(#20229,#20234) -successor(#20228,#20237) -successor(#20218,#20221) -successor(#20225,#20224) -successor(#20224,#20222) -successor(#20222,#20219) -successor(#20221,#20225) -successor(#20219,#20227) +entry_cfg_node(#20237,#20001) +#20238=@"loc,{#10000},1,1,1,0" +locations_default(#20238,#10000,1,1,1,0) +hasLocation(#20237,#20238) +#20239=* +exit_cfg_node(#20239,#20001) +hasLocation(#20239,#20163) +successor(#20229,#20233) +successor(#20236,#20234) +successor(#20234,#20230) +successor(#20233,#20231) +successor(#20231,#20236) +successor(#20230,#20239) +successor(#20220,#20223) +successor(#20227,#20226) +successor(#20226,#20224) +successor(#20224,#20221) +successor(#20223,#20227) +successor(#20221,#20229) successor(#20181,#20184) -successor(#20216,#20214) -successor(#20214,#20207) -successor(#20213,#20209) -successor(#20211,#20213) -successor(#20209,#20216) -successor(#20207,#20182) -successor(#20205,#20211) +successor(#20218,#20216) +successor(#20216,#20209) +successor(#20215,#20211) +successor(#20213,#20215) +successor(#20211,#20218) +successor(#20209,#20182) +successor(#20207,#20213) successor(#20202,#20197) successor(#20199,#20202) successor(#20197,#20194) successor(#20196,#20199) -successor(#20194,#20205) +successor(#20194,#20207) successor(#20191,#20185) successor(#20190,#20187) successor(#20189,#20190) successor(#20187,#20191) successor(#20185,#20196) successor(#20184,#20189) -successor(#20182,#20218) +successor(#20182,#20220) successor(#20169,#20174) successor(#20180,#20178) successor(#20179,#20180) @@ -765,6 +771,6 @@ successor(#20170,#20181) successor(#20165,#20168) successor(#20168,#20166) successor(#20166,#20169) -successor(#20235,#20165) +successor(#20237,#20165) numlines(#10000,5,5,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/regexp/input/multipart.js b/javascript/extractor/tests/regexp/input/multipart.js new file mode 100644 index 00000000000..e278722b9a2 --- /dev/null +++ b/javascript/extractor/tests/regexp/input/multipart.js @@ -0,0 +1,14 @@ +var reg = new RegExp("foo" + "bar"); + +var reg2 = new RegExp("foo" + + "bar"); + +var reg3 = new RegExp( + "foo" + "bar"); + +var reg4 = new RegExp( + "foo" + + "bar" + + "baz" + + "qux" +); \ No newline at end of file diff --git a/javascript/extractor/tests/regexp/output/trap/multipart.js.trap b/javascript/extractor/tests/regexp/output/trap/multipart.js.trap new file mode 100644 index 00000000000..b8b165ddf5b --- /dev/null +++ b/javascript/extractor/tests/regexp/output/trap/multipart.js.trap @@ -0,0 +1,727 @@ +#10000=@"/multipart.js;sourcefile" +files(#10000,"/multipart.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,"var reg = new RegExp(""foo"" + ""bar"");"," +") +#20003=@"loc,{#10000},1,1,1,36" +locations_default(#20003,#10000,1,1,1,36) +hasLocation(#20002,#20003) +#20004=* +lines(#20004,#20001,""," +") +#20005=@"loc,{#10000},2,1,2,0" +locations_default(#20005,#10000,2,1,2,0) +hasLocation(#20004,#20005) +#20006=* +lines(#20006,#20001,"var reg2 = new RegExp(""foo"""," +") +#20007=@"loc,{#10000},3,1,3,27" +locations_default(#20007,#10000,3,1,3,27) +hasLocation(#20006,#20007) +#20008=* +lines(#20008,#20001," + ""bar"");"," +") +#20009=@"loc,{#10000},4,1,4,13" +locations_default(#20009,#10000,4,1,4,13) +hasLocation(#20008,#20009) +indentation(#10000,4," ",4) +#20010=* +lines(#20010,#20001,""," +") +#20011=@"loc,{#10000},5,1,5,0" +locations_default(#20011,#10000,5,1,5,0) +hasLocation(#20010,#20011) +#20012=* +lines(#20012,#20001,"var reg3 = new RegExp("," +") +#20013=@"loc,{#10000},6,1,6,22" +locations_default(#20013,#10000,6,1,6,22) +hasLocation(#20012,#20013) +#20014=* +lines(#20014,#20001," ""foo"" + ""bar"");"," +") +#20015=@"loc,{#10000},7,1,7,19" +locations_default(#20015,#10000,7,1,7,19) +hasLocation(#20014,#20015) +indentation(#10000,7," ",4) +#20016=* +lines(#20016,#20001,""," +") +#20017=@"loc,{#10000},8,1,8,0" +locations_default(#20017,#10000,8,1,8,0) +hasLocation(#20016,#20017) +#20018=* +lines(#20018,#20001,"var reg4 = new RegExp("," +") +#20019=@"loc,{#10000},9,1,9,22" +locations_default(#20019,#10000,9,1,9,22) +hasLocation(#20018,#20019) +#20020=* +lines(#20020,#20001," ""foo"" + "," +") +#20021=@"loc,{#10000},10,1,10,12" +locations_default(#20021,#10000,10,1,10,12) +hasLocation(#20020,#20021) +indentation(#10000,10," ",4) +#20022=* +lines(#20022,#20001," ""bar"" + "," +") +#20023=@"loc,{#10000},11,1,11,12" +locations_default(#20023,#10000,11,1,11,12) +hasLocation(#20022,#20023) +indentation(#10000,11," ",4) +#20024=* +lines(#20024,#20001," ""baz"" + "," +") +#20025=@"loc,{#10000},12,1,12,12" +locations_default(#20025,#10000,12,1,12,12) +hasLocation(#20024,#20025) +indentation(#10000,12," ",4) +#20026=* +lines(#20026,#20001," ""qux"""," +") +#20027=@"loc,{#10000},13,1,13,9" +locations_default(#20027,#10000,13,1,13,9) +hasLocation(#20026,#20027) +indentation(#10000,13," ",4) +#20028=* +lines(#20028,#20001,");","") +#20029=@"loc,{#10000},14,1,14,2" +locations_default(#20029,#10000,14,1,14,2) +hasLocation(#20028,#20029) +numlines(#20001,14,11,0) +#20030=* +tokeninfo(#20030,7,#20001,0,"var") +#20031=@"loc,{#10000},1,1,1,3" +locations_default(#20031,#10000,1,1,1,3) +hasLocation(#20030,#20031) +#20032=* +tokeninfo(#20032,6,#20001,1,"reg") +#20033=@"loc,{#10000},1,5,1,7" +locations_default(#20033,#10000,1,5,1,7) +hasLocation(#20032,#20033) +#20034=* +tokeninfo(#20034,8,#20001,2,"=") +#20035=@"loc,{#10000},1,9,1,9" +locations_default(#20035,#10000,1,9,1,9) +hasLocation(#20034,#20035) +#20036=* +tokeninfo(#20036,7,#20001,3,"new") +#20037=@"loc,{#10000},1,11,1,13" +locations_default(#20037,#10000,1,11,1,13) +hasLocation(#20036,#20037) +#20038=* +tokeninfo(#20038,6,#20001,4,"RegExp") +#20039=@"loc,{#10000},1,15,1,20" +locations_default(#20039,#10000,1,15,1,20) +hasLocation(#20038,#20039) +#20040=* +tokeninfo(#20040,8,#20001,5,"(") +#20041=@"loc,{#10000},1,21,1,21" +locations_default(#20041,#10000,1,21,1,21) +hasLocation(#20040,#20041) +#20042=* +tokeninfo(#20042,4,#20001,6,"""foo""") +#20043=@"loc,{#10000},1,22,1,26" +locations_default(#20043,#10000,1,22,1,26) +hasLocation(#20042,#20043) +#20044=* +tokeninfo(#20044,8,#20001,7,"+") +#20045=@"loc,{#10000},1,28,1,28" +locations_default(#20045,#10000,1,28,1,28) +hasLocation(#20044,#20045) +#20046=* +tokeninfo(#20046,4,#20001,8,"""bar""") +#20047=@"loc,{#10000},1,30,1,34" +locations_default(#20047,#10000,1,30,1,34) +hasLocation(#20046,#20047) +#20048=* +tokeninfo(#20048,8,#20001,9,")") +#20049=@"loc,{#10000},1,35,1,35" +locations_default(#20049,#10000,1,35,1,35) +hasLocation(#20048,#20049) +#20050=* +tokeninfo(#20050,8,#20001,10,";") +#20051=@"loc,{#10000},1,36,1,36" +locations_default(#20051,#10000,1,36,1,36) +hasLocation(#20050,#20051) +#20052=* +tokeninfo(#20052,7,#20001,11,"var") +#20053=@"loc,{#10000},3,1,3,3" +locations_default(#20053,#10000,3,1,3,3) +hasLocation(#20052,#20053) +#20054=* +tokeninfo(#20054,6,#20001,12,"reg2") +#20055=@"loc,{#10000},3,5,3,8" +locations_default(#20055,#10000,3,5,3,8) +hasLocation(#20054,#20055) +#20056=* +tokeninfo(#20056,8,#20001,13,"=") +#20057=@"loc,{#10000},3,10,3,10" +locations_default(#20057,#10000,3,10,3,10) +hasLocation(#20056,#20057) +#20058=* +tokeninfo(#20058,7,#20001,14,"new") +#20059=@"loc,{#10000},3,12,3,14" +locations_default(#20059,#10000,3,12,3,14) +hasLocation(#20058,#20059) +#20060=* +tokeninfo(#20060,6,#20001,15,"RegExp") +#20061=@"loc,{#10000},3,16,3,21" +locations_default(#20061,#10000,3,16,3,21) +hasLocation(#20060,#20061) +#20062=* +tokeninfo(#20062,8,#20001,16,"(") +#20063=@"loc,{#10000},3,22,3,22" +locations_default(#20063,#10000,3,22,3,22) +hasLocation(#20062,#20063) +#20064=* +tokeninfo(#20064,4,#20001,17,"""foo""") +#20065=@"loc,{#10000},3,23,3,27" +locations_default(#20065,#10000,3,23,3,27) +hasLocation(#20064,#20065) +#20066=* +tokeninfo(#20066,8,#20001,18,"+") +#20067=@"loc,{#10000},4,5,4,5" +locations_default(#20067,#10000,4,5,4,5) +hasLocation(#20066,#20067) +#20068=* +tokeninfo(#20068,4,#20001,19,"""bar""") +#20069=@"loc,{#10000},4,7,4,11" +locations_default(#20069,#10000,4,7,4,11) +hasLocation(#20068,#20069) +#20070=* +tokeninfo(#20070,8,#20001,20,")") +#20071=@"loc,{#10000},4,12,4,12" +locations_default(#20071,#10000,4,12,4,12) +hasLocation(#20070,#20071) +#20072=* +tokeninfo(#20072,8,#20001,21,";") +#20073=@"loc,{#10000},4,13,4,13" +locations_default(#20073,#10000,4,13,4,13) +hasLocation(#20072,#20073) +#20074=* +tokeninfo(#20074,7,#20001,22,"var") +#20075=@"loc,{#10000},6,1,6,3" +locations_default(#20075,#10000,6,1,6,3) +hasLocation(#20074,#20075) +#20076=* +tokeninfo(#20076,6,#20001,23,"reg3") +#20077=@"loc,{#10000},6,5,6,8" +locations_default(#20077,#10000,6,5,6,8) +hasLocation(#20076,#20077) +#20078=* +tokeninfo(#20078,8,#20001,24,"=") +#20079=@"loc,{#10000},6,10,6,10" +locations_default(#20079,#10000,6,10,6,10) +hasLocation(#20078,#20079) +#20080=* +tokeninfo(#20080,7,#20001,25,"new") +#20081=@"loc,{#10000},6,12,6,14" +locations_default(#20081,#10000,6,12,6,14) +hasLocation(#20080,#20081) +#20082=* +tokeninfo(#20082,6,#20001,26,"RegExp") +#20083=@"loc,{#10000},6,16,6,21" +locations_default(#20083,#10000,6,16,6,21) +hasLocation(#20082,#20083) +#20084=* +tokeninfo(#20084,8,#20001,27,"(") +#20085=@"loc,{#10000},6,22,6,22" +locations_default(#20085,#10000,6,22,6,22) +hasLocation(#20084,#20085) +#20086=* +tokeninfo(#20086,4,#20001,28,"""foo""") +#20087=@"loc,{#10000},7,5,7,9" +locations_default(#20087,#10000,7,5,7,9) +hasLocation(#20086,#20087) +#20088=* +tokeninfo(#20088,8,#20001,29,"+") +#20089=@"loc,{#10000},7,11,7,11" +locations_default(#20089,#10000,7,11,7,11) +hasLocation(#20088,#20089) +#20090=* +tokeninfo(#20090,4,#20001,30,"""bar""") +#20091=@"loc,{#10000},7,13,7,17" +locations_default(#20091,#10000,7,13,7,17) +hasLocation(#20090,#20091) +#20092=* +tokeninfo(#20092,8,#20001,31,")") +#20093=@"loc,{#10000},7,18,7,18" +locations_default(#20093,#10000,7,18,7,18) +hasLocation(#20092,#20093) +#20094=* +tokeninfo(#20094,8,#20001,32,";") +#20095=@"loc,{#10000},7,19,7,19" +locations_default(#20095,#10000,7,19,7,19) +hasLocation(#20094,#20095) +#20096=* +tokeninfo(#20096,7,#20001,33,"var") +#20097=@"loc,{#10000},9,1,9,3" +locations_default(#20097,#10000,9,1,9,3) +hasLocation(#20096,#20097) +#20098=* +tokeninfo(#20098,6,#20001,34,"reg4") +#20099=@"loc,{#10000},9,5,9,8" +locations_default(#20099,#10000,9,5,9,8) +hasLocation(#20098,#20099) +#20100=* +tokeninfo(#20100,8,#20001,35,"=") +#20101=@"loc,{#10000},9,10,9,10" +locations_default(#20101,#10000,9,10,9,10) +hasLocation(#20100,#20101) +#20102=* +tokeninfo(#20102,7,#20001,36,"new") +#20103=@"loc,{#10000},9,12,9,14" +locations_default(#20103,#10000,9,12,9,14) +hasLocation(#20102,#20103) +#20104=* +tokeninfo(#20104,6,#20001,37,"RegExp") +#20105=@"loc,{#10000},9,16,9,21" +locations_default(#20105,#10000,9,16,9,21) +hasLocation(#20104,#20105) +#20106=* +tokeninfo(#20106,8,#20001,38,"(") +#20107=@"loc,{#10000},9,22,9,22" +locations_default(#20107,#10000,9,22,9,22) +hasLocation(#20106,#20107) +#20108=* +tokeninfo(#20108,4,#20001,39,"""foo""") +#20109=@"loc,{#10000},10,5,10,9" +locations_default(#20109,#10000,10,5,10,9) +hasLocation(#20108,#20109) +#20110=* +tokeninfo(#20110,8,#20001,40,"+") +#20111=@"loc,{#10000},10,11,10,11" +locations_default(#20111,#10000,10,11,10,11) +hasLocation(#20110,#20111) +#20112=* +tokeninfo(#20112,4,#20001,41,"""bar""") +#20113=@"loc,{#10000},11,5,11,9" +locations_default(#20113,#10000,11,5,11,9) +hasLocation(#20112,#20113) +#20114=* +tokeninfo(#20114,8,#20001,42,"+") +#20115=@"loc,{#10000},11,11,11,11" +locations_default(#20115,#10000,11,11,11,11) +hasLocation(#20114,#20115) +#20116=* +tokeninfo(#20116,4,#20001,43,"""baz""") +#20117=@"loc,{#10000},12,5,12,9" +locations_default(#20117,#10000,12,5,12,9) +hasLocation(#20116,#20117) +#20118=* +tokeninfo(#20118,8,#20001,44,"+") +#20119=@"loc,{#10000},12,11,12,11" +locations_default(#20119,#10000,12,11,12,11) +hasLocation(#20118,#20119) +#20120=* +tokeninfo(#20120,4,#20001,45,"""qux""") +#20121=@"loc,{#10000},13,5,13,9" +locations_default(#20121,#10000,13,5,13,9) +hasLocation(#20120,#20121) +#20122=* +tokeninfo(#20122,8,#20001,46,")") +#20123=@"loc,{#10000},14,1,14,1" +locations_default(#20123,#10000,14,1,14,1) +hasLocation(#20122,#20123) +#20124=* +tokeninfo(#20124,8,#20001,47,";") +#20125=@"loc,{#10000},14,2,14,2" +locations_default(#20125,#10000,14,2,14,2) +hasLocation(#20124,#20125) +#20126=* +tokeninfo(#20126,0,#20001,48,"") +#20127=@"loc,{#10000},14,3,14,2" +locations_default(#20127,#10000,14,3,14,2) +hasLocation(#20126,#20127) +toplevels(#20001,0) +#20128=@"loc,{#10000},1,1,14,2" +locations_default(#20128,#10000,1,1,14,2) +hasLocation(#20001,#20128) +#20129=@"var;{reg};{#20000}" +variables(#20129,"reg",#20000) +#20130=@"var;{reg2};{#20000}" +variables(#20130,"reg2",#20000) +#20131=@"var;{reg3};{#20000}" +variables(#20131,"reg3",#20000) +#20132=@"var;{reg4};{#20000}" +variables(#20132,"reg4",#20000) +#20133=* +stmts(#20133,18,#20001,0,"var reg ... ""bar"");") +hasLocation(#20133,#20003) +stmt_containers(#20133,#20001) +#20134=* +exprs(#20134,64,#20133,0,"reg = n ... ""bar"")") +#20135=@"loc,{#10000},1,5,1,35" +locations_default(#20135,#10000,1,5,1,35) +hasLocation(#20134,#20135) +enclosing_stmt(#20134,#20133) +expr_containers(#20134,#20001) +#20136=* +exprs(#20136,78,#20134,0,"reg") +hasLocation(#20136,#20033) +enclosing_stmt(#20136,#20133) +expr_containers(#20136,#20001) +literals("reg","reg",#20136) +decl(#20136,#20129) +#20137=* +exprs(#20137,12,#20134,1,"new Reg ... ""bar"")") +#20138=@"loc,{#10000},1,11,1,35" +locations_default(#20138,#10000,1,11,1,35) +hasLocation(#20137,#20138) +enclosing_stmt(#20137,#20133) +expr_containers(#20137,#20001) +#20139=* +exprs(#20139,79,#20137,-1,"RegExp") +hasLocation(#20139,#20039) +enclosing_stmt(#20139,#20133) +expr_containers(#20139,#20001) +literals("RegExp","RegExp",#20139) +#20140=@"var;{RegExp};{#20000}" +variables(#20140,"RegExp",#20000) +bind(#20139,#20140) +#20141=* +exprs(#20141,34,#20137,0,"""foo"" + ""bar""") +#20142=@"loc,{#10000},1,22,1,34" +locations_default(#20142,#10000,1,22,1,34) +hasLocation(#20141,#20142) +enclosing_stmt(#20141,#20133) +expr_containers(#20141,#20001) +#20143=* +exprs(#20143,4,#20141,0,"""foo""") +hasLocation(#20143,#20043) +enclosing_stmt(#20143,#20133) +expr_containers(#20143,#20001) +literals("foo","""foo""",#20143) +#20144=* +regexpterm(#20144,14,#20143,0,"foo") +#20145=@"loc,{#10000},1,23,1,25" +locations_default(#20145,#10000,1,23,1,25) +hasLocation(#20144,#20145) +regexp_const_value(#20144,"foo") +#20146=* +exprs(#20146,4,#20141,1,"""bar""") +hasLocation(#20146,#20047) +enclosing_stmt(#20146,#20133) +expr_containers(#20146,#20001) +literals("bar","""bar""",#20146) +#20147=* +regexpterm(#20147,14,#20146,0,"bar") +#20148=@"loc,{#10000},1,31,1,33" +locations_default(#20148,#10000,1,31,1,33) +hasLocation(#20147,#20148) +regexp_const_value(#20147,"bar") +#20149=* +regexpterm(#20149,14,#20141,0,"foobar") +#20150=@"loc,{#10000},1,23,1,33" +locations_default(#20150,#10000,1,23,1,33) +hasLocation(#20149,#20150) +regexp_const_value(#20149,"foobar") +#20151=* +stmts(#20151,18,#20001,1,"var reg ... ""bar"");") +#20152=@"loc,{#10000},3,1,4,13" +locations_default(#20152,#10000,3,1,4,13) +hasLocation(#20151,#20152) +stmt_containers(#20151,#20001) +#20153=* +exprs(#20153,64,#20151,0,"reg2 = ... ""bar"")") +#20154=@"loc,{#10000},3,5,4,12" +locations_default(#20154,#10000,3,5,4,12) +hasLocation(#20153,#20154) +enclosing_stmt(#20153,#20151) +expr_containers(#20153,#20001) +#20155=* +exprs(#20155,78,#20153,0,"reg2") +hasLocation(#20155,#20055) +enclosing_stmt(#20155,#20151) +expr_containers(#20155,#20001) +literals("reg2","reg2",#20155) +decl(#20155,#20130) +#20156=* +exprs(#20156,12,#20153,1,"new Reg ... ""bar"")") +#20157=@"loc,{#10000},3,12,4,12" +locations_default(#20157,#10000,3,12,4,12) +hasLocation(#20156,#20157) +enclosing_stmt(#20156,#20151) +expr_containers(#20156,#20001) +#20158=* +exprs(#20158,79,#20156,-1,"RegExp") +hasLocation(#20158,#20061) +enclosing_stmt(#20158,#20151) +expr_containers(#20158,#20001) +literals("RegExp","RegExp",#20158) +bind(#20158,#20140) +#20159=* +exprs(#20159,34,#20156,0,"""foo""\n + ""bar""") +#20160=@"loc,{#10000},3,23,4,11" +locations_default(#20160,#10000,3,23,4,11) +hasLocation(#20159,#20160) +enclosing_stmt(#20159,#20151) +expr_containers(#20159,#20001) +#20161=* +exprs(#20161,4,#20159,0,"""foo""") +hasLocation(#20161,#20065) +enclosing_stmt(#20161,#20151) +expr_containers(#20161,#20001) +literals("foo","""foo""",#20161) +#20162=* +regexpterm(#20162,14,#20161,0,"foo") +#20163=@"loc,{#10000},3,24,3,26" +locations_default(#20163,#10000,3,24,3,26) +hasLocation(#20162,#20163) +regexp_const_value(#20162,"foo") +#20164=* +exprs(#20164,4,#20159,1,"""bar""") +hasLocation(#20164,#20069) +enclosing_stmt(#20164,#20151) +expr_containers(#20164,#20001) +literals("bar","""bar""",#20164) +#20165=* +regexpterm(#20165,14,#20164,0,"bar") +#20166=@"loc,{#10000},4,8,4,10" +locations_default(#20166,#10000,4,8,4,10) +hasLocation(#20165,#20166) +regexp_const_value(#20165,"bar") +#20167=* +regexpterm(#20167,14,#20159,0,"foobar") +#20168=@"loc,{#10000},3,24,4,11" +locations_default(#20168,#10000,3,24,4,11) +hasLocation(#20167,#20168) +regexp_const_value(#20167,"foobar") +#20169=* +stmts(#20169,18,#20001,2,"var reg ... ""bar"");") +#20170=@"loc,{#10000},6,1,7,19" +locations_default(#20170,#10000,6,1,7,19) +hasLocation(#20169,#20170) +stmt_containers(#20169,#20001) +#20171=* +exprs(#20171,64,#20169,0,"reg3 = ... ""bar"")") +#20172=@"loc,{#10000},6,5,7,18" +locations_default(#20172,#10000,6,5,7,18) +hasLocation(#20171,#20172) +enclosing_stmt(#20171,#20169) +expr_containers(#20171,#20001) +#20173=* +exprs(#20173,78,#20171,0,"reg3") +hasLocation(#20173,#20077) +enclosing_stmt(#20173,#20169) +expr_containers(#20173,#20001) +literals("reg3","reg3",#20173) +decl(#20173,#20131) +#20174=* +exprs(#20174,12,#20171,1,"new Reg ... ""bar"")") +#20175=@"loc,{#10000},6,12,7,18" +locations_default(#20175,#10000,6,12,7,18) +hasLocation(#20174,#20175) +enclosing_stmt(#20174,#20169) +expr_containers(#20174,#20001) +#20176=* +exprs(#20176,79,#20174,-1,"RegExp") +hasLocation(#20176,#20083) +enclosing_stmt(#20176,#20169) +expr_containers(#20176,#20001) +literals("RegExp","RegExp",#20176) +bind(#20176,#20140) +#20177=* +exprs(#20177,34,#20174,0,"""foo"" + ""bar""") +#20178=@"loc,{#10000},7,5,7,17" +locations_default(#20178,#10000,7,5,7,17) +hasLocation(#20177,#20178) +enclosing_stmt(#20177,#20169) +expr_containers(#20177,#20001) +#20179=* +exprs(#20179,4,#20177,0,"""foo""") +hasLocation(#20179,#20087) +enclosing_stmt(#20179,#20169) +expr_containers(#20179,#20001) +literals("foo","""foo""",#20179) +#20180=* +regexpterm(#20180,14,#20179,0,"foo") +#20181=@"loc,{#10000},7,6,7,8" +locations_default(#20181,#10000,7,6,7,8) +hasLocation(#20180,#20181) +regexp_const_value(#20180,"foo") +#20182=* +exprs(#20182,4,#20177,1,"""bar""") +hasLocation(#20182,#20091) +enclosing_stmt(#20182,#20169) +expr_containers(#20182,#20001) +literals("bar","""bar""",#20182) +#20183=* +regexpterm(#20183,14,#20182,0,"bar") +#20184=@"loc,{#10000},7,14,7,16" +locations_default(#20184,#10000,7,14,7,16) +hasLocation(#20183,#20184) +regexp_const_value(#20183,"bar") +#20185=* +regexpterm(#20185,14,#20177,0,"foobar") +#20186=@"loc,{#10000},7,6,7,16" +locations_default(#20186,#10000,7,6,7,16) +hasLocation(#20185,#20186) +regexp_const_value(#20185,"foobar") +#20187=* +stmts(#20187,18,#20001,3,"var reg ... qux""\n);") +#20188=@"loc,{#10000},9,1,14,2" +locations_default(#20188,#10000,9,1,14,2) +hasLocation(#20187,#20188) +stmt_containers(#20187,#20001) +#20189=* +exprs(#20189,64,#20187,0,"reg4 = ... ""qux""\n)") +#20190=@"loc,{#10000},9,5,14,1" +locations_default(#20190,#10000,9,5,14,1) +hasLocation(#20189,#20190) +enclosing_stmt(#20189,#20187) +expr_containers(#20189,#20001) +#20191=* +exprs(#20191,78,#20189,0,"reg4") +hasLocation(#20191,#20099) +enclosing_stmt(#20191,#20187) +expr_containers(#20191,#20001) +literals("reg4","reg4",#20191) +decl(#20191,#20132) +#20192=* +exprs(#20192,12,#20189,1,"new Reg ... ""qux""\n)") +#20193=@"loc,{#10000},9,12,14,1" +locations_default(#20193,#10000,9,12,14,1) +hasLocation(#20192,#20193) +enclosing_stmt(#20192,#20187) +expr_containers(#20192,#20001) +#20194=* +exprs(#20194,79,#20192,-1,"RegExp") +hasLocation(#20194,#20105) +enclosing_stmt(#20194,#20187) +expr_containers(#20194,#20001) +literals("RegExp","RegExp",#20194) +bind(#20194,#20140) +#20195=* +exprs(#20195,34,#20192,0,"""foo"" + ... ""qux""") +#20196=@"loc,{#10000},10,5,13,9" +locations_default(#20196,#10000,10,5,13,9) +hasLocation(#20195,#20196) +enclosing_stmt(#20195,#20187) +expr_containers(#20195,#20001) +#20197=* +exprs(#20197,34,#20195,0,"""foo"" + ... ""baz""") +#20198=@"loc,{#10000},10,5,12,9" +locations_default(#20198,#10000,10,5,12,9) +hasLocation(#20197,#20198) +enclosing_stmt(#20197,#20187) +expr_containers(#20197,#20001) +#20199=* +exprs(#20199,34,#20197,0,"""foo"" + \n ""bar""") +#20200=@"loc,{#10000},10,5,11,9" +locations_default(#20200,#10000,10,5,11,9) +hasLocation(#20199,#20200) +enclosing_stmt(#20199,#20187) +expr_containers(#20199,#20001) +#20201=* +exprs(#20201,4,#20199,0,"""foo""") +hasLocation(#20201,#20109) +enclosing_stmt(#20201,#20187) +expr_containers(#20201,#20001) +literals("foo","""foo""",#20201) +#20202=* +regexpterm(#20202,14,#20201,0,"foo") +#20203=@"loc,{#10000},10,6,10,8" +locations_default(#20203,#10000,10,6,10,8) +hasLocation(#20202,#20203) +regexp_const_value(#20202,"foo") +#20204=* +exprs(#20204,4,#20199,1,"""bar""") +hasLocation(#20204,#20113) +enclosing_stmt(#20204,#20187) +expr_containers(#20204,#20001) +literals("bar","""bar""",#20204) +#20205=* +regexpterm(#20205,14,#20204,0,"bar") +#20206=@"loc,{#10000},11,6,11,8" +locations_default(#20206,#10000,11,6,11,8) +hasLocation(#20205,#20206) +regexp_const_value(#20205,"bar") +#20207=* +exprs(#20207,4,#20197,1,"""baz""") +hasLocation(#20207,#20117) +enclosing_stmt(#20207,#20187) +expr_containers(#20207,#20001) +literals("baz","""baz""",#20207) +#20208=* +regexpterm(#20208,14,#20207,0,"baz") +#20209=@"loc,{#10000},12,6,12,8" +locations_default(#20209,#10000,12,6,12,8) +hasLocation(#20208,#20209) +regexp_const_value(#20208,"baz") +#20210=* +exprs(#20210,4,#20195,1,"""qux""") +hasLocation(#20210,#20121) +enclosing_stmt(#20210,#20187) +expr_containers(#20210,#20001) +literals("qux","""qux""",#20210) +#20211=* +regexpterm(#20211,14,#20210,0,"qux") +#20212=@"loc,{#10000},13,6,13,8" +locations_default(#20212,#10000,13,6,13,8) +hasLocation(#20211,#20212) +regexp_const_value(#20211,"qux") +#20213=* +regexpterm(#20213,14,#20195,0,"foobarbazqux") +#20214=@"loc,{#10000},10,6,13,9" +locations_default(#20214,#10000,10,6,13,9) +hasLocation(#20213,#20214) +regexp_const_value(#20213,"foobarbazqux") +#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,#20127) +successor(#20187,#20191) +successor(#20210,#20195) +successor(#20207,#20197) +successor(#20204,#20199) +successor(#20201,#20204) +successor(#20199,#20207) +successor(#20197,#20210) +successor(#20195,#20192) +successor(#20194,#20201) +successor(#20192,#20189) +successor(#20191,#20194) +successor(#20189,#20217) +successor(#20169,#20173) +successor(#20182,#20177) +successor(#20179,#20182) +successor(#20177,#20174) +successor(#20176,#20179) +successor(#20174,#20171) +successor(#20173,#20176) +successor(#20171,#20187) +successor(#20151,#20155) +successor(#20164,#20159) +successor(#20161,#20164) +successor(#20159,#20156) +successor(#20158,#20161) +successor(#20156,#20153) +successor(#20155,#20158) +successor(#20153,#20169) +successor(#20133,#20136) +successor(#20146,#20141) +successor(#20143,#20146) +successor(#20141,#20137) +successor(#20139,#20143) +successor(#20137,#20134) +successor(#20136,#20139) +successor(#20134,#20151) +successor(#20215,#20133) +numlines(#10000,14,11,0) +filetype(#10000,"javascript") diff --git a/javascript/ql/lib/semmle/javascript/Expr.qll b/javascript/ql/lib/semmle/javascript/Expr.qll index da4051bf72a..4d91fdb218e 100644 --- a/javascript/ql/lib/semmle/javascript/Expr.qll +++ b/javascript/ql/lib/semmle/javascript/Expr.qll @@ -1559,6 +1559,14 @@ class URShiftExpr extends @urshift_expr, BinaryExpr { */ class AddExpr extends @add_expr, BinaryExpr { override string getOperator() { result = "+" } + + /** + * Gets the value of this string concatenation parsed as a regular expression, if possible. + * + * All string literals have an associated regular expression tree, provided they can + * be parsed without syntax errors. + */ + RegExpTerm asRegExp() { this = result.getParent() } } /** diff --git a/javascript/ql/lib/semmle/javascript/Regexp.qll b/javascript/ql/lib/semmle/javascript/Regexp.qll index 877db09c9ea..f3293f81a16 100644 --- a/javascript/ql/lib/semmle/javascript/Regexp.qll +++ b/javascript/ql/lib/semmle/javascript/Regexp.qll @@ -155,7 +155,7 @@ class RegExpTerm extends Locatable, @regexpterm { exists(RegExpParent parent | parent = getRootTerm().getParent() | parent instanceof RegExpLiteral or - parent.(StringLiteral).flow() instanceof RegExpPatternSource + parent.(Expr).flow() instanceof RegExpPatternSource ) } @@ -1104,6 +1104,30 @@ private class StringRegExpPatternSource extends RegExpPatternSource { override RegExpTerm getRegExpTerm() { result = asExpr().(StringLiteral).asRegExp() } } +/** + * A node whose string value may flow to a position where it is interpreted + * as a part of a regular expression. + */ +private class StringConcatRegExpPatternSource extends RegExpPatternSource { + DataFlow::Node parse; + + StringConcatRegExpPatternSource() { this = regExpSource(parse) } + + override DataFlow::Node getAParse() { result = parse } + + override DataFlow::SourceNode getARegExpObject() { + exists(DataFlow::InvokeNode constructor | + constructor = DataFlow::globalVarRef("RegExp").getAnInvocation() and + parse = constructor.getArgument(0) and + result = constructor + ) + } + + override string getPattern() { result = getStringValue() } + + override RegExpTerm getRegExpTerm() { result = asExpr().(AddExpr).asRegExp() } +} + module RegExp { /** Gets the string `"?"` used to represent a regular expression whose flags are unknown. */ string unknownFlag() { result = "?" } diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme b/javascript/ql/lib/semmlecode.javascript.dbscheme index e54b35a8a12..8320e9d13aa 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme @@ -855,7 +855,7 @@ regexpterm (unique int id: @regexpterm, int idx: int ref, varchar(900) tostring: string ref); -@regexpparent = @regexpterm | @regexp_literal | @string_literal; +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; case @regexpterm.kind of 0 = @regexp_alt diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected index dbf74f78d8f..a68bc2b1924 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected +++ b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected @@ -512,3 +512,8 @@ | tst.js:384:15:384:26 | ([AB]\|[ab])* | Strings with many repetitions of 'A' can start matching anywhere after the start of the preceeding ([AB]\|[ab])*C | | tst.js:385:14:385:25 | ([DE]\|[de])* | Strings with many repetitions of 'd' can start matching anywhere after the start of the preceeding ([DE]\|[de])*F | | tst.js:388:14:388:20 | (a\|aa)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a\|aa)*$ | +| tst.js:391:6:394:6 | (a\|aa)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a\|aa)*b$ | +| tst.js:398:7:399:5 | (c\|cc)* | Strings with many repetitions of 'c' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | +| tst.js:399:7:400:5 | (d\|dd)* | Strings with many repetitions of 'd' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | +| tst.js:400:7:401:2 | (e\|ee)* | Strings with many repetitions of 'e' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | +| tst.js:404:6:405:8 | (g\|gg)* | Strings with many repetitions of 'g' can start matching anywhere after the start of the preceeding (g\|gg)*h$ | diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected b/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected index d7155b3711f..b8ed9c86150 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected +++ b/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected @@ -183,3 +183,8 @@ | tst.js:385:14:385:25 | ([DE]\|[de])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'd'. | | tst.js:387:27:387:33 | (a\|aa)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'. | | tst.js:388:14:388:20 | (a\|aa)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'. | +| tst.js:391:6:394:6 | (a\|aa)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'. | +| tst.js:398:7:399:5 | (c\|cc)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'cc'. | +| tst.js:399:7:400:5 | (d\|dd)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'dd'. | +| tst.js:400:7:401:2 | (e\|ee)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'ee'. | +| tst.js:404:6:405:8 | (g\|gg)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'gg'. | diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/tst.js b/javascript/ql/test/query-tests/Performance/ReDoS/tst.js index 6f3f8b1cd22..58ae9694efc 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/tst.js +++ b/javascript/ql/test/query-tests/Performance/ReDoS/tst.js @@ -385,4 +385,21 @@ var good47 = /([AB]|[ab])*C/; var bad92 = /([DE]|[de])*F/i; var bad93 = /(?<=^v?|\sv?)(a|aa)*$/; -var bad94 = /(a|aa)*$/; \ No newline at end of file +var bad94 = /(a|aa)*$/; + +var bad95 = new RegExp( + "(a" + + "|" + + "aa)*" + + "b$" +); + +var bad96 = new RegExp("(" + + "(c|cc)*|" + + "(d|dd)*|" + + "(e|ee)*" + +")f$"); + +var bad97 = new RegExp( + "(g|gg" + + ")*h$"); diff --git a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected index 4911f159e47..7d95ac646e7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected @@ -15,11 +15,15 @@ | tst-IncompleteHostnameRegExp.js:38:3:38:43 | ^(http\|https):\\/\\/www.example.com\\/p\\/f\\/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:38:2:38:44 | /^(http ... p\\/f\\// | here | | tst-IncompleteHostnameRegExp.js:39:5:39:30 | http:\\/\\/sub.example.com\\/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:39:2:39:33 | /^(http ... om\\/)/g | here | | tst-IncompleteHostnameRegExp.js:40:3:40:29 | ^https?:\\/\\/api.example.com | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:40:2:40:30 | /^https ... le.com/ | here | +| tst-IncompleteHostnameRegExp.js:41:42:41:48 | ^https?://.+\\.example\\.com/ | This regular expression has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:41:13:41:71 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:41:42:41:70 | ^https?://.+\\.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:41:13:41:71 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:43:3:43:32 | ^https:\\/\\/[a-z]*.example.com$ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:43:2:43:33 | /^https ... e.com$/ | here | | tst-IncompleteHostnameRegExp.js:44:32:44:45 | .+.example.net | This regular expression has an unescaped '.' before 'example.net', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | | tst-IncompleteHostnameRegExp.js:44:47:44:62 | .+.example-a.com | This regular expression has an unescaped '.' before 'example-a.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | | tst-IncompleteHostnameRegExp.js:44:64:44:79 | .+.example-b.com | This regular expression has an unescaped '.' before 'example-b.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | +| tst-IncompleteHostnameRegExp.js:48:42:48:47 | ^https?://.+.example\\.com/ | This regular expression has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | +| tst-IncompleteHostnameRegExp.js:48:42:48:47 | ^https?://.+.example\\.com/ | This regular expression has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:48:42:48:68 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:48:42:48:68 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | +| tst-IncompleteHostnameRegExp.js:53:14:53:35 | test.example.com$ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:53:13:53:36 | 'test.' ... e.com$' | here | | tst-IncompleteHostnameRegExp.js:59:5:59:20 | foo.example\\.com | This regular expression has an unescaped '.' before 'example\\.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:59:2:59:32 | /^(foo. ... ever)$/ | here | diff --git a/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/old.dbscheme b/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/old.dbscheme new file mode 100644 index 00000000000..e54b35a8a12 --- /dev/null +++ b/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/old.dbscheme @@ -0,0 +1,1217 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@import_or_export_declaration = @import_declaration | @export_declaration; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @import_or_export_declaration ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +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); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/semmlecode.javascript.dbscheme b/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..8320e9d13aa --- /dev/null +++ b/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/semmlecode.javascript.dbscheme @@ -0,0 +1,1217 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@import_or_export_declaration = @import_declaration | @export_declaration; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @import_or_export_declaration ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +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); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/upgrade.properties b/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/upgrade.properties new file mode 100644 index 00000000000..32ef6c384eb --- /dev/null +++ b/javascript/upgrades/e54b35a8a129ebcf246cd4e834935f929b54aa04/upgrade.properties @@ -0,0 +1,2 @@ +description: add string concatenations as regexp parents +compatibility: backwards From be46c1f679413b5cb1238aa4f756e8a58880edb0 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 3 Nov 2021 13:25:09 +0100 Subject: [PATCH 02/10] remove unused import --- .../extractor/src/com/semmle/js/extractor/ASTExtractor.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index ff660303702..94f364e8a64 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -166,9 +166,6 @@ import com.semmle.util.locations.SourceMap; import com.semmle.util.trap.TrapWriter; import com.semmle.util.trap.TrapWriter.Label; -import com.semmle.util.files.FileLineOffsetCache; - - /** Extractor for AST-based information; invoked by the {@link JSExtractor}. */ public class ASTExtractor { private final TrapWriter trapwriter; From 1ba6f448cd2f97d9ca5617f0a77f853ca15c7e93 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 3 Nov 2021 13:26:19 +0100 Subject: [PATCH 03/10] compute concatenated string and offset at the same time --- .../com/semmle/js/extractor/ASTExtractor.java | 43 ++++++------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 94f364e8a64..c891b247262 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -600,14 +600,18 @@ public class ASTExtractor { return '0' <= ch && ch <= '7'; } - private String getStringConcatResult(Expression exp) { + private Pair getStringConcatResult(Expression exp) { if (exp instanceof BinaryExpression) { BinaryExpression be = (BinaryExpression) exp; if (be.getOperator().equals("+")) { - String left = getStringConcatResult(be.getLeft()); - String right = getStringConcatResult(be.getRight()); + Pair left = getStringConcatResult(be.getLeft()); + Pair right = getStringConcatResult(be.getRight()); if (left != null && right != null) { - return left + right; + String str = left.fst() + right.fst(); + + int delta = be.getRight().getLoc().getStart().getOffset() - be.getLeft().getLoc().getStart().getOffset(); + int offset = left.fst().length(); + return Pair.make(str, left.snd().append(right.snd(), offset, delta)); } } } else if (exp instanceof Literal) { @@ -615,33 +619,11 @@ public class ASTExtractor { if (!lit.isStringLiteral()) { return null; } - return lit.getStringValue(); + return Pair.make(lit.getStringValue(), makeStringLiteralOffsets(lit.getRaw())); } return null; } - private OffsetTranslation computeStringConcatOffset(Expression exp) { - if (exp instanceof Literal && ((Literal)exp).isStringLiteral()) { - String raw = ((Literal) exp).getRaw(); - return makeStringLiteralOffsets(raw); - } - - if (exp instanceof BinaryExpression) { - BinaryExpression be = (BinaryExpression) exp; - OffsetTranslation left = computeStringConcatOffset(be.getLeft()); - OffsetTranslation right = computeStringConcatOffset(be.getRight()); - - if (left == null || right == null) { - return null; - } - int delta = be.getRight().getLoc().getStart().getOffset() - be.getLeft().getLoc().getStart().getOffset(); - int offset = getStringConcatResult(be.getLeft()).length(); - return left.append(right, offset, delta); - } - - return null; - } - /** * Builds a translation from offsets in a string value back to its original raw literal text * (including quotes). @@ -848,14 +830,15 @@ public class ASTExtractor { if (extractedAsRegexp.contains(nd)) { return key; } - String rawString = getStringConcatResult(nd); - if (rawString == null) { + Pair concatResult = getStringConcatResult(nd); + if (concatResult == null) { return key; } + String rawString = concatResult.fst(); if (rawString.length() > 1000 && !rawString.trim().isEmpty()) { return key; } - OffsetTranslation offsets = computeStringConcatOffset(nd); + OffsetTranslation offsets = concatResult.snd(); Position start = nd.getLoc().getStart(); com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn(), start.getOffset()); SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getLoc().getSource()).offsetBy(0, offsets), startPos); From 737c747dbbe1e040432fc4fb9a765002277d10e8 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 3 Nov 2021 13:28:03 +0100 Subject: [PATCH 04/10] early exit if string becomes too big --- .../com/semmle/js/extractor/ASTExtractor.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index c891b247262..06b4130e3ad 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -606,13 +606,17 @@ public class ASTExtractor { if (be.getOperator().equals("+")) { Pair left = getStringConcatResult(be.getLeft()); Pair right = getStringConcatResult(be.getRight()); - if (left != null && right != null) { - String str = left.fst() + right.fst(); - - int delta = be.getRight().getLoc().getStart().getOffset() - be.getLeft().getLoc().getStart().getOffset(); - int offset = left.fst().length(); - return Pair.make(str, left.snd().append(right.snd(), offset, delta)); + if (left == null || right == null) { + return null; } + String str = left.fst() + right.fst(); + if (str.length() > 1000) { + return null; + } + + int delta = be.getRight().getLoc().getStart().getOffset() - be.getLeft().getLoc().getStart().getOffset(); + int offset = left.fst().length(); + return Pair.make(str, left.snd().append(right.snd(), offset, delta)); } } else if (exp instanceof Literal) { Literal lit = (Literal) exp; From 7b0ebd3f1ab02a19566e350077932a2cd7c74c89 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 3 Nov 2021 14:09:44 +0100 Subject: [PATCH 05/10] use the context to determine whether or not a node is an operand of a binop --- .../com/semmle/js/extractor/ASTExtractor.java | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 06b4130e3ad..681f0756fda 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -334,17 +334,28 @@ public class ASTExtractor { private final Label parent; private final int childIndex; private final IdContext idcontext; + private final boolean binopOperand; public Context(Label parent, int childIndex, IdContext idcontext) { + this(parent, childIndex, idcontext, false); + } + + public Context(Label parent, int childIndex, IdContext idcontext, boolean binopOperand) { this.parent = parent; this.childIndex = childIndex; this.idcontext = idcontext; + this.binopOperand = binopOperand; } /** True if the visited AST node occurs as part of a type annotation. */ public boolean isInsideType() { return idcontext.isInsideType(); } + + /** True if the visited AST node occurs as one of the operands of a binary operation. */ + public boolean isBinopOperand() { + return binopOperand; + } } private class V extends DefaultVisitor { @@ -360,7 +371,7 @@ public class ASTExtractor { } private Label visit(INode child, Label parent, int childIndex) { - return visit(child, parent, childIndex, IdContext.VAR_BIND); + return visit(child, parent, childIndex, IdContext.VAR_BIND, false); } private Label visitAll(List children, Label parent) { @@ -368,8 +379,16 @@ public class ASTExtractor { } private Label visit(INode child, Label parent, int childIndex, IdContext idContext) { + return visit(child, parent, childIndex, idContext, false); + } + + private Label visit(INode child, Label parent, int childIndex, boolean binopOperand) { + return visit(child, parent, childIndex, IdContext.VAR_BIND, binopOperand); + } + + private Label visit(INode child, Label parent, int childIndex, IdContext idContext, boolean binopOperand) { if (child == null) return null; - return child.accept(this, new Context(parent, childIndex, idContext)); + return child.accept(this, new Context(parent, childIndex, idContext, binopOperand)); } private Label visitAll( @@ -381,7 +400,7 @@ public class ASTExtractor { List children, Label parent, IdContext idContext, int index, int step) { Label res = null; for (INode child : children) { - res = visit(child, parent, index, idContext); + res = visit(child, parent, index, idContext, false); index += step; } return res; @@ -821,33 +840,33 @@ public class ASTExtractor { return key; } - // set to determine which BinaryExpression has been extracted as regexp - private Set extractedAsRegexp = new HashSet<>(); - @Override public Label visit(BinaryExpression nd, Context c) { Label key = super.visit(nd, c); - extractedAsRegexp.add(nd.getLeft()); - extractedAsRegexp.add(nd.getRight()); - visit(nd.getLeft(), key, 0); - visit(nd.getRight(), key, 1); - if (extractedAsRegexp.contains(nd)) { - return key; + visit(nd.getLeft(), key, 0, true); + visit(nd.getRight(), key, 1, true); + extractRegxpFromBinop(nd, c); + return key; + } + + private void extractRegxpFromBinop(BinaryExpression nd, Context c) { + if (c.isBinopOperand()) { + return; } Pair concatResult = getStringConcatResult(nd); if (concatResult == null) { - return key; + return; } String rawString = concatResult.fst(); if (rawString.length() > 1000 && !rawString.trim().isEmpty()) { - return key; + return; } OffsetTranslation offsets = concatResult.snd(); Position start = nd.getLoc().getStart(); com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn(), start.getOffset()); SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getLoc().getSource()).offsetBy(0, offsets), startPos); regexpExtractor.extract(rawString, sourceMap, nd, true); - return key; + return; } @Override From f01ee5914bb05e205da8fa36e6069185a829c49d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 3 Nov 2021 14:19:31 +0100 Subject: [PATCH 06/10] add a docstring, and rename rawString -> foldedString --- .../src/com/semmle/js/extractor/ASTExtractor.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 681f0756fda..2856aa86c96 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -619,6 +619,10 @@ public class ASTExtractor { return '0' <= ch && ch <= '7'; } + /** + * Constant-folds simple string concatenations in `exp` while keeping an offset translation + * that tracks back to the original source. + */ private Pair getStringConcatResult(Expression exp) { if (exp instanceof BinaryExpression) { BinaryExpression be = (BinaryExpression) exp; @@ -857,15 +861,15 @@ public class ASTExtractor { if (concatResult == null) { return; } - String rawString = concatResult.fst(); - if (rawString.length() > 1000 && !rawString.trim().isEmpty()) { + String foldedString = concatResult.fst(); + if (foldedString.length() > 1000 && !foldedString.trim().isEmpty()) { return; } OffsetTranslation offsets = concatResult.snd(); Position start = nd.getLoc().getStart(); com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn(), start.getOffset()); SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getLoc().getSource()).offsetBy(0, offsets), startPos); - regexpExtractor.extract(rawString, sourceMap, nd, true); + regexpExtractor.extract(foldedString, sourceMap, nd, true); return; } From 98da532c46153f4a1497fbf173c7be062dd594f4 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 10 Nov 2021 14:11:48 +0100 Subject: [PATCH 07/10] dont extract regular expressions from strings that are leaves in a string concat --- .../com/semmle/js/extractor/ASTExtractor.java | 2 +- .../es2015/output/trap/properties.js.trap | 218 ++++---- .../es2015/output/trap/templates.js.trap | 442 ++++++++-------- .../tests/exprs/output/trap/binary.js.trap | 184 ++++--- .../tests/jsx/output/trap/tst.js.trap | 300 ++++++----- .../regexp/output/trap/multipart.js.trap | 480 ++++++++---------- .../tests/ts/output/trap/hello.ts.trap | 162 +++--- 7 files changed, 843 insertions(+), 945 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 2856aa86c96..93850e595af 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -596,7 +596,7 @@ public class ASTExtractor { offsets.set(0, 1); // skip the initial '/' SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getRaw()).offsetBy(0, offsets), startPos); regexpExtractor.extract(source.substring(1, source.lastIndexOf('/')), sourceMap, nd, false); - } else if (nd.isStringLiteral() && !c.isInsideType() && nd.getRaw().length() < 1000) { + } else if (nd.isStringLiteral() && !c.isInsideType() && nd.getRaw().length() < 1000 && !c.isBinopOperand()) { SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getRaw()).offsetBy(0, makeStringLiteralOffsets(nd.getRaw())), startPos); regexpExtractor.extract(valueString, sourceMap, nd, true); diff --git a/javascript/extractor/tests/es2015/output/trap/properties.js.trap b/javascript/extractor/tests/es2015/output/trap/properties.js.trap index bcc637655b3..b59d331f28e 100644 --- a/javascript/extractor/tests/es2015/output/trap/properties.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/properties.js.trap @@ -287,150 +287,144 @@ enclosing_stmt(#20097,#20083) expr_containers(#20097,#20001) literals("prop","""prop""",#20097) #20098=* -regexpterm(#20098,14,#20097,0,"prop") -#20099=@"loc,{#10000},3,11,3,14" -locations_default(#20099,#10000,3,11,3,14) +exprs(#20098,13,#20095,1,"Math.random()") +#20099=@"loc,{#10000},3,19,3,31" +locations_default(#20099,#10000,3,19,3,31) hasLocation(#20098,#20099) -regexp_const_value(#20098,"prop") +enclosing_stmt(#20098,#20083) +expr_containers(#20098,#20001) #20100=* -exprs(#20100,13,#20095,1,"Math.random()") -#20101=@"loc,{#10000},3,19,3,31" -locations_default(#20101,#10000,3,19,3,31) +exprs(#20100,14,#20098,-1,"Math.random") +#20101=@"loc,{#10000},3,19,3,29" +locations_default(#20101,#10000,3,19,3,29) hasLocation(#20100,#20101) enclosing_stmt(#20100,#20083) expr_containers(#20100,#20001) #20102=* -exprs(#20102,14,#20100,-1,"Math.random") -#20103=@"loc,{#10000},3,19,3,29" -locations_default(#20103,#10000,3,19,3,29) -hasLocation(#20102,#20103) +exprs(#20102,79,#20100,0,"Math") +hasLocation(#20102,#20037) enclosing_stmt(#20102,#20083) expr_containers(#20102,#20001) +literals("Math","Math",#20102) +#20103=@"var;{Math};{#20000}" +variables(#20103,"Math",#20000) +bind(#20102,#20103) #20104=* -exprs(#20104,79,#20102,0,"Math") -hasLocation(#20104,#20037) +exprs(#20104,0,#20100,1,"random") +hasLocation(#20104,#20041) enclosing_stmt(#20104,#20083) expr_containers(#20104,#20001) -literals("Math","Math",#20104) -#20105=@"var;{Math};{#20000}" -variables(#20105,"Math",#20000) -bind(#20104,#20105) +literals("random","random",#20104) +#20105=* +exprs(#20105,3,#20093,1,"23") +hasLocation(#20105,#20051) +enclosing_stmt(#20105,#20083) +expr_containers(#20105,#20001) +literals("23","23",#20105) +is_computed(#20093) #20106=* -exprs(#20106,0,#20102,1,"random") -hasLocation(#20106,#20041) -enclosing_stmt(#20106,#20083) -expr_containers(#20106,#20001) -literals("random","random",#20106) +properties(#20106,#20091,1,0,"x") +hasLocation(#20106,#20055) #20107=* -exprs(#20107,3,#20093,1,"23") -hasLocation(#20107,#20051) +exprs(#20107,0,#20106,0,"x") +hasLocation(#20107,#20055) enclosing_stmt(#20107,#20083) expr_containers(#20107,#20001) -literals("23","23",#20107) -is_computed(#20093) +literals("x","x",#20107) #20108=* -properties(#20108,#20091,1,0,"x") +exprs(#20108,79,#20106,1,"x") hasLocation(#20108,#20055) +enclosing_stmt(#20108,#20083) +expr_containers(#20108,#20001) +literals("x","x",#20108) +bind(#20108,#20081) #20109=* -exprs(#20109,0,#20108,0,"x") -hasLocation(#20109,#20055) -enclosing_stmt(#20109,#20083) -expr_containers(#20109,#20001) -literals("x","x",#20109) -#20110=* -exprs(#20110,79,#20108,1,"x") -hasLocation(#20110,#20055) -enclosing_stmt(#20110,#20083) -expr_containers(#20110,#20001) -literals("x","x",#20110) -bind(#20110,#20081) +properties(#20109,#20091,2,0,"m() { return 56; }") +#20110=@"loc,{#10000},5,9,5,26" +locations_default(#20110,#10000,5,9,5,26) +hasLocation(#20109,#20110) #20111=* -properties(#20111,#20091,2,0,"m() { return 56; }") -#20112=@"loc,{#10000},5,9,5,26" -locations_default(#20112,#10000,5,9,5,26) -hasLocation(#20111,#20112) -#20113=* -exprs(#20113,0,#20111,0,"m") -hasLocation(#20113,#20059) -enclosing_stmt(#20113,#20083) -expr_containers(#20113,#20001) -literals("m","m",#20113) +exprs(#20111,0,#20109,0,"m") +hasLocation(#20111,#20059) +enclosing_stmt(#20111,#20083) +expr_containers(#20111,#20001) +literals("m","m",#20111) +#20112=* +exprs(#20112,9,#20109,1,"() { return 56; }") +#20113=@"loc,{#10000},5,10,5,26" +locations_default(#20113,#10000,5,10,5,26) +hasLocation(#20112,#20113) +enclosing_stmt(#20112,#20083) +expr_containers(#20112,#20001) #20114=* -exprs(#20114,9,#20111,1,"() { return 56; }") -#20115=@"loc,{#10000},5,10,5,26" -locations_default(#20115,#10000,5,10,5,26) -hasLocation(#20114,#20115) -enclosing_stmt(#20114,#20083) -expr_containers(#20114,#20001) +scopes(#20114,1) +scopenodes(#20112,#20114) +scopenesting(#20114,#20000) +#20115=@"var;{arguments};{#20114}" +variables(#20115,"arguments",#20114) +is_arguments_object(#20115) #20116=* -scopes(#20116,1) -scopenodes(#20114,#20116) -scopenesting(#20116,#20000) -#20117=@"var;{arguments};{#20116}" -variables(#20117,"arguments",#20116) -is_arguments_object(#20117) +stmts(#20116,1,#20112,-2,"{ return 56; }") +#20117=@"loc,{#10000},5,13,5,26" +locations_default(#20117,#10000,5,13,5,26) +hasLocation(#20116,#20117) +stmt_containers(#20116,#20112) #20118=* -stmts(#20118,1,#20114,-2,"{ return 56; }") -#20119=@"loc,{#10000},5,13,5,26" -locations_default(#20119,#10000,5,13,5,26) +stmts(#20118,9,#20116,0,"return 56;") +#20119=@"loc,{#10000},5,15,5,24" +locations_default(#20119,#10000,5,15,5,24) hasLocation(#20118,#20119) -stmt_containers(#20118,#20114) +stmt_containers(#20118,#20112) #20120=* -stmts(#20120,9,#20118,0,"return 56;") -#20121=@"loc,{#10000},5,15,5,24" -locations_default(#20121,#10000,5,15,5,24) -hasLocation(#20120,#20121) -stmt_containers(#20120,#20114) -#20122=* -exprs(#20122,3,#20120,0,"56") -hasLocation(#20122,#20069) -enclosing_stmt(#20122,#20120) -expr_containers(#20122,#20114) -literals("56","56",#20122) -is_method(#20111) +exprs(#20120,3,#20118,0,"56") +hasLocation(#20120,#20069) +enclosing_stmt(#20120,#20118) +expr_containers(#20120,#20112) +literals("56","56",#20120) +is_method(#20109) +#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=* -entry_cfg_node(#20123,#20001) -#20124=@"loc,{#10000},1,1,1,0" -locations_default(#20124,#10000,1,1,1,0) -hasLocation(#20123,#20124) -#20125=* -exit_cfg_node(#20125,#20001) -hasLocation(#20125,#20079) +exit_cfg_node(#20123,#20001) +hasLocation(#20123,#20079) successor(#20083,#20086) successor(#20091,#20097) -successor(#20114,#20111) +successor(#20112,#20109) +#20124=* +entry_cfg_node(#20124,#20112) +#20125=@"loc,{#10000},5,10,5,9" +locations_default(#20125,#10000,5,10,5,9) +hasLocation(#20124,#20125) #20126=* -entry_cfg_node(#20126,#20114) -#20127=@"loc,{#10000},5,10,5,9" -locations_default(#20127,#10000,5,10,5,9) +exit_cfg_node(#20126,#20112) +#20127=@"loc,{#10000},5,27,5,26" +locations_default(#20127,#10000,5,27,5,26) hasLocation(#20126,#20127) -#20128=* -exit_cfg_node(#20128,#20114) -#20129=@"loc,{#10000},5,27,5,26" -locations_default(#20129,#10000,5,27,5,26) -hasLocation(#20128,#20129) -successor(#20118,#20122) -successor(#20122,#20120) -successor(#20120,#20128) -successor(#20126,#20118) -successor(#20113,#20114) -successor(#20111,#20088) -successor(#20110,#20108) -successor(#20109,#20110) -successor(#20108,#20113) -successor(#20107,#20093) -successor(#20106,#20102) -successor(#20104,#20106) -successor(#20102,#20100) -successor(#20100,#20095) -successor(#20097,#20104) -successor(#20095,#20107) -successor(#20093,#20109) +successor(#20116,#20120) +successor(#20120,#20118) +successor(#20118,#20126) +successor(#20124,#20116) +successor(#20111,#20112) +successor(#20109,#20088) +successor(#20108,#20106) +successor(#20107,#20108) +successor(#20106,#20111) +successor(#20105,#20093) +successor(#20104,#20100) +successor(#20102,#20104) +successor(#20100,#20098) +successor(#20098,#20095) +successor(#20097,#20102) +successor(#20095,#20105) +successor(#20093,#20107) successor(#20090,#20091) -successor(#20088,#20125) +successor(#20088,#20123) successor(#20087,#20084) successor(#20086,#20087) successor(#20084,#20090) -successor(#20123,#20083) +successor(#20121,#20083) numlines(#10000,6,6,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/es2015/output/trap/templates.js.trap b/javascript/extractor/tests/es2015/output/trap/templates.js.trap index 452ac61c6f5..0ec4736720a 100644 --- a/javascript/extractor/tests/es2015/output/trap/templates.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/templates.js.trap @@ -468,286 +468,280 @@ enclosing_stmt(#20172,#20168) expr_containers(#20172,#20157) literals("values: ","""values: """,#20172) #20173=* -regexpterm(#20173,14,#20172,0,"values: ") -#20174=@"loc,{#10000},2,11,2,18" -locations_default(#20174,#10000,2,11,2,18) +exprs(#20173,13,#20170,1,"values.join(', ')") +#20174=@"loc,{#10000},2,23,2,39" +locations_default(#20174,#10000,2,23,2,39) hasLocation(#20173,#20174) -regexp_const_value(#20173,"values: ") +enclosing_stmt(#20173,#20168) +expr_containers(#20173,#20157) #20175=* -exprs(#20175,13,#20170,1,"values.join(', ')") -#20176=@"loc,{#10000},2,23,2,39" -locations_default(#20176,#10000,2,23,2,39) +exprs(#20175,14,#20173,-1,"values.join") +#20176=@"loc,{#10000},2,23,2,33" +locations_default(#20176,#10000,2,23,2,33) hasLocation(#20175,#20176) enclosing_stmt(#20175,#20168) expr_containers(#20175,#20157) #20177=* -exprs(#20177,14,#20175,-1,"values.join") -#20178=@"loc,{#10000},2,23,2,33" -locations_default(#20178,#10000,2,23,2,33) -hasLocation(#20177,#20178) +exprs(#20177,79,#20175,0,"values") +hasLocation(#20177,#20043) enclosing_stmt(#20177,#20168) expr_containers(#20177,#20157) +literals("values","values",#20177) +bind(#20177,#20163) +#20178=* +exprs(#20178,0,#20175,1,"join") +hasLocation(#20178,#20047) +enclosing_stmt(#20178,#20168) +expr_containers(#20178,#20157) +literals("join","join",#20178) #20179=* -exprs(#20179,79,#20177,0,"values") -hasLocation(#20179,#20043) +exprs(#20179,4,#20173,0,"', '") +hasLocation(#20179,#20051) enclosing_stmt(#20179,#20168) expr_containers(#20179,#20157) -literals("values","values",#20179) -bind(#20179,#20163) +literals(", ","', '",#20179) #20180=* -exprs(#20180,0,#20177,1,"join") -hasLocation(#20180,#20047) -enclosing_stmt(#20180,#20168) -expr_containers(#20180,#20157) -literals("join","join",#20180) -#20181=* -exprs(#20181,4,#20175,0,"', '") -hasLocation(#20181,#20051) -enclosing_stmt(#20181,#20168) -expr_containers(#20181,#20157) -literals(", ","', '",#20181) +regexpterm(#20180,14,#20179,0,", ") +#20181=@"loc,{#10000},2,36,2,37" +locations_default(#20181,#10000,2,36,2,37) +hasLocation(#20180,#20181) +regexp_const_value(#20180,", ") #20182=* -regexpterm(#20182,14,#20181,0,", ") -#20183=@"loc,{#10000},2,36,2,37" -locations_default(#20183,#10000,2,36,2,37) -hasLocation(#20182,#20183) -regexp_const_value(#20182,", ") -#20184=* -stmts(#20184,18,#20001,1,"var x = 23;") -hasLocation(#20184,#20011) -stmt_containers(#20184,#20001) +stmts(#20182,18,#20001,1,"var x = 23;") +hasLocation(#20182,#20011) +stmt_containers(#20182,#20001) +#20183=* +exprs(#20183,64,#20182,0,"x = 23") +#20184=@"loc,{#10000},5,5,5,10" +locations_default(#20184,#10000,5,5,5,10) +hasLocation(#20183,#20184) +enclosing_stmt(#20183,#20182) +expr_containers(#20183,#20001) #20185=* -exprs(#20185,64,#20184,0,"x = 23") -#20186=@"loc,{#10000},5,5,5,10" -locations_default(#20186,#10000,5,5,5,10) -hasLocation(#20185,#20186) -enclosing_stmt(#20185,#20184) +exprs(#20185,78,#20183,0,"x") +hasLocation(#20185,#20060) +enclosing_stmt(#20185,#20182) expr_containers(#20185,#20001) +literals("x","x",#20185) +decl(#20185,#20155) +#20186=* +exprs(#20186,3,#20183,1,"23") +hasLocation(#20186,#20064) +enclosing_stmt(#20186,#20182) +expr_containers(#20186,#20001) +literals("23","23",#20186) #20187=* -exprs(#20187,78,#20185,0,"x") -hasLocation(#20187,#20060) -enclosing_stmt(#20187,#20184) -expr_containers(#20187,#20001) -literals("x","x",#20187) -decl(#20187,#20155) +stmts(#20187,18,#20001,2,"var y = 19;") +hasLocation(#20187,#20013) +stmt_containers(#20187,#20001) #20188=* -exprs(#20188,3,#20185,1,"23") -hasLocation(#20188,#20064) -enclosing_stmt(#20188,#20184) +exprs(#20188,64,#20187,0,"y = 19") +#20189=@"loc,{#10000},6,5,6,10" +locations_default(#20189,#10000,6,5,6,10) +hasLocation(#20188,#20189) +enclosing_stmt(#20188,#20187) expr_containers(#20188,#20001) -literals("23","23",#20188) -#20189=* -stmts(#20189,18,#20001,2,"var y = 19;") -hasLocation(#20189,#20013) -stmt_containers(#20189,#20001) #20190=* -exprs(#20190,64,#20189,0,"y = 19") -#20191=@"loc,{#10000},6,5,6,10" -locations_default(#20191,#10000,6,5,6,10) -hasLocation(#20190,#20191) -enclosing_stmt(#20190,#20189) +exprs(#20190,78,#20188,0,"y") +hasLocation(#20190,#20070) +enclosing_stmt(#20190,#20187) expr_containers(#20190,#20001) +literals("y","y",#20190) +decl(#20190,#20156) +#20191=* +exprs(#20191,3,#20188,1,"19") +hasLocation(#20191,#20074) +enclosing_stmt(#20191,#20187) +expr_containers(#20191,#20001) +literals("19","19",#20191) #20192=* -exprs(#20192,78,#20190,0,"y") -hasLocation(#20192,#20070) -enclosing_stmt(#20192,#20189) -expr_containers(#20192,#20001) -literals("y","y",#20192) -decl(#20192,#20156) +stmts(#20192,2,#20001,3,"`${x} + ... + y}`;") +hasLocation(#20192,#20015) +stmt_containers(#20192,#20001) #20193=* -exprs(#20193,3,#20190,1,"19") -hasLocation(#20193,#20074) -enclosing_stmt(#20193,#20189) +exprs(#20193,71,#20192,0,"`${x} + ... x + y}`") +#20194=@"loc,{#10000},7,1,7,24" +locations_default(#20194,#10000,7,1,7,24) +hasLocation(#20193,#20194) +enclosing_stmt(#20193,#20192) expr_containers(#20193,#20001) -literals("19","19",#20193) -#20194=* -stmts(#20194,2,#20001,3,"`${x} + ... + y}`;") -hasLocation(#20194,#20015) -stmt_containers(#20194,#20001) #20195=* -exprs(#20195,71,#20194,0,"`${x} + ... x + y}`") -#20196=@"loc,{#10000},7,1,7,24" -locations_default(#20196,#10000,7,1,7,24) -hasLocation(#20195,#20196) -enclosing_stmt(#20195,#20194) +exprs(#20195,79,#20193,0,"x") +hasLocation(#20195,#20084) +enclosing_stmt(#20195,#20192) expr_containers(#20195,#20001) +literals("x","x",#20195) +bind(#20195,#20155) +#20196=* +exprs(#20196,72,#20193,1," + ") +hasLocation(#20196,#20088) +enclosing_stmt(#20196,#20192) +expr_containers(#20196,#20001) +literals(" + "," + ",#20196) #20197=* -exprs(#20197,79,#20195,0,"x") -hasLocation(#20197,#20084) -enclosing_stmt(#20197,#20194) +exprs(#20197,79,#20193,2,"y") +hasLocation(#20197,#20092) +enclosing_stmt(#20197,#20192) expr_containers(#20197,#20001) -literals("x","x",#20197) -bind(#20197,#20155) +literals("y","y",#20197) +bind(#20197,#20156) #20198=* -exprs(#20198,72,#20195,1," + ") -hasLocation(#20198,#20088) -enclosing_stmt(#20198,#20194) +exprs(#20198,72,#20193,3," = ") +hasLocation(#20198,#20096) +enclosing_stmt(#20198,#20192) expr_containers(#20198,#20001) -literals(" + "," + ",#20198) +literals(" = "," = ",#20198) #20199=* -exprs(#20199,79,#20195,2,"y") -hasLocation(#20199,#20092) -enclosing_stmt(#20199,#20194) +exprs(#20199,34,#20193,4,"x + y") +#20200=@"loc,{#10000},7,18,7,22" +locations_default(#20200,#10000,7,18,7,22) +hasLocation(#20199,#20200) +enclosing_stmt(#20199,#20192) expr_containers(#20199,#20001) -literals("y","y",#20199) -bind(#20199,#20156) -#20200=* -exprs(#20200,72,#20195,3," = ") -hasLocation(#20200,#20096) -enclosing_stmt(#20200,#20194) -expr_containers(#20200,#20001) -literals(" = "," = ",#20200) #20201=* -exprs(#20201,34,#20195,4,"x + y") -#20202=@"loc,{#10000},7,18,7,22" -locations_default(#20202,#10000,7,18,7,22) -hasLocation(#20201,#20202) -enclosing_stmt(#20201,#20194) +exprs(#20201,79,#20199,0,"x") +hasLocation(#20201,#20100) +enclosing_stmt(#20201,#20192) expr_containers(#20201,#20001) +literals("x","x",#20201) +bind(#20201,#20155) +#20202=* +exprs(#20202,79,#20199,1,"y") +hasLocation(#20202,#20104) +enclosing_stmt(#20202,#20192) +expr_containers(#20202,#20001) +literals("y","y",#20202) +bind(#20202,#20156) #20203=* -exprs(#20203,79,#20201,0,"x") -hasLocation(#20203,#20100) -enclosing_stmt(#20203,#20194) -expr_containers(#20203,#20001) -literals("x","x",#20203) -bind(#20203,#20155) +stmts(#20203,2,#20001,4,"tag `${ ... + y}`;") +hasLocation(#20203,#20017) +stmt_containers(#20203,#20001) #20204=* -exprs(#20204,79,#20201,1,"y") -hasLocation(#20204,#20104) -enclosing_stmt(#20204,#20194) +exprs(#20204,70,#20203,0,"tag `${ ... x + y}`") +#20205=@"loc,{#10000},8,1,8,28" +locations_default(#20205,#10000,8,1,8,28) +hasLocation(#20204,#20205) +enclosing_stmt(#20204,#20203) expr_containers(#20204,#20001) -literals("y","y",#20204) -bind(#20204,#20156) -#20205=* -stmts(#20205,2,#20001,4,"tag `${ ... + y}`;") -hasLocation(#20205,#20017) -stmt_containers(#20205,#20001) #20206=* -exprs(#20206,70,#20205,0,"tag `${ ... x + y}`") -#20207=@"loc,{#10000},8,1,8,28" -locations_default(#20207,#10000,8,1,8,28) -hasLocation(#20206,#20207) -enclosing_stmt(#20206,#20205) +exprs(#20206,79,#20204,0,"tag") +hasLocation(#20206,#20114) +enclosing_stmt(#20206,#20203) expr_containers(#20206,#20001) -#20208=* -exprs(#20208,79,#20206,0,"tag") -hasLocation(#20208,#20114) -enclosing_stmt(#20208,#20205) -expr_containers(#20208,#20001) -literals("tag","tag",#20208) -bind(#20208,#20154) +literals("tag","tag",#20206) +bind(#20206,#20154) +#20207=* +exprs(#20207,71,#20204,1,"`${x} + ... x + y}`") +#20208=@"loc,{#10000},8,5,8,28" +locations_default(#20208,#10000,8,5,8,28) +hasLocation(#20207,#20208) +enclosing_stmt(#20207,#20203) +expr_containers(#20207,#20001) #20209=* -exprs(#20209,71,#20206,1,"`${x} + ... x + y}`") -#20210=@"loc,{#10000},8,5,8,28" -locations_default(#20210,#10000,8,5,8,28) -hasLocation(#20209,#20210) -enclosing_stmt(#20209,#20205) +exprs(#20209,79,#20207,0,"x") +hasLocation(#20209,#20122) +enclosing_stmt(#20209,#20203) expr_containers(#20209,#20001) +literals("x","x",#20209) +bind(#20209,#20155) +#20210=* +exprs(#20210,72,#20207,1," + ") +hasLocation(#20210,#20126) +enclosing_stmt(#20210,#20203) +expr_containers(#20210,#20001) +literals(" + "," + ",#20210) #20211=* -exprs(#20211,79,#20209,0,"x") -hasLocation(#20211,#20122) -enclosing_stmt(#20211,#20205) +exprs(#20211,79,#20207,2,"y") +hasLocation(#20211,#20130) +enclosing_stmt(#20211,#20203) expr_containers(#20211,#20001) -literals("x","x",#20211) -bind(#20211,#20155) +literals("y","y",#20211) +bind(#20211,#20156) #20212=* -exprs(#20212,72,#20209,1," + ") -hasLocation(#20212,#20126) -enclosing_stmt(#20212,#20205) +exprs(#20212,72,#20207,3," = ") +hasLocation(#20212,#20134) +enclosing_stmt(#20212,#20203) expr_containers(#20212,#20001) -literals(" + "," + ",#20212) +literals(" = "," = ",#20212) #20213=* -exprs(#20213,79,#20209,2,"y") -hasLocation(#20213,#20130) -enclosing_stmt(#20213,#20205) +exprs(#20213,34,#20207,4,"x + y") +#20214=@"loc,{#10000},8,22,8,26" +locations_default(#20214,#10000,8,22,8,26) +hasLocation(#20213,#20214) +enclosing_stmt(#20213,#20203) expr_containers(#20213,#20001) -literals("y","y",#20213) -bind(#20213,#20156) -#20214=* -exprs(#20214,72,#20209,3," = ") -hasLocation(#20214,#20134) -enclosing_stmt(#20214,#20205) -expr_containers(#20214,#20001) -literals(" = "," = ",#20214) #20215=* -exprs(#20215,34,#20209,4,"x + y") -#20216=@"loc,{#10000},8,22,8,26" -locations_default(#20216,#10000,8,22,8,26) -hasLocation(#20215,#20216) -enclosing_stmt(#20215,#20205) +exprs(#20215,79,#20213,0,"x") +hasLocation(#20215,#20138) +enclosing_stmt(#20215,#20203) expr_containers(#20215,#20001) +literals("x","x",#20215) +bind(#20215,#20155) +#20216=* +exprs(#20216,79,#20213,1,"y") +hasLocation(#20216,#20142) +enclosing_stmt(#20216,#20203) +expr_containers(#20216,#20001) +literals("y","y",#20216) +bind(#20216,#20156) #20217=* -exprs(#20217,79,#20215,0,"x") -hasLocation(#20217,#20138) -enclosing_stmt(#20217,#20205) -expr_containers(#20217,#20001) -literals("x","x",#20217) -bind(#20217,#20155) -#20218=* -exprs(#20218,79,#20215,1,"y") -hasLocation(#20218,#20142) -enclosing_stmt(#20218,#20205) -expr_containers(#20218,#20001) -literals("y","y",#20218) -bind(#20218,#20156) +entry_cfg_node(#20217,#20001) +#20218=@"loc,{#10000},1,1,1,0" +locations_default(#20218,#10000,1,1,1,0) +hasLocation(#20217,#20218) #20219=* -entry_cfg_node(#20219,#20001) -#20220=@"loc,{#10000},1,1,1,0" -locations_default(#20220,#10000,1,1,1,0) -hasLocation(#20219,#20220) -#20221=* -exit_cfg_node(#20221,#20001) -hasLocation(#20221,#20152) -successor(#20205,#20206) -successor(#20206,#20208) -successor(#20209,#20211) -successor(#20218,#20215) -successor(#20217,#20218) -successor(#20215,#20221) -successor(#20214,#20217) -successor(#20213,#20214) -successor(#20212,#20213) -successor(#20211,#20212) -successor(#20208,#20209) -successor(#20194,#20195) -successor(#20195,#20197) -successor(#20204,#20201) +exit_cfg_node(#20219,#20001) +hasLocation(#20219,#20152) successor(#20203,#20204) -successor(#20201,#20205) -successor(#20200,#20203) -successor(#20199,#20200) -successor(#20198,#20199) -successor(#20197,#20198) -successor(#20189,#20192) -successor(#20193,#20190) +successor(#20204,#20206) +successor(#20207,#20209) +successor(#20216,#20213) +successor(#20215,#20216) +successor(#20213,#20219) +successor(#20212,#20215) +successor(#20211,#20212) +successor(#20210,#20211) +successor(#20209,#20210) +successor(#20206,#20207) successor(#20192,#20193) -successor(#20190,#20194) -successor(#20184,#20187) -successor(#20188,#20185) -successor(#20187,#20188) -successor(#20185,#20189) -successor(#20157,#20184) -#20222=* -entry_cfg_node(#20222,#20157) -hasLocation(#20222,#20220) -#20223=* -exit_cfg_node(#20223,#20157) -#20224=@"loc,{#10000},3,2,3,1" -locations_default(#20224,#10000,3,2,3,1) -hasLocation(#20223,#20224) +successor(#20193,#20195) +successor(#20202,#20199) +successor(#20201,#20202) +successor(#20199,#20203) +successor(#20198,#20201) +successor(#20197,#20198) +successor(#20196,#20197) +successor(#20195,#20196) +successor(#20187,#20190) +successor(#20191,#20188) +successor(#20190,#20191) +successor(#20188,#20192) +successor(#20182,#20185) +successor(#20186,#20183) +successor(#20185,#20186) +successor(#20183,#20187) +successor(#20157,#20182) +#20220=* +entry_cfg_node(#20220,#20157) +hasLocation(#20220,#20218) +#20221=* +exit_cfg_node(#20221,#20157) +#20222=@"loc,{#10000},3,2,3,1" +locations_default(#20222,#10000,3,2,3,1) +hasLocation(#20221,#20222) successor(#20166,#20172) -successor(#20181,#20175) -successor(#20180,#20177) -successor(#20179,#20180) -successor(#20177,#20181) -successor(#20175,#20170) -successor(#20172,#20179) +successor(#20179,#20173) +successor(#20178,#20175) +successor(#20177,#20178) +successor(#20175,#20179) +successor(#20173,#20170) +successor(#20172,#20177) successor(#20170,#20168) -successor(#20168,#20223) +successor(#20168,#20221) successor(#20164,#20166) successor(#20162,#20164) -successor(#20222,#20162) +successor(#20220,#20162) successor(#20159,#20157) -successor(#20219,#20159) +successor(#20217,#20159) numlines(#10000,8,7,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/exprs/output/trap/binary.js.trap b/javascript/extractor/tests/exprs/output/trap/binary.js.trap index 0b29d03b73a..ef7f0d95e51 100644 --- a/javascript/extractor/tests/exprs/output/trap/binary.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/binary.js.trap @@ -685,118 +685,112 @@ enclosing_stmt(#20215,#20212) expr_containers(#20215,#20001) literals("prototype","'prototype'",#20215) #20216=* -regexpterm(#20216,14,#20215,0,"prototype") -#20217=@"loc,{#10000},12,2,12,10" -locations_default(#20217,#10000,12,2,12,10) -hasLocation(#20216,#20217) -regexp_const_value(#20216,"prototype") +exprs(#20216,79,#20213,1,"Object") +hasLocation(#20216,#20125) +enclosing_stmt(#20216,#20212) +expr_containers(#20216,#20001) +literals("Object","Object",#20216) +#20217=@"var;{Object};{#20000}" +variables(#20217,"Object",#20000) +bind(#20216,#20217) #20218=* -exprs(#20218,79,#20213,1,"Object") -hasLocation(#20218,#20125) -enclosing_stmt(#20218,#20212) -expr_containers(#20218,#20001) -literals("Object","Object",#20218) -#20219=@"var;{Object};{#20000}" -variables(#20219,"Object",#20000) -bind(#20218,#20219) -#20220=* -stmts(#20220,2,#20001,12,"[] instanceof Array;") -hasLocation(#20220,#20027) -stmt_containers(#20220,#20001) +stmts(#20218,2,#20001,12,"[] instanceof Array;") +hasLocation(#20218,#20027) +stmt_containers(#20218,#20001) +#20219=* +exprs(#20219,43,#20218,0,"[] instanceof Array") +#20220=@"loc,{#10000},13,1,13,19" +locations_default(#20220,#10000,13,1,13,19) +hasLocation(#20219,#20220) +enclosing_stmt(#20219,#20218) +expr_containers(#20219,#20001) #20221=* -exprs(#20221,43,#20220,0,"[] instanceof Array") -#20222=@"loc,{#10000},13,1,13,19" -locations_default(#20222,#10000,13,1,13,19) +exprs(#20221,7,#20219,0,"[]") +#20222=@"loc,{#10000},13,1,13,2" +locations_default(#20222,#10000,13,1,13,2) hasLocation(#20221,#20222) -enclosing_stmt(#20221,#20220) +enclosing_stmt(#20221,#20218) expr_containers(#20221,#20001) +array_size(#20221,0) #20223=* -exprs(#20223,7,#20221,0,"[]") -#20224=@"loc,{#10000},13,1,13,2" -locations_default(#20224,#10000,13,1,13,2) -hasLocation(#20223,#20224) -enclosing_stmt(#20223,#20220) +exprs(#20223,79,#20219,1,"Array") +hasLocation(#20223,#20135) +enclosing_stmt(#20223,#20218) expr_containers(#20223,#20001) -array_size(#20223,0) +literals("Array","Array",#20223) +#20224=@"var;{Array};{#20000}" +variables(#20224,"Array",#20000) +bind(#20223,#20224) #20225=* -exprs(#20225,79,#20221,1,"Array") -hasLocation(#20225,#20135) -enclosing_stmt(#20225,#20220) -expr_containers(#20225,#20001) -literals("Array","Array",#20225) -#20226=@"var;{Array};{#20000}" -variables(#20226,"Array",#20000) -bind(#20225,#20226) -#20227=* -stmts(#20227,2,#20001,13,"1 && 2;") -hasLocation(#20227,#20029) -stmt_containers(#20227,#20001) +stmts(#20225,2,#20001,13,"1 && 2;") +hasLocation(#20225,#20029) +stmt_containers(#20225,#20001) +#20226=* +exprs(#20226,44,#20225,0,"1 && 2") +#20227=@"loc,{#10000},14,1,14,6" +locations_default(#20227,#10000,14,1,14,6) +hasLocation(#20226,#20227) +enclosing_stmt(#20226,#20225) +expr_containers(#20226,#20001) #20228=* -exprs(#20228,44,#20227,0,"1 && 2") -#20229=@"loc,{#10000},14,1,14,6" -locations_default(#20229,#10000,14,1,14,6) -hasLocation(#20228,#20229) -enclosing_stmt(#20228,#20227) +exprs(#20228,3,#20226,0,"1") +hasLocation(#20228,#20139) +enclosing_stmt(#20228,#20225) expr_containers(#20228,#20001) +literals("1","1",#20228) +#20229=* +exprs(#20229,3,#20226,1,"2") +hasLocation(#20229,#20143) +enclosing_stmt(#20229,#20225) +expr_containers(#20229,#20001) +literals("2","2",#20229) #20230=* -exprs(#20230,3,#20228,0,"1") -hasLocation(#20230,#20139) -enclosing_stmt(#20230,#20227) -expr_containers(#20230,#20001) -literals("1","1",#20230) +stmts(#20230,2,#20001,14,"1 || 2;") +hasLocation(#20230,#20031) +stmt_containers(#20230,#20001) #20231=* -exprs(#20231,3,#20228,1,"2") -hasLocation(#20231,#20143) -enclosing_stmt(#20231,#20227) +exprs(#20231,45,#20230,0,"1 || 2") +#20232=@"loc,{#10000},15,1,15,6" +locations_default(#20232,#10000,15,1,15,6) +hasLocation(#20231,#20232) +enclosing_stmt(#20231,#20230) expr_containers(#20231,#20001) -literals("2","2",#20231) -#20232=* -stmts(#20232,2,#20001,14,"1 || 2;") -hasLocation(#20232,#20031) -stmt_containers(#20232,#20001) #20233=* -exprs(#20233,45,#20232,0,"1 || 2") -#20234=@"loc,{#10000},15,1,15,6" -locations_default(#20234,#10000,15,1,15,6) -hasLocation(#20233,#20234) -enclosing_stmt(#20233,#20232) +exprs(#20233,3,#20231,0,"1") +hasLocation(#20233,#20147) +enclosing_stmt(#20233,#20230) expr_containers(#20233,#20001) +literals("1","1",#20233) +#20234=* +exprs(#20234,3,#20231,1,"2") +hasLocation(#20234,#20151) +enclosing_stmt(#20234,#20230) +expr_containers(#20234,#20001) +literals("2","2",#20234) #20235=* -exprs(#20235,3,#20233,0,"1") -hasLocation(#20235,#20147) -enclosing_stmt(#20235,#20232) -expr_containers(#20235,#20001) -literals("1","1",#20235) -#20236=* -exprs(#20236,3,#20233,1,"2") -hasLocation(#20236,#20151) -enclosing_stmt(#20236,#20232) -expr_containers(#20236,#20001) -literals("2","2",#20236) +entry_cfg_node(#20235,#20001) +#20236=@"loc,{#10000},1,1,1,0" +locations_default(#20236,#10000,1,1,1,0) +hasLocation(#20235,#20236) #20237=* -entry_cfg_node(#20237,#20001) -#20238=@"loc,{#10000},1,1,1,0" -locations_default(#20238,#10000,1,1,1,0) -hasLocation(#20237,#20238) -#20239=* -exit_cfg_node(#20239,#20001) -hasLocation(#20239,#20155) -successor(#20232,#20233) -successor(#20233,#20235) -successor(#20235,#20239) -successor(#20236,#20239) -successor(#20227,#20228) -successor(#20228,#20230) +exit_cfg_node(#20237,#20001) +hasLocation(#20237,#20155) successor(#20230,#20231) -successor(#20231,#20232) -successor(#20220,#20223) -successor(#20225,#20221) -successor(#20223,#20225) -successor(#20221,#20227) +successor(#20231,#20233) +successor(#20233,#20237) +successor(#20234,#20237) +successor(#20225,#20226) +successor(#20226,#20228) +successor(#20228,#20229) +successor(#20229,#20230) +successor(#20218,#20221) +successor(#20223,#20219) +successor(#20221,#20223) +successor(#20219,#20225) successor(#20212,#20215) -successor(#20218,#20213) -successor(#20215,#20218) -successor(#20213,#20220) +successor(#20216,#20213) +successor(#20215,#20216) +successor(#20213,#20218) successor(#20207,#20210) successor(#20211,#20208) successor(#20210,#20211) @@ -841,6 +835,6 @@ successor(#20157,#20160) successor(#20161,#20158) successor(#20160,#20161) successor(#20158,#20162) -successor(#20237,#20157) +successor(#20235,#20157) numlines(#10000,15,15,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/jsx/output/trap/tst.js.trap b/javascript/extractor/tests/jsx/output/trap/tst.js.trap index 9ae7c3b06a1..2a2bfa4689f 100644 --- a/javascript/extractor/tests/jsx/output/trap/tst.js.trap +++ b/javascript/extractor/tests/jsx/output/trap/tst.js.trap @@ -571,194 +571,182 @@ enclosing_stmt(#20199,#20181) expr_containers(#20199,#20001) literals("a","""a""",#20199) #20200=* -regexpterm(#20200,14,#20199,0,"a") -#20201=@"loc,{#10000},3,22,3,22" -locations_default(#20201,#10000,3,22,3,22) -hasLocation(#20200,#20201) -regexp_const_value(#20200,"a") -#20202=* -exprs(#20202,4,#20197,1,"""b""") -hasLocation(#20202,#20067) -enclosing_stmt(#20202,#20181) -expr_containers(#20202,#20001) -literals("b","""b""",#20202) +exprs(#20200,4,#20197,1,"""b""") +hasLocation(#20200,#20067) +enclosing_stmt(#20200,#20181) +expr_containers(#20200,#20001) +literals("b","""b""",#20200) +#20201=* +regexpterm(#20201,14,#20197,0,"ab") +#20202=@"loc,{#10000},3,22,3,26" +locations_default(#20202,#10000,3,22,3,26) +hasLocation(#20201,#20202) +regexp_const_value(#20201,"ab") #20203=* -regexpterm(#20203,14,#20202,0,"b") -#20204=@"loc,{#10000},3,26,3,26" -locations_default(#20204,#10000,3,26,3,26) -hasLocation(#20203,#20204) -regexp_const_value(#20203,"b") +exprs(#20203,79,#20182,-2,"j") +hasLocation(#20203,#20075) +enclosing_stmt(#20203,#20181) +expr_containers(#20203,#20001) +literals("j","j",#20203) +#20204=@"var;{j};{#20000}" +variables(#20204,"j",#20000) +bind(#20203,#20204) #20205=* -regexpterm(#20205,14,#20197,0,"ab") -#20206=@"loc,{#10000},3,22,3,26" -locations_default(#20206,#10000,3,22,3,26) +exprs(#20205,89,#20182,-3,"") +#20206=@"loc,{#10000},3,33,3,47" +locations_default(#20206,#10000,3,33,3,47) hasLocation(#20205,#20206) -regexp_const_value(#20205,"ab") +enclosing_stmt(#20205,#20181) +expr_containers(#20205,#20001) #20207=* -exprs(#20207,79,#20182,-2,"j") -hasLocation(#20207,#20075) +exprs(#20207,14,#20205,-1,"k.l") +#20208=@"loc,{#10000},3,34,3,36" +locations_default(#20208,#10000,3,34,3,36) +hasLocation(#20207,#20208) enclosing_stmt(#20207,#20181) expr_containers(#20207,#20001) -literals("j","j",#20207) -#20208=@"var;{j};{#20000}" -variables(#20208,"j",#20000) -bind(#20207,#20208) #20209=* -exprs(#20209,89,#20182,-3,"") -#20210=@"loc,{#10000},3,33,3,47" -locations_default(#20210,#10000,3,33,3,47) -hasLocation(#20209,#20210) +exprs(#20209,79,#20207,0,"k") +hasLocation(#20209,#20081) enclosing_stmt(#20209,#20181) expr_containers(#20209,#20001) +literals("k","k",#20209) +#20210=@"var;{k};{#20000}" +variables(#20210,"k",#20000) +bind(#20209,#20210) #20211=* -exprs(#20211,14,#20209,-1,"k.l") -#20212=@"loc,{#10000},3,34,3,36" -locations_default(#20212,#10000,3,34,3,36) -hasLocation(#20211,#20212) +exprs(#20211,0,#20207,1,"l") +hasLocation(#20211,#20085) enclosing_stmt(#20211,#20181) expr_containers(#20211,#20001) -#20213=* -exprs(#20213,79,#20211,0,"k") -hasLocation(#20213,#20081) -enclosing_stmt(#20213,#20181) -expr_containers(#20213,#20001) -literals("k","k",#20213) -#20214=@"var;{k};{#20000}" -variables(#20214,"k",#20000) -bind(#20213,#20214) -#20215=* -exprs(#20215,0,#20211,1,"l") -hasLocation(#20215,#20085) -enclosing_stmt(#20215,#20181) -expr_containers(#20215,#20001) -literals("l","l",#20215) +literals("l","l",#20211) +#20212=* +exprs(#20212,89,#20205,-2,"") +#20213=@"loc,{#10000},3,38,3,41" +locations_default(#20213,#10000,3,38,3,41) +hasLocation(#20212,#20213) +enclosing_stmt(#20212,#20181) +expr_containers(#20212,#20001) +#20214=* +exprs(#20214,79,#20212,-1,"M") +hasLocation(#20214,#20091) +enclosing_stmt(#20214,#20181) +expr_containers(#20214,#20001) +literals("M","M",#20214) +#20215=@"var;{M};{#20000}" +variables(#20215,"M",#20000) +bind(#20214,#20215) #20216=* -exprs(#20216,89,#20209,-2,"") -#20217=@"loc,{#10000},3,38,3,41" -locations_default(#20217,#10000,3,38,3,41) -hasLocation(#20216,#20217) -enclosing_stmt(#20216,#20181) -expr_containers(#20216,#20001) -#20218=* -exprs(#20218,79,#20216,-1,"M") -hasLocation(#20218,#20091) -enclosing_stmt(#20218,#20181) -expr_containers(#20218,#20001) -literals("M","M",#20218) -#20219=@"var;{M};{#20000}" -variables(#20219,"M",#20000) -bind(#20218,#20219) +stmts(#20216,2,#20001,3,";") +hasLocation(#20216,#20009) +stmt_containers(#20216,#20001) +#20217=* +exprs(#20217,89,#20216,0,"") +#20218=@"loc,{#10000},4,1,4,15" +locations_default(#20218,#10000,4,1,4,15) +hasLocation(#20217,#20218) +enclosing_stmt(#20217,#20216) +expr_containers(#20217,#20001) +#20219=* +exprs(#20219,0,#20217,-1,"n") +hasLocation(#20219,#20121) +enclosing_stmt(#20219,#20216) +expr_containers(#20219,#20001) +literals("n","n",#20219) #20220=* -stmts(#20220,2,#20001,3,";") -hasLocation(#20220,#20009) -stmt_containers(#20220,#20001) -#20221=* -exprs(#20221,89,#20220,0,"") -#20222=@"loc,{#10000},4,1,4,15" -locations_default(#20222,#10000,4,1,4,15) -hasLocation(#20221,#20222) -enclosing_stmt(#20221,#20220) -expr_containers(#20221,#20001) +properties(#20220,#20217,0,3,"{...props}") +#20221=@"loc,{#10000},4,4,4,13" +locations_default(#20221,#10000,4,4,4,13) +hasLocation(#20220,#20221) +#20222=* +exprs(#20222,66,#20220,1,"...props") +hasLocation(#20222,#20221) +enclosing_stmt(#20222,#20216) +expr_containers(#20222,#20001) #20223=* -exprs(#20223,0,#20221,-1,"n") -hasLocation(#20223,#20121) -enclosing_stmt(#20223,#20220) +exprs(#20223,79,#20222,0,"props") +hasLocation(#20223,#20127) +enclosing_stmt(#20223,#20216) expr_containers(#20223,#20001) -literals("n","n",#20223) -#20224=* -properties(#20224,#20221,0,3,"{...props}") -#20225=@"loc,{#10000},4,4,4,13" -locations_default(#20225,#10000,4,4,4,13) -hasLocation(#20224,#20225) +literals("props","props",#20223) +#20224=@"var;{props};{#20000}" +variables(#20224,"props",#20000) +bind(#20223,#20224) +#20225=* +stmts(#20225,2,#20001,4,"<>") +hasLocation(#20225,#20011) +stmt_containers(#20225,#20001) #20226=* -exprs(#20226,66,#20224,1,"...props") -hasLocation(#20226,#20225) -enclosing_stmt(#20226,#20220) +exprs(#20226,89,#20225,0,"<>") +hasLocation(#20226,#20011) +enclosing_stmt(#20226,#20225) expr_containers(#20226,#20001) #20227=* -exprs(#20227,79,#20226,0,"props") -hasLocation(#20227,#20127) -enclosing_stmt(#20227,#20220) +exprs(#20227,89,#20226,-2,"") +#20228=@"loc,{#10000},5,3,5,6" +locations_default(#20228,#10000,5,3,5,6) +hasLocation(#20227,#20228) +enclosing_stmt(#20227,#20225) expr_containers(#20227,#20001) -literals("props","props",#20227) -#20228=@"var;{props};{#20000}" -variables(#20228,"props",#20000) -bind(#20227,#20228) #20229=* -stmts(#20229,2,#20001,4,"<>") -hasLocation(#20229,#20011) -stmt_containers(#20229,#20001) +exprs(#20229,0,#20227,-1,"a") +hasLocation(#20229,#20143) +enclosing_stmt(#20229,#20225) +expr_containers(#20229,#20001) +literals("a","a",#20229) #20230=* -exprs(#20230,89,#20229,0,"<>") -hasLocation(#20230,#20011) -enclosing_stmt(#20230,#20229) +exprs(#20230,89,#20226,-3,"") +#20231=@"loc,{#10000},5,7,5,10" +locations_default(#20231,#10000,5,7,5,10) +hasLocation(#20230,#20231) +enclosing_stmt(#20230,#20225) expr_containers(#20230,#20001) -#20231=* -exprs(#20231,89,#20230,-2,"") -#20232=@"loc,{#10000},5,3,5,6" -locations_default(#20232,#10000,5,3,5,6) -hasLocation(#20231,#20232) -enclosing_stmt(#20231,#20229) -expr_containers(#20231,#20001) +#20232=* +exprs(#20232,0,#20230,-1,"b") +hasLocation(#20232,#20151) +enclosing_stmt(#20232,#20225) +expr_containers(#20232,#20001) +literals("b","b",#20232) #20233=* -exprs(#20233,0,#20231,-1,"a") -hasLocation(#20233,#20143) -enclosing_stmt(#20233,#20229) -expr_containers(#20233,#20001) -literals("a","a",#20233) -#20234=* -exprs(#20234,89,#20230,-3,"") -#20235=@"loc,{#10000},5,7,5,10" -locations_default(#20235,#10000,5,7,5,10) -hasLocation(#20234,#20235) -enclosing_stmt(#20234,#20229) -expr_containers(#20234,#20001) -#20236=* -exprs(#20236,0,#20234,-1,"b") -hasLocation(#20236,#20151) -enclosing_stmt(#20236,#20229) -expr_containers(#20236,#20001) -literals("b","b",#20236) -#20237=* -entry_cfg_node(#20237,#20001) -#20238=@"loc,{#10000},1,1,1,0" -locations_default(#20238,#10000,1,1,1,0) -hasLocation(#20237,#20238) -#20239=* -exit_cfg_node(#20239,#20001) -hasLocation(#20239,#20163) -successor(#20229,#20233) -successor(#20236,#20234) -successor(#20234,#20230) -successor(#20233,#20231) -successor(#20231,#20236) -successor(#20230,#20239) -successor(#20220,#20223) -successor(#20227,#20226) -successor(#20226,#20224) -successor(#20224,#20221) -successor(#20223,#20227) -successor(#20221,#20229) +entry_cfg_node(#20233,#20001) +#20234=@"loc,{#10000},1,1,1,0" +locations_default(#20234,#10000,1,1,1,0) +hasLocation(#20233,#20234) +#20235=* +exit_cfg_node(#20235,#20001) +hasLocation(#20235,#20163) +successor(#20225,#20229) +successor(#20232,#20230) +successor(#20230,#20226) +successor(#20229,#20227) +successor(#20227,#20232) +successor(#20226,#20235) +successor(#20216,#20219) +successor(#20223,#20222) +successor(#20222,#20220) +successor(#20220,#20217) +successor(#20219,#20223) +successor(#20217,#20225) successor(#20181,#20184) -successor(#20218,#20216) -successor(#20216,#20209) -successor(#20215,#20211) -successor(#20213,#20215) -successor(#20211,#20218) -successor(#20209,#20182) -successor(#20207,#20213) -successor(#20202,#20197) -successor(#20199,#20202) +successor(#20214,#20212) +successor(#20212,#20205) +successor(#20211,#20207) +successor(#20209,#20211) +successor(#20207,#20214) +successor(#20205,#20182) +successor(#20203,#20209) +successor(#20200,#20197) +successor(#20199,#20200) successor(#20197,#20194) successor(#20196,#20199) -successor(#20194,#20207) +successor(#20194,#20203) successor(#20191,#20185) successor(#20190,#20187) successor(#20189,#20190) successor(#20187,#20191) successor(#20185,#20196) successor(#20184,#20189) -successor(#20182,#20220) +successor(#20182,#20216) successor(#20169,#20174) successor(#20180,#20178) successor(#20179,#20180) @@ -771,6 +759,6 @@ successor(#20170,#20181) successor(#20165,#20168) successor(#20168,#20166) successor(#20166,#20169) -successor(#20237,#20165) +successor(#20233,#20165) numlines(#10000,5,5,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/regexp/output/trap/multipart.js.trap b/javascript/extractor/tests/regexp/output/trap/multipart.js.trap index b8b165ddf5b..2c85cf4e70d 100644 --- a/javascript/extractor/tests/regexp/output/trap/multipart.js.trap +++ b/javascript/extractor/tests/regexp/output/trap/multipart.js.trap @@ -404,324 +404,264 @@ enclosing_stmt(#20143,#20133) expr_containers(#20143,#20001) literals("foo","""foo""",#20143) #20144=* -regexpterm(#20144,14,#20143,0,"foo") -#20145=@"loc,{#10000},1,23,1,25" -locations_default(#20145,#10000,1,23,1,25) -hasLocation(#20144,#20145) -regexp_const_value(#20144,"foo") -#20146=* -exprs(#20146,4,#20141,1,"""bar""") -hasLocation(#20146,#20047) -enclosing_stmt(#20146,#20133) -expr_containers(#20146,#20001) -literals("bar","""bar""",#20146) +exprs(#20144,4,#20141,1,"""bar""") +hasLocation(#20144,#20047) +enclosing_stmt(#20144,#20133) +expr_containers(#20144,#20001) +literals("bar","""bar""",#20144) +#20145=* +regexpterm(#20145,14,#20141,0,"foobar") +#20146=@"loc,{#10000},1,23,1,33" +locations_default(#20146,#10000,1,23,1,33) +hasLocation(#20145,#20146) +regexp_const_value(#20145,"foobar") #20147=* -regexpterm(#20147,14,#20146,0,"bar") -#20148=@"loc,{#10000},1,31,1,33" -locations_default(#20148,#10000,1,31,1,33) +stmts(#20147,18,#20001,1,"var reg ... ""bar"");") +#20148=@"loc,{#10000},3,1,4,13" +locations_default(#20148,#10000,3,1,4,13) hasLocation(#20147,#20148) -regexp_const_value(#20147,"bar") +stmt_containers(#20147,#20001) #20149=* -regexpterm(#20149,14,#20141,0,"foobar") -#20150=@"loc,{#10000},1,23,1,33" -locations_default(#20150,#10000,1,23,1,33) +exprs(#20149,64,#20147,0,"reg2 = ... ""bar"")") +#20150=@"loc,{#10000},3,5,4,12" +locations_default(#20150,#10000,3,5,4,12) hasLocation(#20149,#20150) -regexp_const_value(#20149,"foobar") +enclosing_stmt(#20149,#20147) +expr_containers(#20149,#20001) #20151=* -stmts(#20151,18,#20001,1,"var reg ... ""bar"");") -#20152=@"loc,{#10000},3,1,4,13" -locations_default(#20152,#10000,3,1,4,13) -hasLocation(#20151,#20152) -stmt_containers(#20151,#20001) -#20153=* -exprs(#20153,64,#20151,0,"reg2 = ... ""bar"")") -#20154=@"loc,{#10000},3,5,4,12" -locations_default(#20154,#10000,3,5,4,12) -hasLocation(#20153,#20154) -enclosing_stmt(#20153,#20151) -expr_containers(#20153,#20001) +exprs(#20151,78,#20149,0,"reg2") +hasLocation(#20151,#20055) +enclosing_stmt(#20151,#20147) +expr_containers(#20151,#20001) +literals("reg2","reg2",#20151) +decl(#20151,#20130) +#20152=* +exprs(#20152,12,#20149,1,"new Reg ... ""bar"")") +#20153=@"loc,{#10000},3,12,4,12" +locations_default(#20153,#10000,3,12,4,12) +hasLocation(#20152,#20153) +enclosing_stmt(#20152,#20147) +expr_containers(#20152,#20001) +#20154=* +exprs(#20154,79,#20152,-1,"RegExp") +hasLocation(#20154,#20061) +enclosing_stmt(#20154,#20147) +expr_containers(#20154,#20001) +literals("RegExp","RegExp",#20154) +bind(#20154,#20140) #20155=* -exprs(#20155,78,#20153,0,"reg2") -hasLocation(#20155,#20055) -enclosing_stmt(#20155,#20151) +exprs(#20155,34,#20152,0,"""foo""\n + ""bar""") +#20156=@"loc,{#10000},3,23,4,11" +locations_default(#20156,#10000,3,23,4,11) +hasLocation(#20155,#20156) +enclosing_stmt(#20155,#20147) expr_containers(#20155,#20001) -literals("reg2","reg2",#20155) -decl(#20155,#20130) -#20156=* -exprs(#20156,12,#20153,1,"new Reg ... ""bar"")") -#20157=@"loc,{#10000},3,12,4,12" -locations_default(#20157,#10000,3,12,4,12) -hasLocation(#20156,#20157) -enclosing_stmt(#20156,#20151) -expr_containers(#20156,#20001) +#20157=* +exprs(#20157,4,#20155,0,"""foo""") +hasLocation(#20157,#20065) +enclosing_stmt(#20157,#20147) +expr_containers(#20157,#20001) +literals("foo","""foo""",#20157) #20158=* -exprs(#20158,79,#20156,-1,"RegExp") -hasLocation(#20158,#20061) -enclosing_stmt(#20158,#20151) +exprs(#20158,4,#20155,1,"""bar""") +hasLocation(#20158,#20069) +enclosing_stmt(#20158,#20147) expr_containers(#20158,#20001) -literals("RegExp","RegExp",#20158) -bind(#20158,#20140) +literals("bar","""bar""",#20158) #20159=* -exprs(#20159,34,#20156,0,"""foo""\n + ""bar""") -#20160=@"loc,{#10000},3,23,4,11" -locations_default(#20160,#10000,3,23,4,11) +regexpterm(#20159,14,#20155,0,"foobar") +#20160=@"loc,{#10000},3,24,4,11" +locations_default(#20160,#10000,3,24,4,11) hasLocation(#20159,#20160) -enclosing_stmt(#20159,#20151) -expr_containers(#20159,#20001) +regexp_const_value(#20159,"foobar") #20161=* -exprs(#20161,4,#20159,0,"""foo""") -hasLocation(#20161,#20065) -enclosing_stmt(#20161,#20151) -expr_containers(#20161,#20001) -literals("foo","""foo""",#20161) -#20162=* -regexpterm(#20162,14,#20161,0,"foo") -#20163=@"loc,{#10000},3,24,3,26" -locations_default(#20163,#10000,3,24,3,26) -hasLocation(#20162,#20163) -regexp_const_value(#20162,"foo") -#20164=* -exprs(#20164,4,#20159,1,"""bar""") -hasLocation(#20164,#20069) -enclosing_stmt(#20164,#20151) -expr_containers(#20164,#20001) -literals("bar","""bar""",#20164) +stmts(#20161,18,#20001,2,"var reg ... ""bar"");") +#20162=@"loc,{#10000},6,1,7,19" +locations_default(#20162,#10000,6,1,7,19) +hasLocation(#20161,#20162) +stmt_containers(#20161,#20001) +#20163=* +exprs(#20163,64,#20161,0,"reg3 = ... ""bar"")") +#20164=@"loc,{#10000},6,5,7,18" +locations_default(#20164,#10000,6,5,7,18) +hasLocation(#20163,#20164) +enclosing_stmt(#20163,#20161) +expr_containers(#20163,#20001) #20165=* -regexpterm(#20165,14,#20164,0,"bar") -#20166=@"loc,{#10000},4,8,4,10" -locations_default(#20166,#10000,4,8,4,10) -hasLocation(#20165,#20166) -regexp_const_value(#20165,"bar") -#20167=* -regexpterm(#20167,14,#20159,0,"foobar") -#20168=@"loc,{#10000},3,24,4,11" -locations_default(#20168,#10000,3,24,4,11) -hasLocation(#20167,#20168) -regexp_const_value(#20167,"foobar") +exprs(#20165,78,#20163,0,"reg3") +hasLocation(#20165,#20077) +enclosing_stmt(#20165,#20161) +expr_containers(#20165,#20001) +literals("reg3","reg3",#20165) +decl(#20165,#20131) +#20166=* +exprs(#20166,12,#20163,1,"new Reg ... ""bar"")") +#20167=@"loc,{#10000},6,12,7,18" +locations_default(#20167,#10000,6,12,7,18) +hasLocation(#20166,#20167) +enclosing_stmt(#20166,#20161) +expr_containers(#20166,#20001) +#20168=* +exprs(#20168,79,#20166,-1,"RegExp") +hasLocation(#20168,#20083) +enclosing_stmt(#20168,#20161) +expr_containers(#20168,#20001) +literals("RegExp","RegExp",#20168) +bind(#20168,#20140) #20169=* -stmts(#20169,18,#20001,2,"var reg ... ""bar"");") -#20170=@"loc,{#10000},6,1,7,19" -locations_default(#20170,#10000,6,1,7,19) +exprs(#20169,34,#20166,0,"""foo"" + ""bar""") +#20170=@"loc,{#10000},7,5,7,17" +locations_default(#20170,#10000,7,5,7,17) hasLocation(#20169,#20170) -stmt_containers(#20169,#20001) +enclosing_stmt(#20169,#20161) +expr_containers(#20169,#20001) #20171=* -exprs(#20171,64,#20169,0,"reg3 = ... ""bar"")") -#20172=@"loc,{#10000},6,5,7,18" -locations_default(#20172,#10000,6,5,7,18) -hasLocation(#20171,#20172) -enclosing_stmt(#20171,#20169) +exprs(#20171,4,#20169,0,"""foo""") +hasLocation(#20171,#20087) +enclosing_stmt(#20171,#20161) expr_containers(#20171,#20001) +literals("foo","""foo""",#20171) +#20172=* +exprs(#20172,4,#20169,1,"""bar""") +hasLocation(#20172,#20091) +enclosing_stmt(#20172,#20161) +expr_containers(#20172,#20001) +literals("bar","""bar""",#20172) #20173=* -exprs(#20173,78,#20171,0,"reg3") -hasLocation(#20173,#20077) -enclosing_stmt(#20173,#20169) -expr_containers(#20173,#20001) -literals("reg3","reg3",#20173) -decl(#20173,#20131) -#20174=* -exprs(#20174,12,#20171,1,"new Reg ... ""bar"")") -#20175=@"loc,{#10000},6,12,7,18" -locations_default(#20175,#10000,6,12,7,18) -hasLocation(#20174,#20175) -enclosing_stmt(#20174,#20169) -expr_containers(#20174,#20001) -#20176=* -exprs(#20176,79,#20174,-1,"RegExp") -hasLocation(#20176,#20083) -enclosing_stmt(#20176,#20169) -expr_containers(#20176,#20001) -literals("RegExp","RegExp",#20176) -bind(#20176,#20140) +regexpterm(#20173,14,#20169,0,"foobar") +#20174=@"loc,{#10000},7,6,7,16" +locations_default(#20174,#10000,7,6,7,16) +hasLocation(#20173,#20174) +regexp_const_value(#20173,"foobar") +#20175=* +stmts(#20175,18,#20001,3,"var reg ... qux""\n);") +#20176=@"loc,{#10000},9,1,14,2" +locations_default(#20176,#10000,9,1,14,2) +hasLocation(#20175,#20176) +stmt_containers(#20175,#20001) #20177=* -exprs(#20177,34,#20174,0,"""foo"" + ""bar""") -#20178=@"loc,{#10000},7,5,7,17" -locations_default(#20178,#10000,7,5,7,17) +exprs(#20177,64,#20175,0,"reg4 = ... ""qux""\n)") +#20178=@"loc,{#10000},9,5,14,1" +locations_default(#20178,#10000,9,5,14,1) hasLocation(#20177,#20178) -enclosing_stmt(#20177,#20169) +enclosing_stmt(#20177,#20175) expr_containers(#20177,#20001) #20179=* -exprs(#20179,4,#20177,0,"""foo""") -hasLocation(#20179,#20087) -enclosing_stmt(#20179,#20169) +exprs(#20179,78,#20177,0,"reg4") +hasLocation(#20179,#20099) +enclosing_stmt(#20179,#20175) expr_containers(#20179,#20001) -literals("foo","""foo""",#20179) +literals("reg4","reg4",#20179) +decl(#20179,#20132) #20180=* -regexpterm(#20180,14,#20179,0,"foo") -#20181=@"loc,{#10000},7,6,7,8" -locations_default(#20181,#10000,7,6,7,8) +exprs(#20180,12,#20177,1,"new Reg ... ""qux""\n)") +#20181=@"loc,{#10000},9,12,14,1" +locations_default(#20181,#10000,9,12,14,1) hasLocation(#20180,#20181) -regexp_const_value(#20180,"foo") +enclosing_stmt(#20180,#20175) +expr_containers(#20180,#20001) #20182=* -exprs(#20182,4,#20177,1,"""bar""") -hasLocation(#20182,#20091) -enclosing_stmt(#20182,#20169) +exprs(#20182,79,#20180,-1,"RegExp") +hasLocation(#20182,#20105) +enclosing_stmt(#20182,#20175) expr_containers(#20182,#20001) -literals("bar","""bar""",#20182) +literals("RegExp","RegExp",#20182) +bind(#20182,#20140) #20183=* -regexpterm(#20183,14,#20182,0,"bar") -#20184=@"loc,{#10000},7,14,7,16" -locations_default(#20184,#10000,7,14,7,16) +exprs(#20183,34,#20180,0,"""foo"" + ... ""qux""") +#20184=@"loc,{#10000},10,5,13,9" +locations_default(#20184,#10000,10,5,13,9) hasLocation(#20183,#20184) -regexp_const_value(#20183,"bar") +enclosing_stmt(#20183,#20175) +expr_containers(#20183,#20001) #20185=* -regexpterm(#20185,14,#20177,0,"foobar") -#20186=@"loc,{#10000},7,6,7,16" -locations_default(#20186,#10000,7,6,7,16) +exprs(#20185,34,#20183,0,"""foo"" + ... ""baz""") +#20186=@"loc,{#10000},10,5,12,9" +locations_default(#20186,#10000,10,5,12,9) hasLocation(#20185,#20186) -regexp_const_value(#20185,"foobar") +enclosing_stmt(#20185,#20175) +expr_containers(#20185,#20001) #20187=* -stmts(#20187,18,#20001,3,"var reg ... qux""\n);") -#20188=@"loc,{#10000},9,1,14,2" -locations_default(#20188,#10000,9,1,14,2) +exprs(#20187,34,#20185,0,"""foo"" + \n ""bar""") +#20188=@"loc,{#10000},10,5,11,9" +locations_default(#20188,#10000,10,5,11,9) hasLocation(#20187,#20188) -stmt_containers(#20187,#20001) +enclosing_stmt(#20187,#20175) +expr_containers(#20187,#20001) #20189=* -exprs(#20189,64,#20187,0,"reg4 = ... ""qux""\n)") -#20190=@"loc,{#10000},9,5,14,1" -locations_default(#20190,#10000,9,5,14,1) -hasLocation(#20189,#20190) -enclosing_stmt(#20189,#20187) +exprs(#20189,4,#20187,0,"""foo""") +hasLocation(#20189,#20109) +enclosing_stmt(#20189,#20175) expr_containers(#20189,#20001) +literals("foo","""foo""",#20189) +#20190=* +exprs(#20190,4,#20187,1,"""bar""") +hasLocation(#20190,#20113) +enclosing_stmt(#20190,#20175) +expr_containers(#20190,#20001) +literals("bar","""bar""",#20190) #20191=* -exprs(#20191,78,#20189,0,"reg4") -hasLocation(#20191,#20099) -enclosing_stmt(#20191,#20187) +exprs(#20191,4,#20185,1,"""baz""") +hasLocation(#20191,#20117) +enclosing_stmt(#20191,#20175) expr_containers(#20191,#20001) -literals("reg4","reg4",#20191) -decl(#20191,#20132) +literals("baz","""baz""",#20191) #20192=* -exprs(#20192,12,#20189,1,"new Reg ... ""qux""\n)") -#20193=@"loc,{#10000},9,12,14,1" -locations_default(#20193,#10000,9,12,14,1) -hasLocation(#20192,#20193) -enclosing_stmt(#20192,#20187) +exprs(#20192,4,#20183,1,"""qux""") +hasLocation(#20192,#20121) +enclosing_stmt(#20192,#20175) expr_containers(#20192,#20001) -#20194=* -exprs(#20194,79,#20192,-1,"RegExp") -hasLocation(#20194,#20105) -enclosing_stmt(#20194,#20187) -expr_containers(#20194,#20001) -literals("RegExp","RegExp",#20194) -bind(#20194,#20140) +literals("qux","""qux""",#20192) +#20193=* +regexpterm(#20193,14,#20183,0,"foobarbazqux") +#20194=@"loc,{#10000},10,6,13,9" +locations_default(#20194,#10000,10,6,13,9) +hasLocation(#20193,#20194) +regexp_const_value(#20193,"foobarbazqux") #20195=* -exprs(#20195,34,#20192,0,"""foo"" + ... ""qux""") -#20196=@"loc,{#10000},10,5,13,9" -locations_default(#20196,#10000,10,5,13,9) +entry_cfg_node(#20195,#20001) +#20196=@"loc,{#10000},1,1,1,0" +locations_default(#20196,#10000,1,1,1,0) hasLocation(#20195,#20196) -enclosing_stmt(#20195,#20187) -expr_containers(#20195,#20001) #20197=* -exprs(#20197,34,#20195,0,"""foo"" + ... ""baz""") -#20198=@"loc,{#10000},10,5,12,9" -locations_default(#20198,#10000,10,5,12,9) -hasLocation(#20197,#20198) -enclosing_stmt(#20197,#20187) -expr_containers(#20197,#20001) -#20199=* -exprs(#20199,34,#20197,0,"""foo"" + \n ""bar""") -#20200=@"loc,{#10000},10,5,11,9" -locations_default(#20200,#10000,10,5,11,9) -hasLocation(#20199,#20200) -enclosing_stmt(#20199,#20187) -expr_containers(#20199,#20001) -#20201=* -exprs(#20201,4,#20199,0,"""foo""") -hasLocation(#20201,#20109) -enclosing_stmt(#20201,#20187) -expr_containers(#20201,#20001) -literals("foo","""foo""",#20201) -#20202=* -regexpterm(#20202,14,#20201,0,"foo") -#20203=@"loc,{#10000},10,6,10,8" -locations_default(#20203,#10000,10,6,10,8) -hasLocation(#20202,#20203) -regexp_const_value(#20202,"foo") -#20204=* -exprs(#20204,4,#20199,1,"""bar""") -hasLocation(#20204,#20113) -enclosing_stmt(#20204,#20187) -expr_containers(#20204,#20001) -literals("bar","""bar""",#20204) -#20205=* -regexpterm(#20205,14,#20204,0,"bar") -#20206=@"loc,{#10000},11,6,11,8" -locations_default(#20206,#10000,11,6,11,8) -hasLocation(#20205,#20206) -regexp_const_value(#20205,"bar") -#20207=* -exprs(#20207,4,#20197,1,"""baz""") -hasLocation(#20207,#20117) -enclosing_stmt(#20207,#20187) -expr_containers(#20207,#20001) -literals("baz","""baz""",#20207) -#20208=* -regexpterm(#20208,14,#20207,0,"baz") -#20209=@"loc,{#10000},12,6,12,8" -locations_default(#20209,#10000,12,6,12,8) -hasLocation(#20208,#20209) -regexp_const_value(#20208,"baz") -#20210=* -exprs(#20210,4,#20195,1,"""qux""") -hasLocation(#20210,#20121) -enclosing_stmt(#20210,#20187) -expr_containers(#20210,#20001) -literals("qux","""qux""",#20210) -#20211=* -regexpterm(#20211,14,#20210,0,"qux") -#20212=@"loc,{#10000},13,6,13,8" -locations_default(#20212,#10000,13,6,13,8) -hasLocation(#20211,#20212) -regexp_const_value(#20211,"qux") -#20213=* -regexpterm(#20213,14,#20195,0,"foobarbazqux") -#20214=@"loc,{#10000},10,6,13,9" -locations_default(#20214,#10000,10,6,13,9) -hasLocation(#20213,#20214) -regexp_const_value(#20213,"foobarbazqux") -#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,#20127) +exit_cfg_node(#20197,#20001) +hasLocation(#20197,#20127) +successor(#20175,#20179) +successor(#20192,#20183) +successor(#20191,#20185) +successor(#20190,#20187) +successor(#20189,#20190) successor(#20187,#20191) -successor(#20210,#20195) -successor(#20207,#20197) -successor(#20204,#20199) -successor(#20201,#20204) -successor(#20199,#20207) -successor(#20197,#20210) -successor(#20195,#20192) -successor(#20194,#20201) -successor(#20192,#20189) -successor(#20191,#20194) -successor(#20189,#20217) -successor(#20169,#20173) -successor(#20182,#20177) +successor(#20185,#20192) +successor(#20183,#20180) +successor(#20182,#20189) +successor(#20180,#20177) successor(#20179,#20182) -successor(#20177,#20174) -successor(#20176,#20179) -successor(#20174,#20171) -successor(#20173,#20176) -successor(#20171,#20187) -successor(#20151,#20155) -successor(#20164,#20159) -successor(#20161,#20164) -successor(#20159,#20156) -successor(#20158,#20161) -successor(#20156,#20153) -successor(#20155,#20158) -successor(#20153,#20169) +successor(#20177,#20197) +successor(#20161,#20165) +successor(#20172,#20169) +successor(#20171,#20172) +successor(#20169,#20166) +successor(#20168,#20171) +successor(#20166,#20163) +successor(#20165,#20168) +successor(#20163,#20175) +successor(#20147,#20151) +successor(#20158,#20155) +successor(#20157,#20158) +successor(#20155,#20152) +successor(#20154,#20157) +successor(#20152,#20149) +successor(#20151,#20154) +successor(#20149,#20161) successor(#20133,#20136) -successor(#20146,#20141) -successor(#20143,#20146) +successor(#20144,#20141) +successor(#20143,#20144) successor(#20141,#20137) successor(#20139,#20143) successor(#20137,#20134) successor(#20136,#20139) -successor(#20134,#20151) -successor(#20215,#20133) +successor(#20134,#20147) +successor(#20195,#20133) numlines(#10000,14,11,0) filetype(#10000,"javascript") diff --git a/javascript/extractor/tests/ts/output/trap/hello.ts.trap b/javascript/extractor/tests/ts/output/trap/hello.ts.trap index 73c0ba7df7c..a1f36955b45 100644 --- a/javascript/extractor/tests/ts/output/trap/hello.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/hello.ts.trap @@ -235,109 +235,97 @@ enclosing_stmt(#20079,#20073) expr_containers(#20079,#20063) literals("Hello, ","""Hello, """,#20079) #20080=* -regexpterm(#20080,14,#20079,0,"Hello, ") -#20081=@"loc,{#10000},2,13,2,19" -locations_default(#20081,#10000,2,13,2,19) -hasLocation(#20080,#20081) -regexp_const_value(#20080,"Hello, ") +exprs(#20080,79,#20077,1,"person") +hasLocation(#20080,#20035) +enclosing_stmt(#20080,#20073) +expr_containers(#20080,#20063) +literals("person","person",#20080) +bind(#20080,#20067) +#20081=* +exprs(#20081,4,#20075,1,"""!""") +hasLocation(#20081,#20039) +enclosing_stmt(#20081,#20073) +expr_containers(#20081,#20063) +literals("!","""!""",#20081) #20082=* -exprs(#20082,79,#20077,1,"person") -hasLocation(#20082,#20035) -enclosing_stmt(#20082,#20073) -expr_containers(#20082,#20063) -literals("person","person",#20082) -bind(#20082,#20067) +stmts(#20082,2,#20001,1,"alert(g ... rld""));") +hasLocation(#20082,#20011) +stmt_containers(#20082,#20001) #20083=* -exprs(#20083,4,#20075,1,"""!""") -hasLocation(#20083,#20039) -enclosing_stmt(#20083,#20073) -expr_containers(#20083,#20063) -literals("!","""!""",#20083) -#20084=* -regexpterm(#20084,14,#20083,0,"!") -#20085=@"loc,{#10000},2,34,2,34" -locations_default(#20085,#10000,2,34,2,34) -hasLocation(#20084,#20085) -regexp_const_value(#20084,"!") -#20086=* -stmts(#20086,2,#20001,1,"alert(g ... rld""));") -hasLocation(#20086,#20011) -stmt_containers(#20086,#20001) +exprs(#20083,13,#20082,0,"alert(g ... orld""))") +#20084=@"loc,{#10000},5,1,5,23" +locations_default(#20084,#10000,5,1,5,23) +hasLocation(#20083,#20084) +enclosing_stmt(#20083,#20082) +expr_containers(#20083,#20001) +#20085=* +exprs(#20085,79,#20083,-1,"alert") +hasLocation(#20085,#20044) +enclosing_stmt(#20085,#20082) +expr_containers(#20085,#20001) +literals("alert","alert",#20085) +#20086=@"var;{alert};{#20000}" +variables(#20086,"alert",#20000) +bind(#20085,#20086) #20087=* -exprs(#20087,13,#20086,0,"alert(g ... orld""))") -#20088=@"loc,{#10000},5,1,5,23" -locations_default(#20088,#10000,5,1,5,23) +exprs(#20087,13,#20083,0,"greeter(""world"")") +#20088=@"loc,{#10000},5,7,5,22" +locations_default(#20088,#10000,5,7,5,22) hasLocation(#20087,#20088) -enclosing_stmt(#20087,#20086) +enclosing_stmt(#20087,#20082) expr_containers(#20087,#20001) #20089=* -exprs(#20089,79,#20087,-1,"alert") -hasLocation(#20089,#20044) -enclosing_stmt(#20089,#20086) +exprs(#20089,79,#20087,-1,"greeter") +hasLocation(#20089,#20048) +enclosing_stmt(#20089,#20082) expr_containers(#20089,#20001) -literals("alert","alert",#20089) -#20090=@"var;{alert};{#20000}" -variables(#20090,"alert",#20000) -bind(#20089,#20090) +literals("greeter","greeter",#20089) +bind(#20089,#20062) +#20090=* +exprs(#20090,4,#20087,0,"""world""") +hasLocation(#20090,#20052) +enclosing_stmt(#20090,#20082) +expr_containers(#20090,#20001) +literals("world","""world""",#20090) #20091=* -exprs(#20091,13,#20087,0,"greeter(""world"")") -#20092=@"loc,{#10000},5,7,5,22" -locations_default(#20092,#10000,5,7,5,22) +regexpterm(#20091,14,#20090,0,"world") +#20092=@"loc,{#10000},5,16,5,20" +locations_default(#20092,#10000,5,16,5,20) hasLocation(#20091,#20092) -enclosing_stmt(#20091,#20086) -expr_containers(#20091,#20001) +regexp_const_value(#20091,"world") #20093=* -exprs(#20093,79,#20091,-1,"greeter") -hasLocation(#20093,#20048) -enclosing_stmt(#20093,#20086) -expr_containers(#20093,#20001) -literals("greeter","greeter",#20093) -bind(#20093,#20062) -#20094=* -exprs(#20094,4,#20091,0,"""world""") -hasLocation(#20094,#20052) -enclosing_stmt(#20094,#20086) -expr_containers(#20094,#20001) -literals("world","""world""",#20094) +entry_cfg_node(#20093,#20001) +#20094=@"loc,{#10000},1,1,1,0" +locations_default(#20094,#10000,1,1,1,0) +hasLocation(#20093,#20094) #20095=* -regexpterm(#20095,14,#20094,0,"world") -#20096=@"loc,{#10000},5,16,5,20" -locations_default(#20096,#10000,5,16,5,20) -hasLocation(#20095,#20096) -regexp_const_value(#20095,"world") +exit_cfg_node(#20095,#20001) +hasLocation(#20095,#20060) +successor(#20082,#20085) +successor(#20090,#20087) +successor(#20089,#20090) +successor(#20087,#20083) +successor(#20085,#20089) +successor(#20083,#20095) +successor(#20063,#20082) +#20096=* +entry_cfg_node(#20096,#20063) +hasLocation(#20096,#20094) #20097=* -entry_cfg_node(#20097,#20001) -#20098=@"loc,{#10000},1,1,1,0" -locations_default(#20098,#10000,1,1,1,0) +exit_cfg_node(#20097,#20063) +#20098=@"loc,{#10000},3,2,3,1" +locations_default(#20098,#10000,3,2,3,1) hasLocation(#20097,#20098) -#20099=* -exit_cfg_node(#20099,#20001) -hasLocation(#20099,#20060) -successor(#20086,#20089) -successor(#20094,#20091) -successor(#20093,#20094) -successor(#20091,#20087) -successor(#20089,#20093) -successor(#20087,#20099) -successor(#20063,#20086) -#20100=* -entry_cfg_node(#20100,#20063) -hasLocation(#20100,#20098) -#20101=* -exit_cfg_node(#20101,#20063) -#20102=@"loc,{#10000},3,2,3,1" -locations_default(#20102,#10000,3,2,3,1) -hasLocation(#20101,#20102) successor(#20071,#20079) -successor(#20083,#20075) -successor(#20082,#20077) -successor(#20079,#20082) -successor(#20077,#20083) +successor(#20081,#20075) +successor(#20080,#20077) +successor(#20079,#20080) +successor(#20077,#20081) successor(#20075,#20073) -successor(#20073,#20101) +successor(#20073,#20097) successor(#20068,#20071) -successor(#20100,#20068) +successor(#20096,#20068) successor(#20065,#20063) -successor(#20097,#20065) +successor(#20093,#20065) numlines(#10000,5,4,0) filetype(#10000,"typescript") From 9a11c13e11cf0f27f37eef2b168641f583ca5de2 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 11 Nov 2021 11:56:30 +0100 Subject: [PATCH 08/10] update expected output --- .../Security/CWE-020/IncompleteHostnameRegExp.expected | 4 ---- 1 file changed, 4 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected index 7d95ac646e7..4911f159e47 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected @@ -15,15 +15,11 @@ | tst-IncompleteHostnameRegExp.js:38:3:38:43 | ^(http\|https):\\/\\/www.example.com\\/p\\/f\\/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:38:2:38:44 | /^(http ... p\\/f\\// | here | | tst-IncompleteHostnameRegExp.js:39:5:39:30 | http:\\/\\/sub.example.com\\/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:39:2:39:33 | /^(http ... om\\/)/g | here | | tst-IncompleteHostnameRegExp.js:40:3:40:29 | ^https?:\\/\\/api.example.com | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:40:2:40:30 | /^https ... le.com/ | here | -| tst-IncompleteHostnameRegExp.js:41:42:41:48 | ^https?://.+\\.example\\.com/ | This regular expression has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:41:13:41:71 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:41:42:41:70 | ^https?://.+\\.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:41:13:41:71 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:43:3:43:32 | ^https:\\/\\/[a-z]*.example.com$ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:43:2:43:33 | /^https ... e.com$/ | here | | tst-IncompleteHostnameRegExp.js:44:32:44:45 | .+.example.net | This regular expression has an unescaped '.' before 'example.net', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | | tst-IncompleteHostnameRegExp.js:44:47:44:62 | .+.example-a.com | This regular expression has an unescaped '.' before 'example-a.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | | tst-IncompleteHostnameRegExp.js:44:64:44:79 | .+.example-b.com | This regular expression has an unescaped '.' before 'example-b.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | -| tst-IncompleteHostnameRegExp.js:48:42:48:47 | ^https?://.+.example\\.com/ | This regular expression has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | -| tst-IncompleteHostnameRegExp.js:48:42:48:47 | ^https?://.+.example\\.com/ | This regular expression has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:48:42:48:68 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:48:42:48:68 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | -| tst-IncompleteHostnameRegExp.js:53:14:53:35 | test.example.com$ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:53:13:53:36 | 'test.' ... e.com$' | here | | tst-IncompleteHostnameRegExp.js:59:5:59:20 | foo.example\\.com | This regular expression has an unescaped '.' before 'example\\.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:59:2:59:32 | /^(foo. ... ever)$/ | here | From 2163648b397675d0edeed9603affa9ef6f04b3bd Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 15 Nov 2021 13:43:39 +0100 Subject: [PATCH 09/10] fix location off-by-ones with regexp parsing --- .../com/semmle/js/extractor/ASTExtractor.java | 4 +- .../semmle/js/extractor/RegExpExtractor.java | 10 +- .../extractor/tests/regexp/input/multipart.js | 19 +- .../regexp/output/trap/multipart.js.trap | 1699 ++++++++++++----- .../ReDoS/PolynomialBackTracking.expected | 10 +- .../Performance/ReDoS/ReDoS.expected | 10 +- 6 files changed, 1283 insertions(+), 469 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 93850e595af..0ed7e56df30 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -589,7 +589,7 @@ public class ASTExtractor { trapwriter.addTuple("literals", valueString, source, key); Position start = nd.getLoc().getStart(); - com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn(), start.getOffset()); + com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn() + 1 /* Convert from 0-based to 1-based. */, start.getOffset()); if (nd.isRegExp()) { OffsetTranslation offsets = new OffsetTranslation(); @@ -867,7 +867,7 @@ public class ASTExtractor { } OffsetTranslation offsets = concatResult.snd(); Position start = nd.getLoc().getStart(); - com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn(), start.getOffset()); + com.semmle.util.locations.Position startPos = new com.semmle.util.locations.Position(start.getLine(), start.getColumn() + 1 /* Convert from 0-based to 1-based. */, start.getOffset()); SourceMap sourceMap = SourceMap.legacyWithStartPos(SourceMap.fromString(nd.getLoc().getSource()).offsetBy(0, offsets), startPos); regexpExtractor.extract(foldedString, sourceMap, nd, true); return; diff --git a/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java index f94166b45ad..41d7d446cfe 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/RegExpExtractor.java @@ -121,10 +121,12 @@ public class RegExpExtractor { } public void emitLocation(SourceElement term, Label lbl) { - int sl = sourceMap.getStart(term.getLoc().getStart().getColumn()).getLine(); - int sc = sourceMap.getStart(term.getLoc().getStart().getColumn()).getColumn() + 1; // convert to 1-based - int el = sourceMap.getEnd(term.getLoc().getEnd().getColumn()).getLine(); - int ec = sourceMap.getEnd(term.getLoc().getEnd().getColumn()).getColumn() - 1; // convert to inclusive + int start = term.getLoc().getStart().getColumn(); + int sl = sourceMap.getStart(start).getLine(); + int sc = sourceMap.getStart(start).getColumn(); + int end = term.getLoc().getEnd().getColumn(); + int el = sourceMap.getStart(end).getLine(); + int ec = sourceMap.getStart(end).getColumn() - 1; // convert to inclusive locationManager.emitSnippetLocation(lbl, sl, sc, el, ec); } diff --git a/javascript/extractor/tests/regexp/input/multipart.js b/javascript/extractor/tests/regexp/input/multipart.js index e278722b9a2..9acdbdf144f 100644 --- a/javascript/extractor/tests/regexp/input/multipart.js +++ b/javascript/extractor/tests/regexp/input/multipart.js @@ -11,4 +11,21 @@ var reg4 = new RegExp( "bar" + "baz" + "qux" -); \ No newline at end of file +); + +var bad95 = new RegExp( + "(a" + + "|" + + "aa)*" + + "b$" +); + +var bad96 = new RegExp("(" + + "(c|cc)*|" + + "(d|dd)*|" + + "(e|ee)*" + +")f$"); + +var bad97 = new RegExp( + "(g|gg" + + ")*h$"); diff --git a/javascript/extractor/tests/regexp/output/trap/multipart.js.trap b/javascript/extractor/tests/regexp/output/trap/multipart.js.trap index 2c85cf4e70d..4039d782b26 100644 --- a/javascript/extractor/tests/regexp/output/trap/multipart.js.trap +++ b/javascript/extractor/tests/regexp/output/trap/multipart.js.trap @@ -94,574 +94,1369 @@ locations_default(#20027,#10000,13,1,13,9) hasLocation(#20026,#20027) indentation(#10000,13," ",4) #20028=* -lines(#20028,#20001,");","") +lines(#20028,#20001,");"," +") #20029=@"loc,{#10000},14,1,14,2" locations_default(#20029,#10000,14,1,14,2) hasLocation(#20028,#20029) -numlines(#20001,14,11,0) #20030=* -tokeninfo(#20030,7,#20001,0,"var") -#20031=@"loc,{#10000},1,1,1,3" -locations_default(#20031,#10000,1,1,1,3) +lines(#20030,#20001,""," +") +#20031=@"loc,{#10000},15,1,15,0" +locations_default(#20031,#10000,15,1,15,0) hasLocation(#20030,#20031) #20032=* -tokeninfo(#20032,6,#20001,1,"reg") -#20033=@"loc,{#10000},1,5,1,7" -locations_default(#20033,#10000,1,5,1,7) +lines(#20032,#20001,"var bad95 = new RegExp("," +") +#20033=@"loc,{#10000},16,1,16,23" +locations_default(#20033,#10000,16,1,16,23) hasLocation(#20032,#20033) #20034=* -tokeninfo(#20034,8,#20001,2,"=") -#20035=@"loc,{#10000},1,9,1,9" -locations_default(#20035,#10000,1,9,1,9) +lines(#20034,#20001," ""(a"" + "," +") +#20035=@"loc,{#10000},17,1,17,11" +locations_default(#20035,#10000,17,1,17,11) hasLocation(#20034,#20035) +indentation(#10000,17," ",4) #20036=* -tokeninfo(#20036,7,#20001,3,"new") -#20037=@"loc,{#10000},1,11,1,13" -locations_default(#20037,#10000,1,11,1,13) +lines(#20036,#20001," ""|"" + "," +") +#20037=@"loc,{#10000},18,1,18,10" +locations_default(#20037,#10000,18,1,18,10) hasLocation(#20036,#20037) +indentation(#10000,18," ",4) #20038=* -tokeninfo(#20038,6,#20001,4,"RegExp") -#20039=@"loc,{#10000},1,15,1,20" -locations_default(#20039,#10000,1,15,1,20) +lines(#20038,#20001," ""aa)*"" + "," +") +#20039=@"loc,{#10000},19,1,19,13" +locations_default(#20039,#10000,19,1,19,13) hasLocation(#20038,#20039) +indentation(#10000,19," ",4) #20040=* -tokeninfo(#20040,8,#20001,5,"(") -#20041=@"loc,{#10000},1,21,1,21" -locations_default(#20041,#10000,1,21,1,21) +lines(#20040,#20001," ""b$"""," +") +#20041=@"loc,{#10000},20,1,20,8" +locations_default(#20041,#10000,20,1,20,8) hasLocation(#20040,#20041) +indentation(#10000,20," ",4) #20042=* -tokeninfo(#20042,4,#20001,6,"""foo""") -#20043=@"loc,{#10000},1,22,1,26" -locations_default(#20043,#10000,1,22,1,26) +lines(#20042,#20001,");"," +") +#20043=@"loc,{#10000},21,1,21,2" +locations_default(#20043,#10000,21,1,21,2) hasLocation(#20042,#20043) #20044=* -tokeninfo(#20044,8,#20001,7,"+") -#20045=@"loc,{#10000},1,28,1,28" -locations_default(#20045,#10000,1,28,1,28) +lines(#20044,#20001,""," +") +#20045=@"loc,{#10000},22,1,22,0" +locations_default(#20045,#10000,22,1,22,0) hasLocation(#20044,#20045) #20046=* -tokeninfo(#20046,4,#20001,8,"""bar""") -#20047=@"loc,{#10000},1,30,1,34" -locations_default(#20047,#10000,1,30,1,34) +lines(#20046,#20001,"var bad96 = new RegExp(""("" + "," +") +#20047=@"loc,{#10000},23,1,23,29" +locations_default(#20047,#10000,23,1,23,29) hasLocation(#20046,#20047) #20048=* -tokeninfo(#20048,8,#20001,9,")") -#20049=@"loc,{#10000},1,35,1,35" -locations_default(#20049,#10000,1,35,1,35) +lines(#20048,#20001," ""(c|cc)*|"" + "," +") +#20049=@"loc,{#10000},24,1,24,17" +locations_default(#20049,#10000,24,1,24,17) hasLocation(#20048,#20049) +indentation(#10000,24," ",4) #20050=* -tokeninfo(#20050,8,#20001,10,";") -#20051=@"loc,{#10000},1,36,1,36" -locations_default(#20051,#10000,1,36,1,36) +lines(#20050,#20001," ""(d|dd)*|"" +"," +") +#20051=@"loc,{#10000},25,1,25,16" +locations_default(#20051,#10000,25,1,25,16) hasLocation(#20050,#20051) +indentation(#10000,25," ",4) #20052=* -tokeninfo(#20052,7,#20001,11,"var") -#20053=@"loc,{#10000},3,1,3,3" -locations_default(#20053,#10000,3,1,3,3) +lines(#20052,#20001," ""(e|ee)*"" +"," +") +#20053=@"loc,{#10000},26,1,26,15" +locations_default(#20053,#10000,26,1,26,15) hasLocation(#20052,#20053) +indentation(#10000,26," ",4) #20054=* -tokeninfo(#20054,6,#20001,12,"reg2") -#20055=@"loc,{#10000},3,5,3,8" -locations_default(#20055,#10000,3,5,3,8) +lines(#20054,#20001,""")f$"");"," +") +#20055=@"loc,{#10000},27,1,27,7" +locations_default(#20055,#10000,27,1,27,7) hasLocation(#20054,#20055) #20056=* -tokeninfo(#20056,8,#20001,13,"=") -#20057=@"loc,{#10000},3,10,3,10" -locations_default(#20057,#10000,3,10,3,10) +lines(#20056,#20001,""," +") +#20057=@"loc,{#10000},28,1,28,0" +locations_default(#20057,#10000,28,1,28,0) hasLocation(#20056,#20057) #20058=* -tokeninfo(#20058,7,#20001,14,"new") -#20059=@"loc,{#10000},3,12,3,14" -locations_default(#20059,#10000,3,12,3,14) +lines(#20058,#20001,"var bad97 = new RegExp("," +") +#20059=@"loc,{#10000},29,1,29,23" +locations_default(#20059,#10000,29,1,29,23) hasLocation(#20058,#20059) #20060=* -tokeninfo(#20060,6,#20001,15,"RegExp") -#20061=@"loc,{#10000},3,16,3,21" -locations_default(#20061,#10000,3,16,3,21) +lines(#20060,#20001," ""(g|gg"" + "," +") +#20061=@"loc,{#10000},30,1,30,14" +locations_default(#20061,#10000,30,1,30,14) hasLocation(#20060,#20061) +indentation(#10000,30," ",4) #20062=* -tokeninfo(#20062,8,#20001,16,"(") -#20063=@"loc,{#10000},3,22,3,22" -locations_default(#20063,#10000,3,22,3,22) +lines(#20062,#20001," "")*h$"");"," +") +#20063=@"loc,{#10000},31,1,31,12" +locations_default(#20063,#10000,31,1,31,12) hasLocation(#20062,#20063) +indentation(#10000,31," ",4) +numlines(#20001,31,25,0) #20064=* -tokeninfo(#20064,4,#20001,17,"""foo""") -#20065=@"loc,{#10000},3,23,3,27" -locations_default(#20065,#10000,3,23,3,27) +tokeninfo(#20064,7,#20001,0,"var") +#20065=@"loc,{#10000},1,1,1,3" +locations_default(#20065,#10000,1,1,1,3) hasLocation(#20064,#20065) #20066=* -tokeninfo(#20066,8,#20001,18,"+") -#20067=@"loc,{#10000},4,5,4,5" -locations_default(#20067,#10000,4,5,4,5) +tokeninfo(#20066,6,#20001,1,"reg") +#20067=@"loc,{#10000},1,5,1,7" +locations_default(#20067,#10000,1,5,1,7) hasLocation(#20066,#20067) #20068=* -tokeninfo(#20068,4,#20001,19,"""bar""") -#20069=@"loc,{#10000},4,7,4,11" -locations_default(#20069,#10000,4,7,4,11) +tokeninfo(#20068,8,#20001,2,"=") +#20069=@"loc,{#10000},1,9,1,9" +locations_default(#20069,#10000,1,9,1,9) hasLocation(#20068,#20069) #20070=* -tokeninfo(#20070,8,#20001,20,")") -#20071=@"loc,{#10000},4,12,4,12" -locations_default(#20071,#10000,4,12,4,12) +tokeninfo(#20070,7,#20001,3,"new") +#20071=@"loc,{#10000},1,11,1,13" +locations_default(#20071,#10000,1,11,1,13) hasLocation(#20070,#20071) #20072=* -tokeninfo(#20072,8,#20001,21,";") -#20073=@"loc,{#10000},4,13,4,13" -locations_default(#20073,#10000,4,13,4,13) +tokeninfo(#20072,6,#20001,4,"RegExp") +#20073=@"loc,{#10000},1,15,1,20" +locations_default(#20073,#10000,1,15,1,20) hasLocation(#20072,#20073) #20074=* -tokeninfo(#20074,7,#20001,22,"var") -#20075=@"loc,{#10000},6,1,6,3" -locations_default(#20075,#10000,6,1,6,3) +tokeninfo(#20074,8,#20001,5,"(") +#20075=@"loc,{#10000},1,21,1,21" +locations_default(#20075,#10000,1,21,1,21) hasLocation(#20074,#20075) #20076=* -tokeninfo(#20076,6,#20001,23,"reg3") -#20077=@"loc,{#10000},6,5,6,8" -locations_default(#20077,#10000,6,5,6,8) +tokeninfo(#20076,4,#20001,6,"""foo""") +#20077=@"loc,{#10000},1,22,1,26" +locations_default(#20077,#10000,1,22,1,26) hasLocation(#20076,#20077) #20078=* -tokeninfo(#20078,8,#20001,24,"=") -#20079=@"loc,{#10000},6,10,6,10" -locations_default(#20079,#10000,6,10,6,10) +tokeninfo(#20078,8,#20001,7,"+") +#20079=@"loc,{#10000},1,28,1,28" +locations_default(#20079,#10000,1,28,1,28) hasLocation(#20078,#20079) #20080=* -tokeninfo(#20080,7,#20001,25,"new") -#20081=@"loc,{#10000},6,12,6,14" -locations_default(#20081,#10000,6,12,6,14) +tokeninfo(#20080,4,#20001,8,"""bar""") +#20081=@"loc,{#10000},1,30,1,34" +locations_default(#20081,#10000,1,30,1,34) hasLocation(#20080,#20081) #20082=* -tokeninfo(#20082,6,#20001,26,"RegExp") -#20083=@"loc,{#10000},6,16,6,21" -locations_default(#20083,#10000,6,16,6,21) +tokeninfo(#20082,8,#20001,9,")") +#20083=@"loc,{#10000},1,35,1,35" +locations_default(#20083,#10000,1,35,1,35) hasLocation(#20082,#20083) #20084=* -tokeninfo(#20084,8,#20001,27,"(") -#20085=@"loc,{#10000},6,22,6,22" -locations_default(#20085,#10000,6,22,6,22) +tokeninfo(#20084,8,#20001,10,";") +#20085=@"loc,{#10000},1,36,1,36" +locations_default(#20085,#10000,1,36,1,36) hasLocation(#20084,#20085) #20086=* -tokeninfo(#20086,4,#20001,28,"""foo""") -#20087=@"loc,{#10000},7,5,7,9" -locations_default(#20087,#10000,7,5,7,9) +tokeninfo(#20086,7,#20001,11,"var") +#20087=@"loc,{#10000},3,1,3,3" +locations_default(#20087,#10000,3,1,3,3) hasLocation(#20086,#20087) #20088=* -tokeninfo(#20088,8,#20001,29,"+") -#20089=@"loc,{#10000},7,11,7,11" -locations_default(#20089,#10000,7,11,7,11) +tokeninfo(#20088,6,#20001,12,"reg2") +#20089=@"loc,{#10000},3,5,3,8" +locations_default(#20089,#10000,3,5,3,8) hasLocation(#20088,#20089) #20090=* -tokeninfo(#20090,4,#20001,30,"""bar""") -#20091=@"loc,{#10000},7,13,7,17" -locations_default(#20091,#10000,7,13,7,17) +tokeninfo(#20090,8,#20001,13,"=") +#20091=@"loc,{#10000},3,10,3,10" +locations_default(#20091,#10000,3,10,3,10) hasLocation(#20090,#20091) #20092=* -tokeninfo(#20092,8,#20001,31,")") -#20093=@"loc,{#10000},7,18,7,18" -locations_default(#20093,#10000,7,18,7,18) +tokeninfo(#20092,7,#20001,14,"new") +#20093=@"loc,{#10000},3,12,3,14" +locations_default(#20093,#10000,3,12,3,14) hasLocation(#20092,#20093) #20094=* -tokeninfo(#20094,8,#20001,32,";") -#20095=@"loc,{#10000},7,19,7,19" -locations_default(#20095,#10000,7,19,7,19) +tokeninfo(#20094,6,#20001,15,"RegExp") +#20095=@"loc,{#10000},3,16,3,21" +locations_default(#20095,#10000,3,16,3,21) hasLocation(#20094,#20095) #20096=* -tokeninfo(#20096,7,#20001,33,"var") -#20097=@"loc,{#10000},9,1,9,3" -locations_default(#20097,#10000,9,1,9,3) +tokeninfo(#20096,8,#20001,16,"(") +#20097=@"loc,{#10000},3,22,3,22" +locations_default(#20097,#10000,3,22,3,22) hasLocation(#20096,#20097) #20098=* -tokeninfo(#20098,6,#20001,34,"reg4") -#20099=@"loc,{#10000},9,5,9,8" -locations_default(#20099,#10000,9,5,9,8) +tokeninfo(#20098,4,#20001,17,"""foo""") +#20099=@"loc,{#10000},3,23,3,27" +locations_default(#20099,#10000,3,23,3,27) hasLocation(#20098,#20099) #20100=* -tokeninfo(#20100,8,#20001,35,"=") -#20101=@"loc,{#10000},9,10,9,10" -locations_default(#20101,#10000,9,10,9,10) +tokeninfo(#20100,8,#20001,18,"+") +#20101=@"loc,{#10000},4,5,4,5" +locations_default(#20101,#10000,4,5,4,5) hasLocation(#20100,#20101) #20102=* -tokeninfo(#20102,7,#20001,36,"new") -#20103=@"loc,{#10000},9,12,9,14" -locations_default(#20103,#10000,9,12,9,14) +tokeninfo(#20102,4,#20001,19,"""bar""") +#20103=@"loc,{#10000},4,7,4,11" +locations_default(#20103,#10000,4,7,4,11) hasLocation(#20102,#20103) #20104=* -tokeninfo(#20104,6,#20001,37,"RegExp") -#20105=@"loc,{#10000},9,16,9,21" -locations_default(#20105,#10000,9,16,9,21) +tokeninfo(#20104,8,#20001,20,")") +#20105=@"loc,{#10000},4,12,4,12" +locations_default(#20105,#10000,4,12,4,12) hasLocation(#20104,#20105) #20106=* -tokeninfo(#20106,8,#20001,38,"(") -#20107=@"loc,{#10000},9,22,9,22" -locations_default(#20107,#10000,9,22,9,22) +tokeninfo(#20106,8,#20001,21,";") +#20107=@"loc,{#10000},4,13,4,13" +locations_default(#20107,#10000,4,13,4,13) hasLocation(#20106,#20107) #20108=* -tokeninfo(#20108,4,#20001,39,"""foo""") -#20109=@"loc,{#10000},10,5,10,9" -locations_default(#20109,#10000,10,5,10,9) +tokeninfo(#20108,7,#20001,22,"var") +#20109=@"loc,{#10000},6,1,6,3" +locations_default(#20109,#10000,6,1,6,3) hasLocation(#20108,#20109) #20110=* -tokeninfo(#20110,8,#20001,40,"+") -#20111=@"loc,{#10000},10,11,10,11" -locations_default(#20111,#10000,10,11,10,11) +tokeninfo(#20110,6,#20001,23,"reg3") +#20111=@"loc,{#10000},6,5,6,8" +locations_default(#20111,#10000,6,5,6,8) hasLocation(#20110,#20111) #20112=* -tokeninfo(#20112,4,#20001,41,"""bar""") -#20113=@"loc,{#10000},11,5,11,9" -locations_default(#20113,#10000,11,5,11,9) +tokeninfo(#20112,8,#20001,24,"=") +#20113=@"loc,{#10000},6,10,6,10" +locations_default(#20113,#10000,6,10,6,10) hasLocation(#20112,#20113) #20114=* -tokeninfo(#20114,8,#20001,42,"+") -#20115=@"loc,{#10000},11,11,11,11" -locations_default(#20115,#10000,11,11,11,11) +tokeninfo(#20114,7,#20001,25,"new") +#20115=@"loc,{#10000},6,12,6,14" +locations_default(#20115,#10000,6,12,6,14) hasLocation(#20114,#20115) #20116=* -tokeninfo(#20116,4,#20001,43,"""baz""") -#20117=@"loc,{#10000},12,5,12,9" -locations_default(#20117,#10000,12,5,12,9) +tokeninfo(#20116,6,#20001,26,"RegExp") +#20117=@"loc,{#10000},6,16,6,21" +locations_default(#20117,#10000,6,16,6,21) hasLocation(#20116,#20117) #20118=* -tokeninfo(#20118,8,#20001,44,"+") -#20119=@"loc,{#10000},12,11,12,11" -locations_default(#20119,#10000,12,11,12,11) +tokeninfo(#20118,8,#20001,27,"(") +#20119=@"loc,{#10000},6,22,6,22" +locations_default(#20119,#10000,6,22,6,22) hasLocation(#20118,#20119) #20120=* -tokeninfo(#20120,4,#20001,45,"""qux""") -#20121=@"loc,{#10000},13,5,13,9" -locations_default(#20121,#10000,13,5,13,9) +tokeninfo(#20120,4,#20001,28,"""foo""") +#20121=@"loc,{#10000},7,5,7,9" +locations_default(#20121,#10000,7,5,7,9) hasLocation(#20120,#20121) #20122=* -tokeninfo(#20122,8,#20001,46,")") -#20123=@"loc,{#10000},14,1,14,1" -locations_default(#20123,#10000,14,1,14,1) +tokeninfo(#20122,8,#20001,29,"+") +#20123=@"loc,{#10000},7,11,7,11" +locations_default(#20123,#10000,7,11,7,11) hasLocation(#20122,#20123) #20124=* -tokeninfo(#20124,8,#20001,47,";") -#20125=@"loc,{#10000},14,2,14,2" -locations_default(#20125,#10000,14,2,14,2) +tokeninfo(#20124,4,#20001,30,"""bar""") +#20125=@"loc,{#10000},7,13,7,17" +locations_default(#20125,#10000,7,13,7,17) hasLocation(#20124,#20125) #20126=* -tokeninfo(#20126,0,#20001,48,"") -#20127=@"loc,{#10000},14,3,14,2" -locations_default(#20127,#10000,14,3,14,2) +tokeninfo(#20126,8,#20001,31,")") +#20127=@"loc,{#10000},7,18,7,18" +locations_default(#20127,#10000,7,18,7,18) hasLocation(#20126,#20127) -toplevels(#20001,0) -#20128=@"loc,{#10000},1,1,14,2" -locations_default(#20128,#10000,1,1,14,2) -hasLocation(#20001,#20128) -#20129=@"var;{reg};{#20000}" -variables(#20129,"reg",#20000) -#20130=@"var;{reg2};{#20000}" -variables(#20130,"reg2",#20000) -#20131=@"var;{reg3};{#20000}" -variables(#20131,"reg3",#20000) -#20132=@"var;{reg4};{#20000}" -variables(#20132,"reg4",#20000) -#20133=* -stmts(#20133,18,#20001,0,"var reg ... ""bar"");") -hasLocation(#20133,#20003) -stmt_containers(#20133,#20001) +#20128=* +tokeninfo(#20128,8,#20001,32,";") +#20129=@"loc,{#10000},7,19,7,19" +locations_default(#20129,#10000,7,19,7,19) +hasLocation(#20128,#20129) +#20130=* +tokeninfo(#20130,7,#20001,33,"var") +#20131=@"loc,{#10000},9,1,9,3" +locations_default(#20131,#10000,9,1,9,3) +hasLocation(#20130,#20131) +#20132=* +tokeninfo(#20132,6,#20001,34,"reg4") +#20133=@"loc,{#10000},9,5,9,8" +locations_default(#20133,#10000,9,5,9,8) +hasLocation(#20132,#20133) #20134=* -exprs(#20134,64,#20133,0,"reg = n ... ""bar"")") -#20135=@"loc,{#10000},1,5,1,35" -locations_default(#20135,#10000,1,5,1,35) +tokeninfo(#20134,8,#20001,35,"=") +#20135=@"loc,{#10000},9,10,9,10" +locations_default(#20135,#10000,9,10,9,10) hasLocation(#20134,#20135) -enclosing_stmt(#20134,#20133) -expr_containers(#20134,#20001) #20136=* -exprs(#20136,78,#20134,0,"reg") -hasLocation(#20136,#20033) -enclosing_stmt(#20136,#20133) -expr_containers(#20136,#20001) -literals("reg","reg",#20136) -decl(#20136,#20129) -#20137=* -exprs(#20137,12,#20134,1,"new Reg ... ""bar"")") -#20138=@"loc,{#10000},1,11,1,35" -locations_default(#20138,#10000,1,11,1,35) -hasLocation(#20137,#20138) -enclosing_stmt(#20137,#20133) -expr_containers(#20137,#20001) -#20139=* -exprs(#20139,79,#20137,-1,"RegExp") -hasLocation(#20139,#20039) -enclosing_stmt(#20139,#20133) -expr_containers(#20139,#20001) -literals("RegExp","RegExp",#20139) -#20140=@"var;{RegExp};{#20000}" -variables(#20140,"RegExp",#20000) -bind(#20139,#20140) -#20141=* -exprs(#20141,34,#20137,0,"""foo"" + ""bar""") -#20142=@"loc,{#10000},1,22,1,34" -locations_default(#20142,#10000,1,22,1,34) -hasLocation(#20141,#20142) -enclosing_stmt(#20141,#20133) -expr_containers(#20141,#20001) -#20143=* -exprs(#20143,4,#20141,0,"""foo""") -hasLocation(#20143,#20043) -enclosing_stmt(#20143,#20133) -expr_containers(#20143,#20001) -literals("foo","""foo""",#20143) +tokeninfo(#20136,7,#20001,36,"new") +#20137=@"loc,{#10000},9,12,9,14" +locations_default(#20137,#10000,9,12,9,14) +hasLocation(#20136,#20137) +#20138=* +tokeninfo(#20138,6,#20001,37,"RegExp") +#20139=@"loc,{#10000},9,16,9,21" +locations_default(#20139,#10000,9,16,9,21) +hasLocation(#20138,#20139) +#20140=* +tokeninfo(#20140,8,#20001,38,"(") +#20141=@"loc,{#10000},9,22,9,22" +locations_default(#20141,#10000,9,22,9,22) +hasLocation(#20140,#20141) +#20142=* +tokeninfo(#20142,4,#20001,39,"""foo""") +#20143=@"loc,{#10000},10,5,10,9" +locations_default(#20143,#10000,10,5,10,9) +hasLocation(#20142,#20143) #20144=* -exprs(#20144,4,#20141,1,"""bar""") -hasLocation(#20144,#20047) -enclosing_stmt(#20144,#20133) -expr_containers(#20144,#20001) -literals("bar","""bar""",#20144) -#20145=* -regexpterm(#20145,14,#20141,0,"foobar") -#20146=@"loc,{#10000},1,23,1,33" -locations_default(#20146,#10000,1,23,1,33) -hasLocation(#20145,#20146) -regexp_const_value(#20145,"foobar") -#20147=* -stmts(#20147,18,#20001,1,"var reg ... ""bar"");") -#20148=@"loc,{#10000},3,1,4,13" -locations_default(#20148,#10000,3,1,4,13) -hasLocation(#20147,#20148) -stmt_containers(#20147,#20001) -#20149=* -exprs(#20149,64,#20147,0,"reg2 = ... ""bar"")") -#20150=@"loc,{#10000},3,5,4,12" -locations_default(#20150,#10000,3,5,4,12) -hasLocation(#20149,#20150) -enclosing_stmt(#20149,#20147) -expr_containers(#20149,#20001) -#20151=* -exprs(#20151,78,#20149,0,"reg2") -hasLocation(#20151,#20055) -enclosing_stmt(#20151,#20147) -expr_containers(#20151,#20001) -literals("reg2","reg2",#20151) -decl(#20151,#20130) +tokeninfo(#20144,8,#20001,40,"+") +#20145=@"loc,{#10000},10,11,10,11" +locations_default(#20145,#10000,10,11,10,11) +hasLocation(#20144,#20145) +#20146=* +tokeninfo(#20146,4,#20001,41,"""bar""") +#20147=@"loc,{#10000},11,5,11,9" +locations_default(#20147,#10000,11,5,11,9) +hasLocation(#20146,#20147) +#20148=* +tokeninfo(#20148,8,#20001,42,"+") +#20149=@"loc,{#10000},11,11,11,11" +locations_default(#20149,#10000,11,11,11,11) +hasLocation(#20148,#20149) +#20150=* +tokeninfo(#20150,4,#20001,43,"""baz""") +#20151=@"loc,{#10000},12,5,12,9" +locations_default(#20151,#10000,12,5,12,9) +hasLocation(#20150,#20151) #20152=* -exprs(#20152,12,#20149,1,"new Reg ... ""bar"")") -#20153=@"loc,{#10000},3,12,4,12" -locations_default(#20153,#10000,3,12,4,12) +tokeninfo(#20152,8,#20001,44,"+") +#20153=@"loc,{#10000},12,11,12,11" +locations_default(#20153,#10000,12,11,12,11) hasLocation(#20152,#20153) -enclosing_stmt(#20152,#20147) -expr_containers(#20152,#20001) #20154=* -exprs(#20154,79,#20152,-1,"RegExp") -hasLocation(#20154,#20061) -enclosing_stmt(#20154,#20147) -expr_containers(#20154,#20001) -literals("RegExp","RegExp",#20154) -bind(#20154,#20140) -#20155=* -exprs(#20155,34,#20152,0,"""foo""\n + ""bar""") -#20156=@"loc,{#10000},3,23,4,11" -locations_default(#20156,#10000,3,23,4,11) -hasLocation(#20155,#20156) -enclosing_stmt(#20155,#20147) -expr_containers(#20155,#20001) -#20157=* -exprs(#20157,4,#20155,0,"""foo""") -hasLocation(#20157,#20065) -enclosing_stmt(#20157,#20147) -expr_containers(#20157,#20001) -literals("foo","""foo""",#20157) +tokeninfo(#20154,4,#20001,45,"""qux""") +#20155=@"loc,{#10000},13,5,13,9" +locations_default(#20155,#10000,13,5,13,9) +hasLocation(#20154,#20155) +#20156=* +tokeninfo(#20156,8,#20001,46,")") +#20157=@"loc,{#10000},14,1,14,1" +locations_default(#20157,#10000,14,1,14,1) +hasLocation(#20156,#20157) #20158=* -exprs(#20158,4,#20155,1,"""bar""") -hasLocation(#20158,#20069) -enclosing_stmt(#20158,#20147) -expr_containers(#20158,#20001) -literals("bar","""bar""",#20158) -#20159=* -regexpterm(#20159,14,#20155,0,"foobar") -#20160=@"loc,{#10000},3,24,4,11" -locations_default(#20160,#10000,3,24,4,11) -hasLocation(#20159,#20160) -regexp_const_value(#20159,"foobar") -#20161=* -stmts(#20161,18,#20001,2,"var reg ... ""bar"");") -#20162=@"loc,{#10000},6,1,7,19" -locations_default(#20162,#10000,6,1,7,19) -hasLocation(#20161,#20162) -stmt_containers(#20161,#20001) -#20163=* -exprs(#20163,64,#20161,0,"reg3 = ... ""bar"")") -#20164=@"loc,{#10000},6,5,7,18" -locations_default(#20164,#10000,6,5,7,18) -hasLocation(#20163,#20164) -enclosing_stmt(#20163,#20161) -expr_containers(#20163,#20001) -#20165=* -exprs(#20165,78,#20163,0,"reg3") -hasLocation(#20165,#20077) -enclosing_stmt(#20165,#20161) -expr_containers(#20165,#20001) -literals("reg3","reg3",#20165) -decl(#20165,#20131) +tokeninfo(#20158,8,#20001,47,";") +#20159=@"loc,{#10000},14,2,14,2" +locations_default(#20159,#10000,14,2,14,2) +hasLocation(#20158,#20159) +#20160=* +tokeninfo(#20160,7,#20001,48,"var") +#20161=@"loc,{#10000},16,1,16,3" +locations_default(#20161,#10000,16,1,16,3) +hasLocation(#20160,#20161) +#20162=* +tokeninfo(#20162,6,#20001,49,"bad95") +#20163=@"loc,{#10000},16,5,16,9" +locations_default(#20163,#10000,16,5,16,9) +hasLocation(#20162,#20163) +#20164=* +tokeninfo(#20164,8,#20001,50,"=") +#20165=@"loc,{#10000},16,11,16,11" +locations_default(#20165,#10000,16,11,16,11) +hasLocation(#20164,#20165) #20166=* -exprs(#20166,12,#20163,1,"new Reg ... ""bar"")") -#20167=@"loc,{#10000},6,12,7,18" -locations_default(#20167,#10000,6,12,7,18) +tokeninfo(#20166,7,#20001,51,"new") +#20167=@"loc,{#10000},16,13,16,15" +locations_default(#20167,#10000,16,13,16,15) hasLocation(#20166,#20167) -enclosing_stmt(#20166,#20161) -expr_containers(#20166,#20001) #20168=* -exprs(#20168,79,#20166,-1,"RegExp") -hasLocation(#20168,#20083) -enclosing_stmt(#20168,#20161) -expr_containers(#20168,#20001) -literals("RegExp","RegExp",#20168) -bind(#20168,#20140) -#20169=* -exprs(#20169,34,#20166,0,"""foo"" + ""bar""") -#20170=@"loc,{#10000},7,5,7,17" -locations_default(#20170,#10000,7,5,7,17) -hasLocation(#20169,#20170) -enclosing_stmt(#20169,#20161) -expr_containers(#20169,#20001) -#20171=* -exprs(#20171,4,#20169,0,"""foo""") -hasLocation(#20171,#20087) -enclosing_stmt(#20171,#20161) -expr_containers(#20171,#20001) -literals("foo","""foo""",#20171) +tokeninfo(#20168,6,#20001,52,"RegExp") +#20169=@"loc,{#10000},16,17,16,22" +locations_default(#20169,#10000,16,17,16,22) +hasLocation(#20168,#20169) +#20170=* +tokeninfo(#20170,8,#20001,53,"(") +#20171=@"loc,{#10000},16,23,16,23" +locations_default(#20171,#10000,16,23,16,23) +hasLocation(#20170,#20171) #20172=* -exprs(#20172,4,#20169,1,"""bar""") -hasLocation(#20172,#20091) -enclosing_stmt(#20172,#20161) -expr_containers(#20172,#20001) -literals("bar","""bar""",#20172) -#20173=* -regexpterm(#20173,14,#20169,0,"foobar") -#20174=@"loc,{#10000},7,6,7,16" -locations_default(#20174,#10000,7,6,7,16) -hasLocation(#20173,#20174) -regexp_const_value(#20173,"foobar") -#20175=* -stmts(#20175,18,#20001,3,"var reg ... qux""\n);") -#20176=@"loc,{#10000},9,1,14,2" -locations_default(#20176,#10000,9,1,14,2) -hasLocation(#20175,#20176) -stmt_containers(#20175,#20001) -#20177=* -exprs(#20177,64,#20175,0,"reg4 = ... ""qux""\n)") -#20178=@"loc,{#10000},9,5,14,1" -locations_default(#20178,#10000,9,5,14,1) -hasLocation(#20177,#20178) -enclosing_stmt(#20177,#20175) -expr_containers(#20177,#20001) -#20179=* -exprs(#20179,78,#20177,0,"reg4") -hasLocation(#20179,#20099) -enclosing_stmt(#20179,#20175) -expr_containers(#20179,#20001) -literals("reg4","reg4",#20179) -decl(#20179,#20132) +tokeninfo(#20172,4,#20001,54,"""(a""") +#20173=@"loc,{#10000},17,5,17,8" +locations_default(#20173,#10000,17,5,17,8) +hasLocation(#20172,#20173) +#20174=* +tokeninfo(#20174,8,#20001,55,"+") +#20175=@"loc,{#10000},17,10,17,10" +locations_default(#20175,#10000,17,10,17,10) +hasLocation(#20174,#20175) +#20176=* +tokeninfo(#20176,4,#20001,56,"""|""") +#20177=@"loc,{#10000},18,5,18,7" +locations_default(#20177,#10000,18,5,18,7) +hasLocation(#20176,#20177) +#20178=* +tokeninfo(#20178,8,#20001,57,"+") +#20179=@"loc,{#10000},18,9,18,9" +locations_default(#20179,#10000,18,9,18,9) +hasLocation(#20178,#20179) #20180=* -exprs(#20180,12,#20177,1,"new Reg ... ""qux""\n)") -#20181=@"loc,{#10000},9,12,14,1" -locations_default(#20181,#10000,9,12,14,1) +tokeninfo(#20180,4,#20001,58,"""aa)*""") +#20181=@"loc,{#10000},19,5,19,10" +locations_default(#20181,#10000,19,5,19,10) hasLocation(#20180,#20181) -enclosing_stmt(#20180,#20175) -expr_containers(#20180,#20001) #20182=* -exprs(#20182,79,#20180,-1,"RegExp") -hasLocation(#20182,#20105) -enclosing_stmt(#20182,#20175) -expr_containers(#20182,#20001) -literals("RegExp","RegExp",#20182) -bind(#20182,#20140) -#20183=* -exprs(#20183,34,#20180,0,"""foo"" + ... ""qux""") -#20184=@"loc,{#10000},10,5,13,9" -locations_default(#20184,#10000,10,5,13,9) -hasLocation(#20183,#20184) -enclosing_stmt(#20183,#20175) -expr_containers(#20183,#20001) -#20185=* -exprs(#20185,34,#20183,0,"""foo"" + ... ""baz""") -#20186=@"loc,{#10000},10,5,12,9" -locations_default(#20186,#10000,10,5,12,9) -hasLocation(#20185,#20186) -enclosing_stmt(#20185,#20175) -expr_containers(#20185,#20001) -#20187=* -exprs(#20187,34,#20185,0,"""foo"" + \n ""bar""") -#20188=@"loc,{#10000},10,5,11,9" -locations_default(#20188,#10000,10,5,11,9) -hasLocation(#20187,#20188) -enclosing_stmt(#20187,#20175) -expr_containers(#20187,#20001) -#20189=* -exprs(#20189,4,#20187,0,"""foo""") -hasLocation(#20189,#20109) -enclosing_stmt(#20189,#20175) -expr_containers(#20189,#20001) -literals("foo","""foo""",#20189) +tokeninfo(#20182,8,#20001,59,"+") +#20183=@"loc,{#10000},19,12,19,12" +locations_default(#20183,#10000,19,12,19,12) +hasLocation(#20182,#20183) +#20184=* +tokeninfo(#20184,4,#20001,60,"""b$""") +#20185=@"loc,{#10000},20,5,20,8" +locations_default(#20185,#10000,20,5,20,8) +hasLocation(#20184,#20185) +#20186=* +tokeninfo(#20186,8,#20001,61,")") +#20187=@"loc,{#10000},21,1,21,1" +locations_default(#20187,#10000,21,1,21,1) +hasLocation(#20186,#20187) +#20188=* +tokeninfo(#20188,8,#20001,62,";") +#20189=@"loc,{#10000},21,2,21,2" +locations_default(#20189,#10000,21,2,21,2) +hasLocation(#20188,#20189) #20190=* -exprs(#20190,4,#20187,1,"""bar""") -hasLocation(#20190,#20113) -enclosing_stmt(#20190,#20175) -expr_containers(#20190,#20001) -literals("bar","""bar""",#20190) -#20191=* -exprs(#20191,4,#20185,1,"""baz""") -hasLocation(#20191,#20117) -enclosing_stmt(#20191,#20175) -expr_containers(#20191,#20001) -literals("baz","""baz""",#20191) +tokeninfo(#20190,7,#20001,63,"var") +#20191=@"loc,{#10000},23,1,23,3" +locations_default(#20191,#10000,23,1,23,3) +hasLocation(#20190,#20191) #20192=* -exprs(#20192,4,#20183,1,"""qux""") -hasLocation(#20192,#20121) -enclosing_stmt(#20192,#20175) -expr_containers(#20192,#20001) -literals("qux","""qux""",#20192) -#20193=* -regexpterm(#20193,14,#20183,0,"foobarbazqux") -#20194=@"loc,{#10000},10,6,13,9" -locations_default(#20194,#10000,10,6,13,9) -hasLocation(#20193,#20194) -regexp_const_value(#20193,"foobarbazqux") -#20195=* -entry_cfg_node(#20195,#20001) -#20196=@"loc,{#10000},1,1,1,0" -locations_default(#20196,#10000,1,1,1,0) -hasLocation(#20195,#20196) -#20197=* -exit_cfg_node(#20197,#20001) -hasLocation(#20197,#20127) -successor(#20175,#20179) -successor(#20192,#20183) -successor(#20191,#20185) -successor(#20190,#20187) -successor(#20189,#20190) -successor(#20187,#20191) -successor(#20185,#20192) -successor(#20183,#20180) -successor(#20182,#20189) -successor(#20180,#20177) -successor(#20179,#20182) -successor(#20177,#20197) -successor(#20161,#20165) -successor(#20172,#20169) -successor(#20171,#20172) -successor(#20169,#20166) -successor(#20168,#20171) -successor(#20166,#20163) -successor(#20165,#20168) -successor(#20163,#20175) -successor(#20147,#20151) -successor(#20158,#20155) -successor(#20157,#20158) -successor(#20155,#20152) -successor(#20154,#20157) -successor(#20152,#20149) -successor(#20151,#20154) -successor(#20149,#20161) -successor(#20133,#20136) -successor(#20144,#20141) -successor(#20143,#20144) -successor(#20141,#20137) -successor(#20139,#20143) -successor(#20137,#20134) -successor(#20136,#20139) -successor(#20134,#20147) -successor(#20195,#20133) -numlines(#10000,14,11,0) +tokeninfo(#20192,6,#20001,64,"bad96") +#20193=@"loc,{#10000},23,5,23,9" +locations_default(#20193,#10000,23,5,23,9) +hasLocation(#20192,#20193) +#20194=* +tokeninfo(#20194,8,#20001,65,"=") +#20195=@"loc,{#10000},23,11,23,11" +locations_default(#20195,#10000,23,11,23,11) +hasLocation(#20194,#20195) +#20196=* +tokeninfo(#20196,7,#20001,66,"new") +#20197=@"loc,{#10000},23,13,23,15" +locations_default(#20197,#10000,23,13,23,15) +hasLocation(#20196,#20197) +#20198=* +tokeninfo(#20198,6,#20001,67,"RegExp") +#20199=@"loc,{#10000},23,17,23,22" +locations_default(#20199,#10000,23,17,23,22) +hasLocation(#20198,#20199) +#20200=* +tokeninfo(#20200,8,#20001,68,"(") +#20201=@"loc,{#10000},23,23,23,23" +locations_default(#20201,#10000,23,23,23,23) +hasLocation(#20200,#20201) +#20202=* +tokeninfo(#20202,4,#20001,69,"""(""") +#20203=@"loc,{#10000},23,24,23,26" +locations_default(#20203,#10000,23,24,23,26) +hasLocation(#20202,#20203) +#20204=* +tokeninfo(#20204,8,#20001,70,"+") +#20205=@"loc,{#10000},23,28,23,28" +locations_default(#20205,#10000,23,28,23,28) +hasLocation(#20204,#20205) +#20206=* +tokeninfo(#20206,4,#20001,71,"""(c|cc)*|""") +#20207=@"loc,{#10000},24,5,24,14" +locations_default(#20207,#10000,24,5,24,14) +hasLocation(#20206,#20207) +#20208=* +tokeninfo(#20208,8,#20001,72,"+") +#20209=@"loc,{#10000},24,16,24,16" +locations_default(#20209,#10000,24,16,24,16) +hasLocation(#20208,#20209) +#20210=* +tokeninfo(#20210,4,#20001,73,"""(d|dd)*|""") +#20211=@"loc,{#10000},25,5,25,14" +locations_default(#20211,#10000,25,5,25,14) +hasLocation(#20210,#20211) +#20212=* +tokeninfo(#20212,8,#20001,74,"+") +#20213=@"loc,{#10000},25,16,25,16" +locations_default(#20213,#10000,25,16,25,16) +hasLocation(#20212,#20213) +#20214=* +tokeninfo(#20214,4,#20001,75,"""(e|ee)*""") +#20215=@"loc,{#10000},26,5,26,13" +locations_default(#20215,#10000,26,5,26,13) +hasLocation(#20214,#20215) +#20216=* +tokeninfo(#20216,8,#20001,76,"+") +#20217=@"loc,{#10000},26,15,26,15" +locations_default(#20217,#10000,26,15,26,15) +hasLocation(#20216,#20217) +#20218=* +tokeninfo(#20218,4,#20001,77,""")f$""") +#20219=@"loc,{#10000},27,1,27,5" +locations_default(#20219,#10000,27,1,27,5) +hasLocation(#20218,#20219) +#20220=* +tokeninfo(#20220,8,#20001,78,")") +#20221=@"loc,{#10000},27,6,27,6" +locations_default(#20221,#10000,27,6,27,6) +hasLocation(#20220,#20221) +#20222=* +tokeninfo(#20222,8,#20001,79,";") +#20223=@"loc,{#10000},27,7,27,7" +locations_default(#20223,#10000,27,7,27,7) +hasLocation(#20222,#20223) +#20224=* +tokeninfo(#20224,7,#20001,80,"var") +#20225=@"loc,{#10000},29,1,29,3" +locations_default(#20225,#10000,29,1,29,3) +hasLocation(#20224,#20225) +#20226=* +tokeninfo(#20226,6,#20001,81,"bad97") +#20227=@"loc,{#10000},29,5,29,9" +locations_default(#20227,#10000,29,5,29,9) +hasLocation(#20226,#20227) +#20228=* +tokeninfo(#20228,8,#20001,82,"=") +#20229=@"loc,{#10000},29,11,29,11" +locations_default(#20229,#10000,29,11,29,11) +hasLocation(#20228,#20229) +#20230=* +tokeninfo(#20230,7,#20001,83,"new") +#20231=@"loc,{#10000},29,13,29,15" +locations_default(#20231,#10000,29,13,29,15) +hasLocation(#20230,#20231) +#20232=* +tokeninfo(#20232,6,#20001,84,"RegExp") +#20233=@"loc,{#10000},29,17,29,22" +locations_default(#20233,#10000,29,17,29,22) +hasLocation(#20232,#20233) +#20234=* +tokeninfo(#20234,8,#20001,85,"(") +#20235=@"loc,{#10000},29,23,29,23" +locations_default(#20235,#10000,29,23,29,23) +hasLocation(#20234,#20235) +#20236=* +tokeninfo(#20236,4,#20001,86,"""(g|gg""") +#20237=@"loc,{#10000},30,5,30,11" +locations_default(#20237,#10000,30,5,30,11) +hasLocation(#20236,#20237) +#20238=* +tokeninfo(#20238,8,#20001,87,"+") +#20239=@"loc,{#10000},30,13,30,13" +locations_default(#20239,#10000,30,13,30,13) +hasLocation(#20238,#20239) +#20240=* +tokeninfo(#20240,4,#20001,88,""")*h$""") +#20241=@"loc,{#10000},31,5,31,10" +locations_default(#20241,#10000,31,5,31,10) +hasLocation(#20240,#20241) +#20242=* +tokeninfo(#20242,8,#20001,89,")") +#20243=@"loc,{#10000},31,11,31,11" +locations_default(#20243,#10000,31,11,31,11) +hasLocation(#20242,#20243) +#20244=* +tokeninfo(#20244,8,#20001,90,";") +#20245=@"loc,{#10000},31,12,31,12" +locations_default(#20245,#10000,31,12,31,12) +hasLocation(#20244,#20245) +#20246=* +tokeninfo(#20246,0,#20001,91,"") +#20247=@"loc,{#10000},32,1,32,0" +locations_default(#20247,#10000,32,1,32,0) +hasLocation(#20246,#20247) +toplevels(#20001,0) +#20248=@"loc,{#10000},1,1,32,0" +locations_default(#20248,#10000,1,1,32,0) +hasLocation(#20001,#20248) +#20249=@"var;{reg};{#20000}" +variables(#20249,"reg",#20000) +#20250=@"var;{reg2};{#20000}" +variables(#20250,"reg2",#20000) +#20251=@"var;{reg3};{#20000}" +variables(#20251,"reg3",#20000) +#20252=@"var;{reg4};{#20000}" +variables(#20252,"reg4",#20000) +#20253=@"var;{bad95};{#20000}" +variables(#20253,"bad95",#20000) +#20254=@"var;{bad96};{#20000}" +variables(#20254,"bad96",#20000) +#20255=@"var;{bad97};{#20000}" +variables(#20255,"bad97",#20000) +#20256=* +stmts(#20256,18,#20001,0,"var reg ... ""bar"");") +hasLocation(#20256,#20003) +stmt_containers(#20256,#20001) +#20257=* +exprs(#20257,64,#20256,0,"reg = n ... ""bar"")") +#20258=@"loc,{#10000},1,5,1,35" +locations_default(#20258,#10000,1,5,1,35) +hasLocation(#20257,#20258) +enclosing_stmt(#20257,#20256) +expr_containers(#20257,#20001) +#20259=* +exprs(#20259,78,#20257,0,"reg") +hasLocation(#20259,#20067) +enclosing_stmt(#20259,#20256) +expr_containers(#20259,#20001) +literals("reg","reg",#20259) +decl(#20259,#20249) +#20260=* +exprs(#20260,12,#20257,1,"new Reg ... ""bar"")") +#20261=@"loc,{#10000},1,11,1,35" +locations_default(#20261,#10000,1,11,1,35) +hasLocation(#20260,#20261) +enclosing_stmt(#20260,#20256) +expr_containers(#20260,#20001) +#20262=* +exprs(#20262,79,#20260,-1,"RegExp") +hasLocation(#20262,#20073) +enclosing_stmt(#20262,#20256) +expr_containers(#20262,#20001) +literals("RegExp","RegExp",#20262) +#20263=@"var;{RegExp};{#20000}" +variables(#20263,"RegExp",#20000) +bind(#20262,#20263) +#20264=* +exprs(#20264,34,#20260,0,"""foo"" + ""bar""") +#20265=@"loc,{#10000},1,22,1,34" +locations_default(#20265,#10000,1,22,1,34) +hasLocation(#20264,#20265) +enclosing_stmt(#20264,#20256) +expr_containers(#20264,#20001) +#20266=* +exprs(#20266,4,#20264,0,"""foo""") +hasLocation(#20266,#20077) +enclosing_stmt(#20266,#20256) +expr_containers(#20266,#20001) +literals("foo","""foo""",#20266) +#20267=* +exprs(#20267,4,#20264,1,"""bar""") +hasLocation(#20267,#20081) +enclosing_stmt(#20267,#20256) +expr_containers(#20267,#20001) +literals("bar","""bar""",#20267) +#20268=* +regexpterm(#20268,14,#20264,0,"foobar") +#20269=@"loc,{#10000},1,23,1,33" +locations_default(#20269,#10000,1,23,1,33) +hasLocation(#20268,#20269) +regexp_const_value(#20268,"foobar") +#20270=* +stmts(#20270,18,#20001,1,"var reg ... ""bar"");") +#20271=@"loc,{#10000},3,1,4,13" +locations_default(#20271,#10000,3,1,4,13) +hasLocation(#20270,#20271) +stmt_containers(#20270,#20001) +#20272=* +exprs(#20272,64,#20270,0,"reg2 = ... ""bar"")") +#20273=@"loc,{#10000},3,5,4,12" +locations_default(#20273,#10000,3,5,4,12) +hasLocation(#20272,#20273) +enclosing_stmt(#20272,#20270) +expr_containers(#20272,#20001) +#20274=* +exprs(#20274,78,#20272,0,"reg2") +hasLocation(#20274,#20089) +enclosing_stmt(#20274,#20270) +expr_containers(#20274,#20001) +literals("reg2","reg2",#20274) +decl(#20274,#20250) +#20275=* +exprs(#20275,12,#20272,1,"new Reg ... ""bar"")") +#20276=@"loc,{#10000},3,12,4,12" +locations_default(#20276,#10000,3,12,4,12) +hasLocation(#20275,#20276) +enclosing_stmt(#20275,#20270) +expr_containers(#20275,#20001) +#20277=* +exprs(#20277,79,#20275,-1,"RegExp") +hasLocation(#20277,#20095) +enclosing_stmt(#20277,#20270) +expr_containers(#20277,#20001) +literals("RegExp","RegExp",#20277) +bind(#20277,#20263) +#20278=* +exprs(#20278,34,#20275,0,"""foo""\n + ""bar""") +#20279=@"loc,{#10000},3,23,4,11" +locations_default(#20279,#10000,3,23,4,11) +hasLocation(#20278,#20279) +enclosing_stmt(#20278,#20270) +expr_containers(#20278,#20001) +#20280=* +exprs(#20280,4,#20278,0,"""foo""") +hasLocation(#20280,#20099) +enclosing_stmt(#20280,#20270) +expr_containers(#20280,#20001) +literals("foo","""foo""",#20280) +#20281=* +exprs(#20281,4,#20278,1,"""bar""") +hasLocation(#20281,#20103) +enclosing_stmt(#20281,#20270) +expr_containers(#20281,#20001) +literals("bar","""bar""",#20281) +#20282=* +regexpterm(#20282,14,#20278,0,"foobar") +#20283=@"loc,{#10000},3,24,4,10" +locations_default(#20283,#10000,3,24,4,10) +hasLocation(#20282,#20283) +regexp_const_value(#20282,"foobar") +#20284=* +stmts(#20284,18,#20001,2,"var reg ... ""bar"");") +#20285=@"loc,{#10000},6,1,7,19" +locations_default(#20285,#10000,6,1,7,19) +hasLocation(#20284,#20285) +stmt_containers(#20284,#20001) +#20286=* +exprs(#20286,64,#20284,0,"reg3 = ... ""bar"")") +#20287=@"loc,{#10000},6,5,7,18" +locations_default(#20287,#10000,6,5,7,18) +hasLocation(#20286,#20287) +enclosing_stmt(#20286,#20284) +expr_containers(#20286,#20001) +#20288=* +exprs(#20288,78,#20286,0,"reg3") +hasLocation(#20288,#20111) +enclosing_stmt(#20288,#20284) +expr_containers(#20288,#20001) +literals("reg3","reg3",#20288) +decl(#20288,#20251) +#20289=* +exprs(#20289,12,#20286,1,"new Reg ... ""bar"")") +#20290=@"loc,{#10000},6,12,7,18" +locations_default(#20290,#10000,6,12,7,18) +hasLocation(#20289,#20290) +enclosing_stmt(#20289,#20284) +expr_containers(#20289,#20001) +#20291=* +exprs(#20291,79,#20289,-1,"RegExp") +hasLocation(#20291,#20117) +enclosing_stmt(#20291,#20284) +expr_containers(#20291,#20001) +literals("RegExp","RegExp",#20291) +bind(#20291,#20263) +#20292=* +exprs(#20292,34,#20289,0,"""foo"" + ""bar""") +#20293=@"loc,{#10000},7,5,7,17" +locations_default(#20293,#10000,7,5,7,17) +hasLocation(#20292,#20293) +enclosing_stmt(#20292,#20284) +expr_containers(#20292,#20001) +#20294=* +exprs(#20294,4,#20292,0,"""foo""") +hasLocation(#20294,#20121) +enclosing_stmt(#20294,#20284) +expr_containers(#20294,#20001) +literals("foo","""foo""",#20294) +#20295=* +exprs(#20295,4,#20292,1,"""bar""") +hasLocation(#20295,#20125) +enclosing_stmt(#20295,#20284) +expr_containers(#20295,#20001) +literals("bar","""bar""",#20295) +#20296=* +regexpterm(#20296,14,#20292,0,"foobar") +#20297=@"loc,{#10000},7,6,7,16" +locations_default(#20297,#10000,7,6,7,16) +hasLocation(#20296,#20297) +regexp_const_value(#20296,"foobar") +#20298=* +stmts(#20298,18,#20001,3,"var reg ... qux""\n);") +#20299=@"loc,{#10000},9,1,14,2" +locations_default(#20299,#10000,9,1,14,2) +hasLocation(#20298,#20299) +stmt_containers(#20298,#20001) +#20300=* +exprs(#20300,64,#20298,0,"reg4 = ... ""qux""\n)") +#20301=@"loc,{#10000},9,5,14,1" +locations_default(#20301,#10000,9,5,14,1) +hasLocation(#20300,#20301) +enclosing_stmt(#20300,#20298) +expr_containers(#20300,#20001) +#20302=* +exprs(#20302,78,#20300,0,"reg4") +hasLocation(#20302,#20133) +enclosing_stmt(#20302,#20298) +expr_containers(#20302,#20001) +literals("reg4","reg4",#20302) +decl(#20302,#20252) +#20303=* +exprs(#20303,12,#20300,1,"new Reg ... ""qux""\n)") +#20304=@"loc,{#10000},9,12,14,1" +locations_default(#20304,#10000,9,12,14,1) +hasLocation(#20303,#20304) +enclosing_stmt(#20303,#20298) +expr_containers(#20303,#20001) +#20305=* +exprs(#20305,79,#20303,-1,"RegExp") +hasLocation(#20305,#20139) +enclosing_stmt(#20305,#20298) +expr_containers(#20305,#20001) +literals("RegExp","RegExp",#20305) +bind(#20305,#20263) +#20306=* +exprs(#20306,34,#20303,0,"""foo"" + ... ""qux""") +#20307=@"loc,{#10000},10,5,13,9" +locations_default(#20307,#10000,10,5,13,9) +hasLocation(#20306,#20307) +enclosing_stmt(#20306,#20298) +expr_containers(#20306,#20001) +#20308=* +exprs(#20308,34,#20306,0,"""foo"" + ... ""baz""") +#20309=@"loc,{#10000},10,5,12,9" +locations_default(#20309,#10000,10,5,12,9) +hasLocation(#20308,#20309) +enclosing_stmt(#20308,#20298) +expr_containers(#20308,#20001) +#20310=* +exprs(#20310,34,#20308,0,"""foo"" + \n ""bar""") +#20311=@"loc,{#10000},10,5,11,9" +locations_default(#20311,#10000,10,5,11,9) +hasLocation(#20310,#20311) +enclosing_stmt(#20310,#20298) +expr_containers(#20310,#20001) +#20312=* +exprs(#20312,4,#20310,0,"""foo""") +hasLocation(#20312,#20143) +enclosing_stmt(#20312,#20298) +expr_containers(#20312,#20001) +literals("foo","""foo""",#20312) +#20313=* +exprs(#20313,4,#20310,1,"""bar""") +hasLocation(#20313,#20147) +enclosing_stmt(#20313,#20298) +expr_containers(#20313,#20001) +literals("bar","""bar""",#20313) +#20314=* +exprs(#20314,4,#20308,1,"""baz""") +hasLocation(#20314,#20151) +enclosing_stmt(#20314,#20298) +expr_containers(#20314,#20001) +literals("baz","""baz""",#20314) +#20315=* +exprs(#20315,4,#20306,1,"""qux""") +hasLocation(#20315,#20155) +enclosing_stmt(#20315,#20298) +expr_containers(#20315,#20001) +literals("qux","""qux""",#20315) +#20316=* +regexpterm(#20316,14,#20306,0,"foobarbazqux") +#20317=@"loc,{#10000},10,6,13,8" +locations_default(#20317,#10000,10,6,13,8) +hasLocation(#20316,#20317) +regexp_const_value(#20316,"foobarbazqux") +#20318=* +stmts(#20318,18,#20001,4,"var bad ... ""b$""\n);") +#20319=@"loc,{#10000},16,1,21,2" +locations_default(#20319,#10000,16,1,21,2) +hasLocation(#20318,#20319) +stmt_containers(#20318,#20001) +#20320=* +exprs(#20320,64,#20318,0,"bad95 = ... ""b$""\n)") +#20321=@"loc,{#10000},16,5,21,1" +locations_default(#20321,#10000,16,5,21,1) +hasLocation(#20320,#20321) +enclosing_stmt(#20320,#20318) +expr_containers(#20320,#20001) +#20322=* +exprs(#20322,78,#20320,0,"bad95") +hasLocation(#20322,#20163) +enclosing_stmt(#20322,#20318) +expr_containers(#20322,#20001) +literals("bad95","bad95",#20322) +decl(#20322,#20253) +#20323=* +exprs(#20323,12,#20320,1,"new Reg ... ""b$""\n)") +#20324=@"loc,{#10000},16,13,21,1" +locations_default(#20324,#10000,16,13,21,1) +hasLocation(#20323,#20324) +enclosing_stmt(#20323,#20318) +expr_containers(#20323,#20001) +#20325=* +exprs(#20325,79,#20323,-1,"RegExp") +hasLocation(#20325,#20169) +enclosing_stmt(#20325,#20318) +expr_containers(#20325,#20001) +literals("RegExp","RegExp",#20325) +bind(#20325,#20263) +#20326=* +exprs(#20326,34,#20323,0,"""(a"" + ... ""b$""") +#20327=@"loc,{#10000},17,5,20,8" +locations_default(#20327,#10000,17,5,20,8) +hasLocation(#20326,#20327) +enclosing_stmt(#20326,#20318) +expr_containers(#20326,#20001) +#20328=* +exprs(#20328,34,#20326,0,"""(a"" + ... ""aa)*""") +#20329=@"loc,{#10000},17,5,19,10" +locations_default(#20329,#10000,17,5,19,10) +hasLocation(#20328,#20329) +enclosing_stmt(#20328,#20318) +expr_containers(#20328,#20001) +#20330=* +exprs(#20330,34,#20328,0,"""(a"" + \n ""|""") +#20331=@"loc,{#10000},17,5,18,7" +locations_default(#20331,#10000,17,5,18,7) +hasLocation(#20330,#20331) +enclosing_stmt(#20330,#20318) +expr_containers(#20330,#20001) +#20332=* +exprs(#20332,4,#20330,0,"""(a""") +hasLocation(#20332,#20173) +enclosing_stmt(#20332,#20318) +expr_containers(#20332,#20001) +literals("(a","""(a""",#20332) +#20333=* +exprs(#20333,4,#20330,1,"""|""") +hasLocation(#20333,#20177) +enclosing_stmt(#20333,#20318) +expr_containers(#20333,#20001) +literals("|","""|""",#20333) +#20334=* +exprs(#20334,4,#20328,1,"""aa)*""") +hasLocation(#20334,#20181) +enclosing_stmt(#20334,#20318) +expr_containers(#20334,#20001) +literals("aa)*","""aa)*""",#20334) +#20335=* +exprs(#20335,4,#20326,1,"""b$""") +hasLocation(#20335,#20185) +enclosing_stmt(#20335,#20318) +expr_containers(#20335,#20001) +literals("b$","""b$""",#20335) +#20336=* +regexpterm(#20336,1,#20326,0,"(a|aa)*b$") +#20337=@"loc,{#10000},17,6,20,7" +locations_default(#20337,#10000,17,6,20,7) +hasLocation(#20336,#20337) +#20338=* +regexpterm(#20338,8,#20336,0,"(a|aa)*") +#20339=@"loc,{#10000},17,6,20,5" +locations_default(#20339,#10000,17,6,20,5) +hasLocation(#20338,#20339) +is_greedy(#20338) +#20340=* +regexpterm(#20340,13,#20338,0,"(a|aa)") +#20341=@"loc,{#10000},17,6,19,8" +locations_default(#20341,#10000,17,6,19,8) +hasLocation(#20340,#20341) +is_capture(#20340,1) +#20342=* +regexpterm(#20342,0,#20340,0,"a|aa") +#20343=@"loc,{#10000},17,7,19,7" +locations_default(#20343,#10000,17,7,19,7) +hasLocation(#20342,#20343) +#20344=* +regexpterm(#20344,14,#20342,0,"a") +#20345=@"loc,{#10000},17,7,18,5" +locations_default(#20345,#10000,17,7,18,5) +hasLocation(#20344,#20345) +regexp_const_value(#20344,"a") +#20346=* +regexpterm(#20346,14,#20342,1,"aa") +#20347=@"loc,{#10000},19,6,19,7" +locations_default(#20347,#10000,19,6,19,7) +hasLocation(#20346,#20347) +regexp_const_value(#20346,"aa") +#20348=* +regexpterm(#20348,14,#20336,1,"b") +#20349=@"loc,{#10000},20,6,20,6" +locations_default(#20349,#10000,20,6,20,6) +hasLocation(#20348,#20349) +regexp_const_value(#20348,"b") +#20350=* +regexpterm(#20350,3,#20336,2,"$") +#20351=@"loc,{#10000},20,7,20,7" +locations_default(#20351,#10000,20,7,20,7) +hasLocation(#20350,#20351) +#20352=* +stmts(#20352,18,#20001,5,"var bad ... "")f$"");") +#20353=@"loc,{#10000},23,1,27,7" +locations_default(#20353,#10000,23,1,27,7) +hasLocation(#20352,#20353) +stmt_containers(#20352,#20001) +#20354=* +exprs(#20354,64,#20352,0,"bad96 = ... \n"")f$"")") +#20355=@"loc,{#10000},23,5,27,6" +locations_default(#20355,#10000,23,5,27,6) +hasLocation(#20354,#20355) +enclosing_stmt(#20354,#20352) +expr_containers(#20354,#20001) +#20356=* +exprs(#20356,78,#20354,0,"bad96") +hasLocation(#20356,#20193) +enclosing_stmt(#20356,#20352) +expr_containers(#20356,#20001) +literals("bad96","bad96",#20356) +decl(#20356,#20254) +#20357=* +exprs(#20357,12,#20354,1,"new Reg ... \n"")f$"")") +#20358=@"loc,{#10000},23,13,27,6" +locations_default(#20358,#10000,23,13,27,6) +hasLocation(#20357,#20358) +enclosing_stmt(#20357,#20352) +expr_containers(#20357,#20001) +#20359=* +exprs(#20359,79,#20357,-1,"RegExp") +hasLocation(#20359,#20199) +enclosing_stmt(#20359,#20352) +expr_containers(#20359,#20001) +literals("RegExp","RegExp",#20359) +bind(#20359,#20263) +#20360=* +exprs(#20360,34,#20357,0,"""("" + \n ... +\n"")f$""") +#20361=@"loc,{#10000},23,24,27,5" +locations_default(#20361,#10000,23,24,27,5) +hasLocation(#20360,#20361) +enclosing_stmt(#20360,#20352) +expr_containers(#20360,#20001) +#20362=* +exprs(#20362,34,#20360,0,"""("" + \n ... e|ee)*""") +#20363=@"loc,{#10000},23,24,26,13" +locations_default(#20363,#10000,23,24,26,13) +hasLocation(#20362,#20363) +enclosing_stmt(#20362,#20352) +expr_containers(#20362,#20001) +#20364=* +exprs(#20364,34,#20362,0,"""("" + \n ... |dd)*|""") +#20365=@"loc,{#10000},23,24,25,14" +locations_default(#20365,#10000,23,24,25,14) +hasLocation(#20364,#20365) +enclosing_stmt(#20364,#20352) +expr_containers(#20364,#20001) +#20366=* +exprs(#20366,34,#20364,0,"""("" + \n ... |cc)*|""") +#20367=@"loc,{#10000},23,24,24,14" +locations_default(#20367,#10000,23,24,24,14) +hasLocation(#20366,#20367) +enclosing_stmt(#20366,#20352) +expr_containers(#20366,#20001) +#20368=* +exprs(#20368,4,#20366,0,"""(""") +hasLocation(#20368,#20203) +enclosing_stmt(#20368,#20352) +expr_containers(#20368,#20001) +literals("(","""(""",#20368) +#20369=* +exprs(#20369,4,#20366,1,"""(c|cc)*|""") +hasLocation(#20369,#20207) +enclosing_stmt(#20369,#20352) +expr_containers(#20369,#20001) +literals("(c|cc)*|","""(c|cc)*|""",#20369) +#20370=* +exprs(#20370,4,#20364,1,"""(d|dd)*|""") +hasLocation(#20370,#20211) +enclosing_stmt(#20370,#20352) +expr_containers(#20370,#20001) +literals("(d|dd)*|","""(d|dd)*|""",#20370) +#20371=* +exprs(#20371,4,#20362,1,"""(e|ee)*""") +hasLocation(#20371,#20215) +enclosing_stmt(#20371,#20352) +expr_containers(#20371,#20001) +literals("(e|ee)*","""(e|ee)*""",#20371) +#20372=* +exprs(#20372,4,#20360,1,""")f$""") +hasLocation(#20372,#20219) +enclosing_stmt(#20372,#20352) +expr_containers(#20372,#20001) +literals(")f$",""")f$""",#20372) +#20373=* +regexpterm(#20373,1,#20360,0,"((c|cc)*|(d|dd)*|(e|ee)*)f$") +#20374=@"loc,{#10000},23,25,27,4" +locations_default(#20374,#10000,23,25,27,4) +hasLocation(#20373,#20374) +#20375=* +regexpterm(#20375,13,#20373,0,"((c|cc)*|(d|dd)*|(e|ee)*)") +#20376=@"loc,{#10000},23,25,27,2" +locations_default(#20376,#10000,23,25,27,2) +hasLocation(#20375,#20376) +is_capture(#20375,1) +#20377=* +regexpterm(#20377,0,#20375,0,"(c|cc)*|(d|dd)*|(e|ee)*") +#20378=@"loc,{#10000},24,6,27,1" +locations_default(#20378,#10000,24,6,27,1) +hasLocation(#20377,#20378) +#20379=* +regexpterm(#20379,8,#20377,0,"(c|cc)*") +#20380=@"loc,{#10000},24,6,24,12" +locations_default(#20380,#10000,24,6,24,12) +hasLocation(#20379,#20380) +is_greedy(#20379) +#20381=* +regexpterm(#20381,13,#20379,0,"(c|cc)") +#20382=@"loc,{#10000},24,6,24,11" +locations_default(#20382,#10000,24,6,24,11) +hasLocation(#20381,#20382) +is_capture(#20381,2) +#20383=* +regexpterm(#20383,0,#20381,0,"c|cc") +#20384=@"loc,{#10000},24,7,24,10" +locations_default(#20384,#10000,24,7,24,10) +hasLocation(#20383,#20384) +#20385=* +regexpterm(#20385,14,#20383,0,"c") +#20386=@"loc,{#10000},24,7,24,7" +locations_default(#20386,#10000,24,7,24,7) +hasLocation(#20385,#20386) +regexp_const_value(#20385,"c") +#20387=* +regexpterm(#20387,14,#20383,1,"cc") +#20388=@"loc,{#10000},24,9,24,10" +locations_default(#20388,#10000,24,9,24,10) +hasLocation(#20387,#20388) +regexp_const_value(#20387,"cc") +#20389=* +regexpterm(#20389,8,#20377,1,"(d|dd)*") +#20390=@"loc,{#10000},25,6,25,12" +locations_default(#20390,#10000,25,6,25,12) +hasLocation(#20389,#20390) +is_greedy(#20389) +#20391=* +regexpterm(#20391,13,#20389,0,"(d|dd)") +#20392=@"loc,{#10000},25,6,25,11" +locations_default(#20392,#10000,25,6,25,11) +hasLocation(#20391,#20392) +is_capture(#20391,3) +#20393=* +regexpterm(#20393,0,#20391,0,"d|dd") +#20394=@"loc,{#10000},25,7,25,10" +locations_default(#20394,#10000,25,7,25,10) +hasLocation(#20393,#20394) +#20395=* +regexpterm(#20395,14,#20393,0,"d") +#20396=@"loc,{#10000},25,7,25,7" +locations_default(#20396,#10000,25,7,25,7) +hasLocation(#20395,#20396) +regexp_const_value(#20395,"d") +#20397=* +regexpterm(#20397,14,#20393,1,"dd") +#20398=@"loc,{#10000},25,9,25,10" +locations_default(#20398,#10000,25,9,25,10) +hasLocation(#20397,#20398) +regexp_const_value(#20397,"dd") +#20399=* +regexpterm(#20399,8,#20377,2,"(e|ee)*") +#20400=@"loc,{#10000},26,6,27,1" +locations_default(#20400,#10000,26,6,27,1) +hasLocation(#20399,#20400) +is_greedy(#20399) +#20401=* +regexpterm(#20401,13,#20399,0,"(e|ee)") +#20402=@"loc,{#10000},26,6,26,11" +locations_default(#20402,#10000,26,6,26,11) +hasLocation(#20401,#20402) +is_capture(#20401,4) +#20403=* +regexpterm(#20403,0,#20401,0,"e|ee") +#20404=@"loc,{#10000},26,7,26,10" +locations_default(#20404,#10000,26,7,26,10) +hasLocation(#20403,#20404) +#20405=* +regexpterm(#20405,14,#20403,0,"e") +#20406=@"loc,{#10000},26,7,26,7" +locations_default(#20406,#10000,26,7,26,7) +hasLocation(#20405,#20406) +regexp_const_value(#20405,"e") +#20407=* +regexpterm(#20407,14,#20403,1,"ee") +#20408=@"loc,{#10000},26,9,26,10" +locations_default(#20408,#10000,26,9,26,10) +hasLocation(#20407,#20408) +regexp_const_value(#20407,"ee") +#20409=* +regexpterm(#20409,14,#20373,1,"f") +#20410=@"loc,{#10000},27,3,27,3" +locations_default(#20410,#10000,27,3,27,3) +hasLocation(#20409,#20410) +regexp_const_value(#20409,"f") +#20411=* +regexpterm(#20411,3,#20373,2,"$") +#20412=@"loc,{#10000},27,4,27,4" +locations_default(#20412,#10000,27,4,27,4) +hasLocation(#20411,#20412) +#20413=* +stmts(#20413,18,#20001,6,"var bad ... )*h$"");") +#20414=@"loc,{#10000},29,1,31,12" +locations_default(#20414,#10000,29,1,31,12) +hasLocation(#20413,#20414) +stmt_containers(#20413,#20001) +#20415=* +exprs(#20415,64,#20413,0,"bad97 = ... "")*h$"")") +#20416=@"loc,{#10000},29,5,31,11" +locations_default(#20416,#10000,29,5,31,11) +hasLocation(#20415,#20416) +enclosing_stmt(#20415,#20413) +expr_containers(#20415,#20001) +#20417=* +exprs(#20417,78,#20415,0,"bad97") +hasLocation(#20417,#20227) +enclosing_stmt(#20417,#20413) +expr_containers(#20417,#20001) +literals("bad97","bad97",#20417) +decl(#20417,#20255) +#20418=* +exprs(#20418,12,#20415,1,"new Reg ... "")*h$"")") +#20419=@"loc,{#10000},29,13,31,11" +locations_default(#20419,#10000,29,13,31,11) +hasLocation(#20418,#20419) +enclosing_stmt(#20418,#20413) +expr_containers(#20418,#20001) +#20420=* +exprs(#20420,79,#20418,-1,"RegExp") +hasLocation(#20420,#20233) +enclosing_stmt(#20420,#20413) +expr_containers(#20420,#20001) +literals("RegExp","RegExp",#20420) +bind(#20420,#20263) +#20421=* +exprs(#20421,34,#20418,0,"""(g|gg"" ... "")*h$""") +#20422=@"loc,{#10000},30,5,31,10" +locations_default(#20422,#10000,30,5,31,10) +hasLocation(#20421,#20422) +enclosing_stmt(#20421,#20413) +expr_containers(#20421,#20001) +#20423=* +exprs(#20423,4,#20421,0,"""(g|gg""") +hasLocation(#20423,#20237) +enclosing_stmt(#20423,#20413) +expr_containers(#20423,#20001) +literals("(g|gg","""(g|gg""",#20423) +#20424=* +exprs(#20424,4,#20421,1,""")*h$""") +hasLocation(#20424,#20241) +enclosing_stmt(#20424,#20413) +expr_containers(#20424,#20001) +literals(")*h$",""")*h$""",#20424) +#20425=* +regexpterm(#20425,1,#20421,0,"(g|gg)*h$") +#20426=@"loc,{#10000},30,6,31,9" +locations_default(#20426,#10000,30,6,31,9) +hasLocation(#20425,#20426) +#20427=* +regexpterm(#20427,8,#20425,0,"(g|gg)*") +#20428=@"loc,{#10000},30,6,31,7" +locations_default(#20428,#10000,30,6,31,7) +hasLocation(#20427,#20428) +is_greedy(#20427) +#20429=* +regexpterm(#20429,13,#20427,0,"(g|gg)") +#20430=@"loc,{#10000},30,6,31,6" +locations_default(#20430,#10000,30,6,31,6) +hasLocation(#20429,#20430) +is_capture(#20429,1) +#20431=* +regexpterm(#20431,0,#20429,0,"g|gg") +#20432=@"loc,{#10000},30,7,31,5" +locations_default(#20432,#10000,30,7,31,5) +hasLocation(#20431,#20432) +#20433=* +regexpterm(#20433,14,#20431,0,"g") +#20434=@"loc,{#10000},30,7,30,7" +locations_default(#20434,#10000,30,7,30,7) +hasLocation(#20433,#20434) +regexp_const_value(#20433,"g") +#20435=* +regexpterm(#20435,14,#20431,1,"gg") +#20436=@"loc,{#10000},30,9,31,5" +locations_default(#20436,#10000,30,9,31,5) +hasLocation(#20435,#20436) +regexp_const_value(#20435,"gg") +#20437=* +regexpterm(#20437,14,#20425,1,"h") +#20438=@"loc,{#10000},31,8,31,8" +locations_default(#20438,#10000,31,8,31,8) +hasLocation(#20437,#20438) +regexp_const_value(#20437,"h") +#20439=* +regexpterm(#20439,3,#20425,2,"$") +#20440=@"loc,{#10000},31,9,31,9" +locations_default(#20440,#10000,31,9,31,9) +hasLocation(#20439,#20440) +#20441=* +entry_cfg_node(#20441,#20001) +#20442=@"loc,{#10000},1,1,1,0" +locations_default(#20442,#10000,1,1,1,0) +hasLocation(#20441,#20442) +#20443=* +exit_cfg_node(#20443,#20001) +hasLocation(#20443,#20247) +successor(#20413,#20417) +successor(#20424,#20421) +successor(#20423,#20424) +successor(#20421,#20418) +successor(#20420,#20423) +successor(#20418,#20415) +successor(#20417,#20420) +successor(#20415,#20443) +successor(#20352,#20356) +successor(#20372,#20360) +successor(#20371,#20362) +successor(#20370,#20364) +successor(#20369,#20366) +successor(#20368,#20369) +successor(#20366,#20370) +successor(#20364,#20371) +successor(#20362,#20372) +successor(#20360,#20357) +successor(#20359,#20368) +successor(#20357,#20354) +successor(#20356,#20359) +successor(#20354,#20413) +successor(#20318,#20322) +successor(#20335,#20326) +successor(#20334,#20328) +successor(#20333,#20330) +successor(#20332,#20333) +successor(#20330,#20334) +successor(#20328,#20335) +successor(#20326,#20323) +successor(#20325,#20332) +successor(#20323,#20320) +successor(#20322,#20325) +successor(#20320,#20352) +successor(#20298,#20302) +successor(#20315,#20306) +successor(#20314,#20308) +successor(#20313,#20310) +successor(#20312,#20313) +successor(#20310,#20314) +successor(#20308,#20315) +successor(#20306,#20303) +successor(#20305,#20312) +successor(#20303,#20300) +successor(#20302,#20305) +successor(#20300,#20318) +successor(#20284,#20288) +successor(#20295,#20292) +successor(#20294,#20295) +successor(#20292,#20289) +successor(#20291,#20294) +successor(#20289,#20286) +successor(#20288,#20291) +successor(#20286,#20298) +successor(#20270,#20274) +successor(#20281,#20278) +successor(#20280,#20281) +successor(#20278,#20275) +successor(#20277,#20280) +successor(#20275,#20272) +successor(#20274,#20277) +successor(#20272,#20284) +successor(#20256,#20259) +successor(#20267,#20264) +successor(#20266,#20267) +successor(#20264,#20260) +successor(#20262,#20266) +successor(#20260,#20257) +successor(#20259,#20262) +successor(#20257,#20270) +successor(#20441,#20256) +numlines(#10000,31,25,0) filetype(#10000,"javascript") diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected index a68bc2b1924..85a029e4b87 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected +++ b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected @@ -512,8 +512,8 @@ | tst.js:384:15:384:26 | ([AB]\|[ab])* | Strings with many repetitions of 'A' can start matching anywhere after the start of the preceeding ([AB]\|[ab])*C | | tst.js:385:14:385:25 | ([DE]\|[de])* | Strings with many repetitions of 'd' can start matching anywhere after the start of the preceeding ([DE]\|[de])*F | | tst.js:388:14:388:20 | (a\|aa)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a\|aa)*$ | -| tst.js:391:6:394:6 | (a\|aa)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a\|aa)*b$ | -| tst.js:398:7:399:5 | (c\|cc)* | Strings with many repetitions of 'c' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | -| tst.js:399:7:400:5 | (d\|dd)* | Strings with many repetitions of 'd' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | -| tst.js:400:7:401:2 | (e\|ee)* | Strings with many repetitions of 'e' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | -| tst.js:404:6:405:8 | (g\|gg)* | Strings with many repetitions of 'g' can start matching anywhere after the start of the preceeding (g\|gg)*h$ | +| tst.js:391:6:394:5 | (a\|aa)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a\|aa)*b$ | +| tst.js:398:6:398:12 | (c\|cc)* | Strings with many repetitions of 'c' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | +| tst.js:399:6:399:12 | (d\|dd)* | Strings with many repetitions of 'd' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | +| tst.js:400:6:401:1 | (e\|ee)* | Strings with many repetitions of 'e' can start matching anywhere after the start of the preceeding ((c\|cc)*\|(d\|dd)*\|(e\|ee)*)f$ | +| tst.js:404:6:405:7 | (g\|gg)* | Strings with many repetitions of 'g' can start matching anywhere after the start of the preceeding (g\|gg)*h$ | diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected b/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected index b8ed9c86150..7319e306e62 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected +++ b/javascript/ql/test/query-tests/Performance/ReDoS/ReDoS.expected @@ -183,8 +183,8 @@ | tst.js:385:14:385:25 | ([DE]\|[de])* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'd'. | | tst.js:387:27:387:33 | (a\|aa)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'. | | tst.js:388:14:388:20 | (a\|aa)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'. | -| tst.js:391:6:394:6 | (a\|aa)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'. | -| tst.js:398:7:399:5 | (c\|cc)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'cc'. | -| tst.js:399:7:400:5 | (d\|dd)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'dd'. | -| tst.js:400:7:401:2 | (e\|ee)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'ee'. | -| tst.js:404:6:405:8 | (g\|gg)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'gg'. | +| tst.js:391:6:394:5 | (a\|aa)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'. | +| tst.js:398:6:398:12 | (c\|cc)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'cc'. | +| tst.js:399:6:399:12 | (d\|dd)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'dd'. | +| tst.js:400:6:401:1 | (e\|ee)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'ee'. | +| tst.js:404:6:405:7 | (g\|gg)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'gg'. | From 0023b885f53d41f10f02e92c42fa4cced70bbb9d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 15 Nov 2021 13:50:12 +0100 Subject: [PATCH 10/10] update expected output --- .../Security/CWE-020/IncompleteHostnameRegExp.expected | 7 ++++--- .../Security/CWE-020/tst-IncompleteHostnameRegExp.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected index 4911f159e47..13950be73ba 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected @@ -15,11 +15,12 @@ | tst-IncompleteHostnameRegExp.js:38:3:38:43 | ^(http\|https):\\/\\/www.example.com\\/p\\/f\\/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:38:2:38:44 | /^(http ... p\\/f\\// | here | | tst-IncompleteHostnameRegExp.js:39:5:39:30 | http:\\/\\/sub.example.com\\/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:39:2:39:33 | /^(http ... om\\/)/g | here | | tst-IncompleteHostnameRegExp.js:40:3:40:29 | ^https?:\\/\\/api.example.com | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:40:2:40:30 | /^https ... le.com/ | here | -| tst-IncompleteHostnameRegExp.js:41:42:41:70 | ^https?://.+\\.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:41:13:41:71 | '^http: ... \\.com/' | here | +| tst-IncompleteHostnameRegExp.js:41:42:41:48 | ^https?://.+\\.example\\.com/ | This regular expression has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:41:13:41:71 | '^http: ... \\.com/' | here | | tst-IncompleteHostnameRegExp.js:43:3:43:32 | ^https:\\/\\/[a-z]*.example.com$ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:43:2:43:33 | /^https ... e.com$/ | here | | tst-IncompleteHostnameRegExp.js:44:32:44:45 | .+.example.net | This regular expression has an unescaped '.' before 'example.net', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | | tst-IncompleteHostnameRegExp.js:44:47:44:62 | .+.example-a.com | This regular expression has an unescaped '.' before 'example-a.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | | tst-IncompleteHostnameRegExp.js:44:64:44:79 | .+.example-b.com | This regular expression has an unescaped '.' before 'example-b.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:44:9:44:101 | '^proto ... ernal)' | here | -| tst-IncompleteHostnameRegExp.js:48:42:48:68 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | -| tst-IncompleteHostnameRegExp.js:48:42:48:68 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | +| tst-IncompleteHostnameRegExp.js:48:42:48:47 | ^https?://.+.example\\.com/ | This regular expression has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | +| tst-IncompleteHostnameRegExp.js:48:42:48:47 | ^https?://.+.example\\.com/ | This regular expression has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.js:48:13:48:69 | '^http: ... \\.com/' | here | +| tst-IncompleteHostnameRegExp.js:53:14:53:35 | test.example.com$ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:53:13:53:36 | 'test.' ... e.com$' | here | | tst-IncompleteHostnameRegExp.js:59:5:59:20 | foo.example\\.com | This regular expression has an unescaped '.' before 'example\\.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.js:59:2:59:32 | /^(foo. ... ever)$/ | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js b/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js index 403366064c1..df887092d23 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js +++ b/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js @@ -50,7 +50,7 @@ var primary = 'example.com$'; new RegExp('test.' + primary); // NOT OK, but not detected - new RegExp('test.' + 'example.com$'); // NOT OK, but not detected + new RegExp('test.' + 'example.com$'); // NOT OK new RegExp('^http://test\.example.com'); // NOT OK, but flagged by js/useless-regexp-character-escape