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:
authorJohn Jarvis <jarv@gitlab.com>2019-04-02 11:12:32 +0300
committerJohn Jarvis <jarv@gitlab.com>2019-04-02 11:12:32 +0300
commit69b65a6b745e74bba290787420a0017395fd7c25 (patch)
treec328963cbe5b340c58c88230d21f338c77462ebd /lib/gitlab/untrusted_regexp/ruby_syntax.rb
parent1b6fe3ae226e4c6f481c90c886e242fcd96ab11b (diff)
parent3e81a5baf25d6ecd9ad807a2b8f4238dcc598d5e (diff)
Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq into jarv/dev-to-gitlab-2019-04-02
Diffstat (limited to 'lib/gitlab/untrusted_regexp/ruby_syntax.rb')
-rw-r--r--lib/gitlab/untrusted_regexp/ruby_syntax.rb43
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/gitlab/untrusted_regexp/ruby_syntax.rb b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
new file mode 100644
index 00000000000..91f300f97d0
--- /dev/null
+++ b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class UntrustedRegexp
+ # This class implements support for Ruby syntax of regexps
+ # and converts that to RE2 representation:
+ # /<regexp>/<flags>
+ class RubySyntax
+ PATTERN = %r{^/(?<regexp>.+)/(?<flags>[ismU]*)$}.freeze
+
+ # Checks if pattern matches a regexp pattern
+ # but does not enforce it's validity
+ def self.matches_syntax?(pattern)
+ pattern.is_a?(String) && pattern.match(PATTERN).present?
+ end
+
+ # The regexp can match the pattern `/.../`, but may not be fabricatable:
+ # it can be invalid or incomplete: `/match ( string/`
+ def self.valid?(pattern)
+ !!self.fabricate(pattern)
+ end
+
+ def self.fabricate(pattern)
+ self.fabricate!(pattern)
+ rescue RegexpError
+ nil
+ end
+
+ def self.fabricate!(pattern)
+ raise RegexpError, 'Pattern is not string!' unless pattern.is_a?(String)
+
+ matches = pattern.match(PATTERN)
+ raise RegexpError, 'Invalid regular expression!' if matches.nil?
+
+ expression = matches[:regexp]
+ flags = matches[:flags]
+ expression.prepend("(?#{flags})") if flags.present?
+
+ UntrustedRegexp.new(expression, multiline: false)
+ end
+ end
+ end
+end