Commit 0ce63efe authored by Grzegorz Bizon's avatar Grzegorz Bizon

Add extended /regexp/ scheme support to untrusted regexp

parent f52de2f7
......@@ -9,6 +9,8 @@ module Gitlab
# there is a strict limit on total execution time. See the RE2 documentation
# at https://github.com/google/re2/wiki/Syntax for more details.
class UntrustedRegexp
require_dependency 're2'
delegate :===, :source, to: :regexp
def initialize(pattern, multiline: false)
......@@ -52,6 +54,27 @@ module Gitlab
Regexp.new(pattern)
end
def self.valid?(pattern)
self.fabricate(pattern)
rescue RegexpError
false
end
def self.fabricate(pattern)
matches = pattern.match(%r{^/(?<regexp>.+)/(?<flags>[ismU]*)$})
if matches
expression = matches[:regexp]
flags = matches[:flags]
expression.prepend("(?#{flags})") if flags.present?
self.new(expression, multiline: false)
else
self.new(pattern, multiline: false)
end
end
private
attr_reader :regexp
......
require 'spec_helper'
require 'fast_spec_helper'
require 'support/shared_examples/malicious_regexp_shared_examples'
describe Gitlab::UntrustedRegexp do
describe '.valid?' do
it 'returns true if regexp is valid' do
end
it 'returns true if regexp is invalid' do
end
end
describe '.fabricate' do
context 'when regexp is using /regexp/ scheme with flags' do
it 'fabricates regexp with a single flag' do
regexp = described_class.fabricate('/something/i')
expect(regexp).to eq described_class.new('(?i)something')
expect(regexp.scan('SOMETHING')).to be_one
end
it 'fabricates regexp with multiple flags' do
regexp = described_class.fabricate('/something/im')
expect(regexp).to eq described_class.new('(?im)something')
end
it 'fabricates regexp without flags' do
regexp = described_class.fabricate('/something/')
expect(regexp).to eq described_class.new('something')
end
end
context 'when regexp is not plain pattern' do
it 'fabricates regexp without flags' do
regexp = described_class.fabricate('something')
expect(regexp).to eq described_class.new('something')
end
end
context 'when regexp is invalid' do
it 'raises an error' do
expect { described_class.fabricate('/some ( thing/') }
.to raise_error(RegexpError)
end
end
end
describe '#initialize' do
subject { described_class.new(pattern) }
......
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