svg_spec.rb 3.52 KB
Newer Older
1 2 3 4
require 'spec_helper'

describe Gitlab::Sanitizers::SVG do
  let(:scrubber) { Gitlab::Sanitizers::SVG::Scrubber.new }
5 6
  let(:namespace) { double(Nokogiri::XML::Namespace, prefix: 'xlink', href: 'http://www.w3.org/1999/xlink') }
  let(:namespaced_attr) { double(Nokogiri::XML::Attr, name: 'href', namespace: namespace, value: '#awesome_id') }
7

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  describe '.clean' do
    let(:input_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'unsanitized.svg') }
    let(:data) { open(input_svg_path).read }
    let(:sanitized_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'sanitized.svg') }
    let(:sanitized) { open(sanitized_svg_path).read }

    it 'delegates sanitization to scrubber' do
      expect_any_instance_of(Gitlab::Sanitizers::SVG::Scrubber).to receive(:scrub).at_least(:once)
      described_class.clean(data)
    end

    it 'returns sanitized data' do
      expect(described_class.clean(data)).to eq(sanitized)
    end
  end

24 25
  context 'scrubber' do
    describe '#scrub' do
26
      let(:invalid_element) { double(Nokogiri::XML::Node, name: 'invalid', value: 'invalid') }
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
      let(:invalid_attribute) { double(Nokogiri::XML::Attr, name: 'invalid', namespace: nil) }
      let(:valid_element) { double(Nokogiri::XML::Node, name: 'use') }

      it 'removes an invalid element' do
        expect(invalid_element).to receive(:unlink)

        scrubber.scrub(invalid_element)
      end

      it 'removes an invalid attribute' do
        allow(valid_element).to receive(:attribute_nodes) { [invalid_attribute] }
        expect(invalid_attribute).to receive(:unlink)

        scrubber.scrub(valid_element)
      end

      it 'accepts valid element' do
        allow(valid_element).to receive(:attribute_nodes) { [namespaced_attr] }
        expect(valid_element).not_to receive(:unlink)

        scrubber.scrub(valid_element)
      end

      it 'accepts valid namespaced attributes' do
        allow(valid_element).to receive(:attribute_nodes) { [namespaced_attr] }
        expect(namespaced_attr).not_to receive(:unlink)

        scrubber.scrub(valid_element)
      end
    end

    describe '#attribute_name_with_namespace' do
      it 'returns name with prefix when attribute is namespaced' do
        expect(scrubber.attribute_name_with_namespace(namespaced_attr)).to eq('xlink:href')
      end
    end
63 64 65 66 67 68 69 70 71 72 73 74

    describe '#unsafe_href?' do
      let(:unsafe_attr) { double(Nokogiri::XML::Attr, name: 'href', namespace: namespace, value: 'http://evilsite.example.com/random.svg') }

      it 'returns true if href attribute is an external url' do
        expect(scrubber.unsafe_href?(unsafe_attr)).to be_truthy
      end

      it 'returns false if href atttribute is an internal reference' do
        expect(scrubber.unsafe_href?(namespaced_attr)).to be_falsey
      end
    end
Gabriel Mazetto's avatar
Gabriel Mazetto committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

    describe '#data_attribute?' do
      let(:data_attr) { double(Nokogiri::XML::Attr, name: 'data-gitlab', namespace: nil, value: 'gitlab is awesome') }
      let(:namespaced_attr) { double(Nokogiri::XML::Attr, name: 'data-gitlab', namespace: namespace, value: 'gitlab is awesome') }
      let(:other_attr) { double(Nokogiri::XML::Attr, name: 'something', namespace: nil, value: 'content') }

      it 'returns true if is a valid data attribute' do
        expect(scrubber.data_attribute?(data_attr)).to be_truthy
      end

      it 'returns false if attribute is namespaced' do
        expect(scrubber.data_attribute?(namespaced_attr)).to be_falsey
      end

      it 'returns false if not a data attribute' do
        expect(scrubber.data_attribute?(other_attr)).to be_falsey
      end
    end
93 94
  end
end