mirror of
https://github.com/github/codeql.git
synced 2026-07-31 07:22:56 +02:00
C++: Make regex library compile
This commit is contained in:
@@ -10,6 +10,7 @@ dependencies:
|
||||
codeql/mad: ${workspace}
|
||||
codeql/quantum: ${workspace}
|
||||
codeql/rangeanalysis: ${workspace}
|
||||
codeql/regex: ${workspace}
|
||||
codeql/ssa: ${workspace}
|
||||
codeql/typeflow: ${workspace}
|
||||
codeql/tutorial: ${workspace}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/** Provides a class hierarchy corresponding to a parse tree of regular expressions. */
|
||||
/**
|
||||
* Provides a class hierarchy corresponding to a parse tree of C++ regular expressions.
|
||||
*/
|
||||
|
||||
private import internal.ParseRegExp
|
||||
private import codeql.util.Numbers
|
||||
private import codeql.ruby.ast.Literal as Ast
|
||||
private import codeql.Locations
|
||||
private import codeql.regex.nfa.NfaUtils as NfaUtils
|
||||
private import semmle.code.cpp.exprs.Literal
|
||||
private import codeql.regex.RegexTreeView
|
||||
// exporting as RegexTreeView, and in the top-level scope.
|
||||
import Impl as RegexTreeView
|
||||
import Impl
|
||||
|
||||
/** Gets the parse tree resulting from parsing `re`, if such has been constructed. */
|
||||
RegExpTerm getParsedRegExp(Ast::RegExpLiteral re) {
|
||||
RegExpTerm getParsedRegExp(StringLiteral re) {
|
||||
result.getRegExp() = re and result.isRootTerm()
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ private newtype TRegExpParent =
|
||||
re.namedCharacterProperty(start, end, _)
|
||||
}
|
||||
|
||||
/** An implementation that statisfies the RegexTreeView signature. */
|
||||
/** An implementation that satisfies the RegexTreeView signature. */
|
||||
private module Impl implements RegexTreeViewSig {
|
||||
/**
|
||||
* An element containing a regular expression term, that is, either
|
||||
@@ -211,24 +211,14 @@ private module Impl implements RegexTreeViewSig {
|
||||
*/
|
||||
Location getLocation() { result = re.getLocation() }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate componentHasLocationInfo(
|
||||
int i, string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
re.getComponent(i)
|
||||
.getLocation()
|
||||
.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
|
||||
/** Holds if this term is found at the specified location offsets. */
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(int re_start |
|
||||
this.componentHasLocationInfo(0, filepath, startline, re_start, _, _) and
|
||||
this.componentHasLocationInfo(re.getNumberOfComponents() - 1, filepath, _, _, endline, _) and
|
||||
startcolumn = re_start + start and
|
||||
endcolumn = re_start + end - 1
|
||||
re.getLocation().hasLocationInfo(filepath, startline, re_start, endline, _) and
|
||||
startcolumn = re_start + 1 + start and
|
||||
endcolumn = re_start + 1 + end - 1
|
||||
)
|
||||
}
|
||||
|
||||
@@ -312,7 +302,7 @@ private module Impl implements RegexTreeViewSig {
|
||||
result.getEnd() = part_end
|
||||
}
|
||||
|
||||
/** Hols if this term may match an unlimited number of times. */
|
||||
/** Hodls if this term may match an unlimited number of times. */
|
||||
predicate mayRepeatForever() { may_repeat_forever = true }
|
||||
|
||||
/** Gets the qualifier for this term. That is e.g "?" for "a?". */
|
||||
@@ -660,9 +650,9 @@ private module Impl implements RegexTreeViewSig {
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```rb
|
||||
* /[a-fA-F0-9]/
|
||||
* /[^abc]/
|
||||
* ```cpp
|
||||
* "[a-fA-F0-9]"
|
||||
* "[^abc]"
|
||||
* ```
|
||||
*/
|
||||
class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass {
|
||||
@@ -1195,9 +1185,7 @@ private module Impl implements RegexTreeViewSig {
|
||||
/**
|
||||
* Holds if the regular expression should not be considered.
|
||||
*/
|
||||
predicate isExcluded(RegExpParent parent) {
|
||||
parent.(RegExpTerm).getRegExp().(Ast::RegExpLiteral).hasFreeSpacingFlag() // exclude free-spacing mode regexes
|
||||
}
|
||||
predicate isExcluded(RegExpParent parent) { none() }
|
||||
|
||||
/**
|
||||
* Holds if `term` is a possessive quantifier.
|
||||
@@ -1207,13 +1195,13 @@ private module Impl implements RegexTreeViewSig {
|
||||
|
||||
/**
|
||||
* Holds if the regex that `term` is part of is used in a way that ignores any leading prefix of the input it's matched against.
|
||||
* Not yet implemented for Ruby.
|
||||
* Not yet implemented for C++.
|
||||
*/
|
||||
predicate matchesAnyPrefix(RegExpTerm term) { any() }
|
||||
|
||||
/**
|
||||
* Holds if the regex that `term` is part of is used in a way that ignores any trailing suffix of the input it's matched against.
|
||||
* Not yet implemented for Ruby.
|
||||
* Not yet implemented for C++.
|
||||
*/
|
||||
predicate matchesAnySuffix(RegExpTerm term) { any() }
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/**
|
||||
* Library for parsing for Ruby regular expressions.
|
||||
* Library for parsing for C++ regular expressions.
|
||||
*
|
||||
* N.B. does not yet handle stripping whitespace and comments in regexes with
|
||||
* the `x` (free-spacing) flag.
|
||||
*/
|
||||
|
||||
private import codeql.ruby.AST as Ast
|
||||
private import codeql.Locations
|
||||
private import semmle.code.cpp.exprs.Literal
|
||||
|
||||
/**
|
||||
* A `StringlikeLiteral` containing a regular expression term, that is, either
|
||||
* A C++ string literal containing a regular expression term, that is, either
|
||||
* a regular expression literal, or a string literal used in a context where
|
||||
* it is parsed as regular expression.
|
||||
* it is parsed as a regular expression.
|
||||
*/
|
||||
abstract class RegExp extends Ast::StringlikeLiteral {
|
||||
abstract class RegExp extends StringLiteral {
|
||||
/**
|
||||
* Holds if this `RegExp` has the `s` flag for multi-line matching.
|
||||
*/
|
||||
@@ -254,11 +253,7 @@ abstract class RegExp extends Ast::StringlikeLiteral {
|
||||
}
|
||||
|
||||
/** Gets the text of this regex */
|
||||
string getText() {
|
||||
exists(Ast::ConstantValue c | c = this.getConstantValue() |
|
||||
result = [this.getConstantValue().getString(), this.getConstantValue().getRegExp()]
|
||||
)
|
||||
}
|
||||
string getText() { result = this.getValue() }
|
||||
|
||||
/** Gets the `i`th character of this regex */
|
||||
string getChar(int i) { result = this.getText().charAt(i) }
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import codeql.Locations
|
||||
import codeql.ruby.Regexp as RE
|
||||
import semmle.code.cpp.regex.RegexTreeView
|
||||
|
||||
query predicate nodes(RE::RegExpTerm n, string attr, string val) {
|
||||
query predicate nodes(RegExpTerm n, string attr, string val) {
|
||||
attr = "semmle.label" and
|
||||
val = "[" + concat(n.getAPrimaryQlClass(), ", ") + "] " + n.toString()
|
||||
or
|
||||
@@ -13,7 +12,7 @@ query predicate nodes(RE::RegExpTerm n, string attr, string val) {
|
||||
val =
|
||||
any(int i |
|
||||
n =
|
||||
rank[i](RE::RegExpTerm t, string fp, int sl, int sc, int el, int ec |
|
||||
rank[i](RegExpTerm t, string fp, int sl, int sc, int el, int ec |
|
||||
t.hasLocationInfo(fp, sl, sc, el, ec)
|
||||
|
|
||||
t order by fp, sl, sc, el, ec, t.toString()
|
||||
@@ -21,7 +20,7 @@ query predicate nodes(RE::RegExpTerm n, string attr, string val) {
|
||||
).toString()
|
||||
}
|
||||
|
||||
query predicate edges(RE::RegExpTerm pred, RE::RegExpTerm succ, string attr, string val) {
|
||||
query predicate edges(RegExpTerm pred, RegExpTerm succ, string attr, string val) {
|
||||
attr in ["semmle.label", "semmle.order"] and
|
||||
val = any(int i | succ = pred.getChild(i)).toString()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import codeql.ruby.Regexp
|
||||
import semmle.code.cpp.regex.RegexTreeView
|
||||
|
||||
query predicate groupName(RegExpGroup g, string name) { name = g.getName() }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user