summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/untrusted_regexp_spec.rb
blob: 0ee7fa1e57093956d767f98fb7b00712136f1463 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
require 'spec_helper'

describe Gitlab::UntrustedRegexp do
  describe '#initialize' do
    subject { described_class.new(pattern) }

    context 'invalid regexp' do
      let(:pattern) { '[' }

      it { expect { subject }.to raise_error(RegexpError) }
    end
  end

  describe '#replace_all' do
    it 'replaces all instances of the match in a string' do
      result = described_class.new('foo').replace_all('foo bar foo', 'oof')

      expect(result).to eq('oof bar oof')
    end
  end

  describe '#replace' do
    it 'replaces the first instance of the match in a string' do
      result = described_class.new('foo').replace('foo bar foo', 'oof')

      expect(result).to eq('oof bar foo')
    end
  end

  describe '#===' do
    it 'returns true for a match' do
      result = described_class.new('foo') === 'a foo here'

      expect(result).to be_truthy
    end

    it 'returns false for no match' do
      result = described_class.new('foo') === 'a bar here'

      expect(result).to be_falsy
    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

  describe '#scan' do
    subject { described_class.new(regexp).scan(text) }
    context 'malicious regexp' do
      let(:text) { malicious_text }
      let(:regexp) { malicious_regexp }

      include_examples 'malicious regexp'
    end

    context 'empty regexp' do
      let(:regexp) { '' }
      let(:text) { 'foo' }

      it 'returns an array of nil matches' do
        is_expected.to eq([nil, nil, nil, nil])
      end
    end

    context 'empty capture group regexp' do
      let(:regexp) { '()' }
      let(:text) { 'foo' }

      it 'returns an array of nil matches in an array' do
        is_expected.to eq([[nil], [nil], [nil], [nil]])
      end
    end

    context 'no capture group' do
      let(:regexp) { '.+' }
      let(:text) { 'foo' }

      it 'returns the whole match' do
        is_expected.to eq(['foo'])
      end
    end

    context 'one capture group' do
      let(:regexp) { '(f).+' }
      let(:text) { 'foo' }

      it 'returns the captured part' do
        is_expected.to eq([%w[f]])
      end
    end

    context 'two capture groups' do
      let(:regexp) { '(f).(o)' }
      let(:text) { 'foo' }

      it 'returns the captured parts' do
        is_expected.to eq([%w[f o]])
      end
    end
  end
end