Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-17 19:05:49 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-17 19:05:49 +0300
commit43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch)
treedceebdc68925362117480a5d672bcff122fb625b /lib/gitlab/untrusted_regexp.rb
parent20c84b99005abd1c82101dfeff264ac50d2df211 (diff)
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'lib/gitlab/untrusted_regexp.rb')
-rw-r--r--lib/gitlab/untrusted_regexp.rb40
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/gitlab/untrusted_regexp.rb b/lib/gitlab/untrusted_regexp.rb
index 7c7bda3a8f9..fe3377dae68 100644
--- a/lib/gitlab/untrusted_regexp.rb
+++ b/lib/gitlab/untrusted_regexp.rb
@@ -10,6 +10,9 @@ module Gitlab
# Not all regular expression features are available in untrusted regexes, and
# there is a strict limit on total execution time. See the RE2 documentation
# at https://github.com/google/re2/wiki/Syntax for more details.
+ #
+ # This class doesn't change any instance variables, which allows it to be frozen
+ # and setup in constants.
class UntrustedRegexp
require_dependency 're2'
@@ -21,6 +24,7 @@ module Gitlab
end
@regexp = RE2::Regexp.new(pattern, log_errors: false)
+ @scan_regexp = initialize_scan_regexp
raise RegexpError, regexp.error unless regexp.ok?
end
@@ -29,6 +33,27 @@ module Gitlab
RE2.GlobalReplace(text, regexp, rewrite)
end
+ # There is no built-in replace with block support (like `gsub`). We can accomplish
+ # the same thing by parsing and rebuilding the string with the substitutions.
+ def replace_gsub(text)
+ new_text = +''
+ remainder = text
+
+ matched = match(remainder)
+
+ until matched.nil? || matched.to_a.compact.empty?
+ partitioned = remainder.partition(matched.to_s)
+ new_text << partitioned.first
+ remainder = partitioned.last
+
+ new_text << yield(matched)
+
+ matched = match(remainder)
+ end
+
+ new_text << remainder
+ end
+
def scan(text)
matches = scan_regexp.scan(text).to_a
matches.map!(&:first) if regexp.number_of_capturing_groups == 0
@@ -87,17 +112,16 @@ module Gitlab
private
- attr_reader :regexp
+ attr_reader :regexp, :scan_regexp
# RE2 scan operates differently to Ruby scan when there are no capture
# groups, so work around it
- def scan_regexp
- @scan_regexp ||=
- if regexp.number_of_capturing_groups == 0
- RE2::Regexp.new('(' + regexp.source + ')')
- else
- regexp
- end
+ def initialize_scan_regexp
+ if regexp.number_of_capturing_groups == 0
+ RE2::Regexp.new('(' + regexp.source + ')')
+ else
+ regexp
+ end
end
end
end