Commit da5c28a4 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Backport EE-specific untrusted regexp implementation

parent f1a2ada1
...@@ -11,7 +11,11 @@ module Gitlab ...@@ -11,7 +11,11 @@ module Gitlab
class UntrustedRegexp class UntrustedRegexp
delegate :===, to: :regexp delegate :===, to: :regexp
def initialize(pattern) def initialize(pattern, multiline: false)
if multiline
pattern = "(?m)#{pattern}"
end
@regexp = RE2::Regexp.new(pattern, log_errors: false) @regexp = RE2::Regexp.new(pattern, log_errors: false)
raise RegexpError.new(regexp.error) unless regexp.ok? raise RegexpError.new(regexp.error) unless regexp.ok?
...@@ -31,6 +35,19 @@ module Gitlab ...@@ -31,6 +35,19 @@ module Gitlab
RE2.Replace(text, regexp, rewrite) RE2.Replace(text, regexp, rewrite)
end end
# Handles regular expressions with the preferred RE2 library where possible
# via UntustedRegex. Falls back to Ruby's built-in regular expression library
# when the syntax would be invalid in RE2.
#
# One difference between these is `(?m)` multi-line mode. Ruby regex enables
# this by default, but also handles `^` and `$` differently.
# See: https://www.regular-expressions.info/modifiers.html
def self.with_fallback(pattern, multiline: false)
UntrustedRegexp.new(pattern, multiline: multiline)
rescue RegexpError
Regexp.new(pattern)
end
private private
attr_reader :regexp attr_reader :regexp
......
...@@ -39,6 +39,14 @@ describe Gitlab::UntrustedRegexp do ...@@ -39,6 +39,14 @@ describe Gitlab::UntrustedRegexp do
expect(result).to be_falsy expect(result).to be_falsy
end end
it 'can handle regular expressions in multiline mode' do
regexp = described_class.new('^\d', multiline: true)
result = regexp === "Header\n\n1. Content"
expect(result).to be_truthy
end
end end
describe '#scan' do describe '#scan' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment