Skip to content

Commit 049af68

Browse files
committed
restrict suffix-construction to relevant regexps
1 parent 0aebc90 commit 049af68

File tree

4 files changed

+68
-28
lines changed

4 files changed

+68
-28
lines changed

java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,18 +1104,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
11041104
result = getAnInputSymbolMatching(char)
11051105
}
11061106

1107+
pragma[noinline]
1108+
RegExpRoot relevantRoot() {
1109+
exists(RegExpTerm term, State s |
1110+
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
1111+
)
1112+
}
1113+
11071114
/**
11081115
* Gets a char used for finding possible suffixes inside `root`.
11091116
*/
11101117
pragma[noinline]
11111118
private string relevant(RegExpRoot root) {
1112-
exists(ascii(result)) and exists(root)
1113-
or
1114-
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1115-
or
1116-
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1117-
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1118-
result = ["|", "\n", "Z"] and exists(root)
1119+
root = relevantRoot() and
1120+
(
1121+
exists(ascii(result)) and exists(root)
1122+
or
1123+
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1124+
or
1125+
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1126+
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1127+
result = ["|", "\n", "Z"] and exists(root)
1128+
)
11191129
}
11201130

11211131
/**

javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,18 +1104,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
11041104
result = getAnInputSymbolMatching(char)
11051105
}
11061106

1107+
pragma[noinline]
1108+
RegExpRoot relevantRoot() {
1109+
exists(RegExpTerm term, State s |
1110+
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
1111+
)
1112+
}
1113+
11071114
/**
11081115
* Gets a char used for finding possible suffixes inside `root`.
11091116
*/
11101117
pragma[noinline]
11111118
private string relevant(RegExpRoot root) {
1112-
exists(ascii(result)) and exists(root)
1113-
or
1114-
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1115-
or
1116-
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1117-
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1118-
result = ["|", "\n", "Z"] and exists(root)
1119+
root = relevantRoot() and
1120+
(
1121+
exists(ascii(result)) and exists(root)
1122+
or
1123+
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1124+
or
1125+
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1126+
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1127+
result = ["|", "\n", "Z"] and exists(root)
1128+
)
11191129
}
11201130

11211131
/**

python/ql/lib/semmle/python/security/regexp/NfaUtils.qll

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,18 +1104,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
11041104
result = getAnInputSymbolMatching(char)
11051105
}
11061106

1107+
pragma[noinline]
1108+
RegExpRoot relevantRoot() {
1109+
exists(RegExpTerm term, State s |
1110+
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
1111+
)
1112+
}
1113+
11071114
/**
11081115
* Gets a char used for finding possible suffixes inside `root`.
11091116
*/
11101117
pragma[noinline]
11111118
private string relevant(RegExpRoot root) {
1112-
exists(ascii(result)) and exists(root)
1113-
or
1114-
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1115-
or
1116-
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1117-
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1118-
result = ["|", "\n", "Z"] and exists(root)
1119+
root = relevantRoot() and
1120+
(
1121+
exists(ascii(result)) and exists(root)
1122+
or
1123+
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1124+
or
1125+
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1126+
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1127+
result = ["|", "\n", "Z"] and exists(root)
1128+
)
11191129
}
11201130

11211131
/**

ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,18 +1104,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
11041104
result = getAnInputSymbolMatching(char)
11051105
}
11061106

1107+
pragma[noinline]
1108+
RegExpRoot relevantRoot() {
1109+
exists(RegExpTerm term, State s |
1110+
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
1111+
)
1112+
}
1113+
11071114
/**
11081115
* Gets a char used for finding possible suffixes inside `root`.
11091116
*/
11101117
pragma[noinline]
11111118
private string relevant(RegExpRoot root) {
1112-
exists(ascii(result)) and exists(root)
1113-
or
1114-
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1115-
or
1116-
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1117-
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1118-
result = ["|", "\n", "Z"] and exists(root)
1119+
root = relevantRoot() and
1120+
(
1121+
exists(ascii(result)) and exists(root)
1122+
or
1123+
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
1124+
or
1125+
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
1126+
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
1127+
result = ["|", "\n", "Z"] and exists(root)
1128+
)
11191129
}
11201130

11211131
/**

0 commit comments

Comments
 (0)