diff --git a/javascript/extractor/src/com/semmle/jcorn/Parser.java b/javascript/extractor/src/com/semmle/jcorn/Parser.java index b0bc89645597..3ae1491af10e 100644 --- a/javascript/extractor/src/com/semmle/jcorn/Parser.java +++ b/javascript/extractor/src/com/semmle/jcorn/Parser.java @@ -790,7 +790,8 @@ private Token readRegexp() { String validFlags = "gim"; if (this.options.ecmaVersion() >= 6) validFlags = "gimuy"; if (this.options.ecmaVersion() >= 9) validFlags = "gimsuy"; - if (this.options.ecmaVersion() >= 15) validFlags = "gimsuyv"; + if (this.options.ecmaVersion() >= 13) validFlags = "dgimsuy"; + if (this.options.ecmaVersion() >= 15) validFlags = "dgimsuyv"; if (!mods.matches("^[" + validFlags + "]*$")) this.raise(start, "Invalid regular expression flag"); if (mods.indexOf('u') >= 0) { diff --git a/javascript/extractor/tests/es2022/input/d-flag.js b/javascript/extractor/tests/es2022/input/d-flag.js new file mode 100644 index 000000000000..be7fb5d6841f --- /dev/null +++ b/javascript/extractor/tests/es2022/input/d-flag.js @@ -0,0 +1,5 @@ +const pattern = /import/dg; + +function target() { + return pattern; +} \ No newline at end of file diff --git a/javascript/extractor/tests/es2022/options.json b/javascript/extractor/tests/es2022/options.json new file mode 100644 index 000000000000..075583ca1f63 --- /dev/null +++ b/javascript/extractor/tests/es2022/options.json @@ -0,0 +1,3 @@ +{ + "experimental": true +} diff --git a/javascript/extractor/tests/es2022/output/trap/d-flag.js.trap b/javascript/extractor/tests/es2022/output/trap/d-flag.js.trap new file mode 100644 index 000000000000..c8a92cf06a3e --- /dev/null +++ b/javascript/extractor/tests/es2022/output/trap/d-flag.js.trap @@ -0,0 +1,224 @@ +#10000=@"/d-flag.js;sourcefile" +files(#10000,"/d-flag.js") +#10001=@"/;folder" +folders(#10001,"/") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=@"script;{#10000},1,1" +#20002=* +lines(#20002,#20001,"const pattern = /import/dg;"," +") +#20003=@"loc,{#10000},1,1,1,27" +locations_default(#20003,#10000,1,1,1,27) +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,"function target() {"," +") +#20007=@"loc,{#10000},3,1,3,19" +locations_default(#20007,#10000,3,1,3,19) +hasLocation(#20006,#20007) +#20008=* +lines(#20008,#20001," return pattern;"," +") +#20009=@"loc,{#10000},4,1,4,17" +locations_default(#20009,#10000,4,1,4,17) +hasLocation(#20008,#20009) +indentation(#10000,4," ",2) +#20010=* +lines(#20010,#20001,"}","") +#20011=@"loc,{#10000},5,1,5,1" +locations_default(#20011,#10000,5,1,5,1) +hasLocation(#20010,#20011) +numlines(#20001,5,4,0) +#20012=* +tokeninfo(#20012,7,#20001,0,"const") +#20013=@"loc,{#10000},1,1,1,5" +locations_default(#20013,#10000,1,1,1,5) +hasLocation(#20012,#20013) +#20014=* +tokeninfo(#20014,6,#20001,1,"pattern") +#20015=@"loc,{#10000},1,7,1,13" +locations_default(#20015,#10000,1,7,1,13) +hasLocation(#20014,#20015) +#20016=* +tokeninfo(#20016,8,#20001,2,"=") +#20017=@"loc,{#10000},1,15,1,15" +locations_default(#20017,#10000,1,15,1,15) +hasLocation(#20016,#20017) +#20018=* +tokeninfo(#20018,5,#20001,3,"/import/dg") +#20019=@"loc,{#10000},1,17,1,26" +locations_default(#20019,#10000,1,17,1,26) +hasLocation(#20018,#20019) +#20020=* +tokeninfo(#20020,8,#20001,4,";") +#20021=@"loc,{#10000},1,27,1,27" +locations_default(#20021,#10000,1,27,1,27) +hasLocation(#20020,#20021) +#20022=* +tokeninfo(#20022,7,#20001,5,"function") +#20023=@"loc,{#10000},3,1,3,8" +locations_default(#20023,#10000,3,1,3,8) +hasLocation(#20022,#20023) +#20024=* +tokeninfo(#20024,6,#20001,6,"target") +#20025=@"loc,{#10000},3,10,3,15" +locations_default(#20025,#10000,3,10,3,15) +hasLocation(#20024,#20025) +#20026=* +tokeninfo(#20026,8,#20001,7,"(") +#20027=@"loc,{#10000},3,16,3,16" +locations_default(#20027,#10000,3,16,3,16) +hasLocation(#20026,#20027) +#20028=* +tokeninfo(#20028,8,#20001,8,")") +#20029=@"loc,{#10000},3,17,3,17" +locations_default(#20029,#10000,3,17,3,17) +hasLocation(#20028,#20029) +#20030=* +tokeninfo(#20030,8,#20001,9,"{") +#20031=@"loc,{#10000},3,19,3,19" +locations_default(#20031,#10000,3,19,3,19) +hasLocation(#20030,#20031) +#20032=* +tokeninfo(#20032,7,#20001,10,"return") +#20033=@"loc,{#10000},4,3,4,8" +locations_default(#20033,#10000,4,3,4,8) +hasLocation(#20032,#20033) +#20034=* +tokeninfo(#20034,6,#20001,11,"pattern") +#20035=@"loc,{#10000},4,10,4,16" +locations_default(#20035,#10000,4,10,4,16) +hasLocation(#20034,#20035) +#20036=* +tokeninfo(#20036,8,#20001,12,";") +#20037=@"loc,{#10000},4,17,4,17" +locations_default(#20037,#10000,4,17,4,17) +hasLocation(#20036,#20037) +#20038=* +tokeninfo(#20038,8,#20001,13,"}") +hasLocation(#20038,#20011) +#20039=* +tokeninfo(#20039,0,#20001,14,"") +#20040=@"loc,{#10000},5,2,5,1" +locations_default(#20040,#10000,5,2,5,1) +hasLocation(#20039,#20040) +toplevels(#20001,0) +#20041=@"loc,{#10000},1,1,5,1" +locations_default(#20041,#10000,1,1,5,1) +hasLocation(#20001,#20041) +#20042=@"var;{target};{#20000}" +variables(#20042,"target",#20000) +#20043=@"var;{pattern};{#20000}" +variables(#20043,"pattern",#20000) +#20044=@"var;{this};{#20000}" +variables(#20044,"this",#20000) +#20045=* +stmts(#20045,22,#20001,0,"const p ... ort/dg;") +hasLocation(#20045,#20003) +stmt_containers(#20045,#20001) +#20046=* +exprs(#20046,64,#20045,0,"pattern = /import/dg") +#20047=@"loc,{#10000},1,7,1,26" +locations_default(#20047,#10000,1,7,1,26) +hasLocation(#20046,#20047) +enclosing_stmt(#20046,#20045) +expr_containers(#20046,#20001) +#20048=* +exprs(#20048,78,#20046,0,"pattern") +hasLocation(#20048,#20015) +enclosing_stmt(#20048,#20045) +expr_containers(#20048,#20001) +literals("pattern","pattern",#20048) +decl(#20048,#20043) +#20049=* +exprs(#20049,5,#20046,1,"/import/dg") +hasLocation(#20049,#20019) +enclosing_stmt(#20049,#20045) +expr_containers(#20049,#20001) +literals("/import/dg","/import/dg",#20049) +#20050=* +regexpterm(#20050,14,#20049,0,"import") +#20051=@"loc,{#10000},1,18,1,23" +locations_default(#20051,#10000,1,18,1,23) +hasLocation(#20050,#20051) +regexp_const_value(#20050,"import") +#20052=* +stmts(#20052,17,#20001,1,"functio ... tern;\n}") +#20053=@"loc,{#10000},3,1,5,1" +locations_default(#20053,#10000,3,1,5,1) +hasLocation(#20052,#20053) +stmt_containers(#20052,#20001) +#20054=* +exprs(#20054,78,#20052,-1,"target") +hasLocation(#20054,#20025) +expr_containers(#20054,#20052) +literals("target","target",#20054) +decl(#20054,#20042) +#20055=* +scopes(#20055,1) +scopenodes(#20052,#20055) +scopenesting(#20055,#20000) +#20056=@"var;{this};{#20055}" +variables(#20056,"this",#20055) +#20057=@"var;{arguments};{#20055}" +variables(#20057,"arguments",#20055) +is_arguments_object(#20057) +#20058=* +stmts(#20058,1,#20052,-2,"{\n ret ... tern;\n}") +#20059=@"loc,{#10000},3,19,5,1" +locations_default(#20059,#10000,3,19,5,1) +hasLocation(#20058,#20059) +stmt_containers(#20058,#20052) +#20060=* +stmts(#20060,9,#20058,0,"return pattern;") +#20061=@"loc,{#10000},4,3,4,17" +locations_default(#20061,#10000,4,3,4,17) +hasLocation(#20060,#20061) +stmt_containers(#20060,#20052) +#20062=* +exprs(#20062,79,#20060,0,"pattern") +hasLocation(#20062,#20035) +enclosing_stmt(#20062,#20060) +expr_containers(#20062,#20052) +literals("pattern","pattern",#20062) +bind(#20062,#20043) +#20063=* +entry_cfg_node(#20063,#20001) +#20064=@"loc,{#10000},1,1,1,0" +locations_default(#20064,#10000,1,1,1,0) +hasLocation(#20063,#20064) +#20065=* +exit_cfg_node(#20065,#20001) +hasLocation(#20065,#20040) +successor(#20052,#20065) +#20066=* +entry_cfg_node(#20066,#20052) +#20067=@"loc,{#10000},3,1,3,0" +locations_default(#20067,#10000,3,1,3,0) +hasLocation(#20066,#20067) +#20068=* +exit_cfg_node(#20068,#20052) +hasLocation(#20068,#20040) +successor(#20062,#20060) +successor(#20060,#20068) +successor(#20058,#20062) +successor(#20066,#20058) +successor(#20045,#20048) +successor(#20049,#20046) +successor(#20048,#20049) +successor(#20046,#20052) +successor(#20054,#20045) +successor(#20063,#20054) +numlines(#10000,5,4,0) +filetype(#10000,"javascript") diff --git a/javascript/ql/lib/change-notes/2026-08-10-d-regex-flag.md b/javascript/ql/lib/change-notes/2026-08-10-d-regex-flag.md new file mode 100644 index 000000000000..8552c7bf7925 --- /dev/null +++ b/javascript/ql/lib/change-notes/2026-08-10-d-regex-flag.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added support for regular expressions using the `d` flag.