From b22287f00fc10800486510c64139b4fefb38ac4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Mon, 25 Feb 2019 15:41:52 +0100 Subject: Make CI refs matching to to use UntrustedRegexp This makes ref validation to use always `UntrustedRegexp`. This also splits the existing RubySyntax into separate class. --- lib/gitlab/untrusted_regexp/ruby_syntax.rb | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lib/gitlab/untrusted_regexp/ruby_syntax.rb (limited to 'lib/gitlab/untrusted_regexp') 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: + # // + class RubySyntax + PATTERN = %r{^/(?.+)/(?[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 -- cgit v1.2.3