Skip to content

Commit b0fcfc7

Browse files
committed
Add RegExpIntersection class to support intersection terms in regex
1 parent 898207f commit b0fcfc7

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

javascript/ql/lib/semmle/javascript/MembershipCandidates.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ module MembershipCandidate {
146146
child instanceof RegExpDollar or
147147
child instanceof RegExpConstant or
148148
child instanceof RegExpAlt or
149+
child instanceof RegExpIntersection or
149150
child instanceof RegExpGroup
150151
) and
151152
// exclude "length matches" that match every string

javascript/ql/lib/semmle/javascript/Regexp.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,29 @@ class RegExpAlt extends RegExpTerm, @regexp_alt {
301301
override string getAPrimaryQlClass() { result = "RegExpAlt" }
302302
}
303303

304+
/**
305+
* An intersection term, that is, a term of the form `a&&b`.
306+
*
307+
* Example:
308+
*
309+
* ```
310+
* /\p{Script_Extensions=Greek}&&\p{Letter}/v
311+
* ```
312+
*/
313+
class RegExpIntersection extends RegExpTerm, @regexp_intersection {
314+
/** Gets an intersected term of this term. */
315+
RegExpTerm getIntersectedTerm() { result = this.getAChild() }
316+
317+
/** Gets the number of intersected terms of this term. */
318+
int getNumIntersectedTerm() { result = this.getNumChild() }
319+
320+
override predicate isNullable() { this.getIntersectedTerm().isNullable() }
321+
322+
override string getAMatchedString() { result = this.getIntersectedTerm().getAMatchedString() }
323+
324+
override string getAPrimaryQlClass() { result = "RegExpIntersection" }
325+
}
326+
304327
/**
305328
* A sequence term.
306329
*

javascript/ql/test/library-tests/RegExp/RegExpIntersection/printAst.expected

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ nodes
33
| intersection.js:1:1:1:17 | [ExprStmt] /[[abc]&&[bcd]]/v | semmle.order | 1 |
44
| intersection.js:1:1:1:17 | [RegExpLiteral] /[[abc]&&[bcd]]/v | semmle.label | [RegExpLiteral] /[[abc]&&[bcd]]/v |
55
| intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | semmle.label | [RegExpCharacterClass] [[abc] |
6-
| intersection.js:1:2:1:15 | [???] [[abc]&&[bcd]] | semmle.label | [???] [[abc]&&[bcd]] |
6+
| intersection.js:1:2:1:15 | [RegExpIntersection] [[abc]&&[bcd]] | semmle.label | [RegExpIntersection] [[abc]&&[bcd]] |
77
| intersection.js:1:3:1:3 | [RegExpNormalConstant] [ | semmle.label | [RegExpNormalConstant] [ |
88
| intersection.js:1:4:1:4 | [RegExpNormalConstant] a | semmle.label | [RegExpNormalConstant] a |
99
| intersection.js:1:5:1:5 | [RegExpNormalConstant] b | semmle.label | [RegExpNormalConstant] b |
@@ -17,8 +17,8 @@ nodes
1717
edges
1818
| intersection.js:1:1:1:17 | [ExprStmt] /[[abc]&&[bcd]]/v | intersection.js:1:1:1:17 | [RegExpLiteral] /[[abc]&&[bcd]]/v | semmle.label | 1 |
1919
| intersection.js:1:1:1:17 | [ExprStmt] /[[abc]&&[bcd]]/v | intersection.js:1:1:1:17 | [RegExpLiteral] /[[abc]&&[bcd]]/v | semmle.order | 1 |
20-
| intersection.js:1:1:1:17 | [RegExpLiteral] /[[abc]&&[bcd]]/v | intersection.js:1:2:1:15 | [???] [[abc]&&[bcd]] | semmle.label | 0 |
21-
| intersection.js:1:1:1:17 | [RegExpLiteral] /[[abc]&&[bcd]]/v | intersection.js:1:2:1:15 | [???] [[abc]&&[bcd]] | semmle.order | 0 |
20+
| intersection.js:1:1:1:17 | [RegExpLiteral] /[[abc]&&[bcd]]/v | intersection.js:1:2:1:15 | [RegExpIntersection] [[abc]&&[bcd]] | semmle.label | 0 |
21+
| intersection.js:1:1:1:17 | [RegExpLiteral] /[[abc]&&[bcd]]/v | intersection.js:1:2:1:15 | [RegExpIntersection] [[abc]&&[bcd]] | semmle.order | 0 |
2222
| intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | intersection.js:1:3:1:3 | [RegExpNormalConstant] [ | semmle.label | 0 |
2323
| intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | intersection.js:1:3:1:3 | [RegExpNormalConstant] [ | semmle.order | 0 |
2424
| intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | intersection.js:1:4:1:4 | [RegExpNormalConstant] a | semmle.label | 1 |
@@ -27,10 +27,10 @@ edges
2727
| intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | intersection.js:1:5:1:5 | [RegExpNormalConstant] b | semmle.order | 2 |
2828
| intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | intersection.js:1:6:1:6 | [RegExpNormalConstant] c | semmle.label | 3 |
2929
| intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | intersection.js:1:6:1:6 | [RegExpNormalConstant] c | semmle.order | 3 |
30-
| intersection.js:1:2:1:15 | [???] [[abc]&&[bcd]] | intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | semmle.label | 0 |
31-
| intersection.js:1:2:1:15 | [???] [[abc]&&[bcd]] | intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | semmle.order | 0 |
32-
| intersection.js:1:2:1:15 | [???] [[abc]&&[bcd]] | intersection.js:1:10:1:15 | [RegExpSequence] [bcd]] | semmle.label | 1 |
33-
| intersection.js:1:2:1:15 | [???] [[abc]&&[bcd]] | intersection.js:1:10:1:15 | [RegExpSequence] [bcd]] | semmle.order | 1 |
30+
| intersection.js:1:2:1:15 | [RegExpIntersection] [[abc]&&[bcd]] | intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | semmle.label | 0 |
31+
| intersection.js:1:2:1:15 | [RegExpIntersection] [[abc]&&[bcd]] | intersection.js:1:2:1:7 | [RegExpCharacterClass] [[abc] | semmle.order | 0 |
32+
| intersection.js:1:2:1:15 | [RegExpIntersection] [[abc]&&[bcd]] | intersection.js:1:10:1:15 | [RegExpSequence] [bcd]] | semmle.label | 1 |
33+
| intersection.js:1:2:1:15 | [RegExpIntersection] [[abc]&&[bcd]] | intersection.js:1:10:1:15 | [RegExpSequence] [bcd]] | semmle.order | 1 |
3434
| intersection.js:1:10:1:14 | [RegExpCharacterClass] [bcd] | intersection.js:1:11:1:11 | [RegExpNormalConstant] b | semmle.label | 0 |
3535
| intersection.js:1:10:1:14 | [RegExpCharacterClass] [bcd] | intersection.js:1:11:1:11 | [RegExpNormalConstant] b | semmle.order | 0 |
3636
| intersection.js:1:10:1:14 | [RegExpCharacterClass] [bcd] | intersection.js:1:12:1:12 | [RegExpNormalConstant] c | semmle.label | 1 |

0 commit comments

Comments
 (0)