diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-26 16:30:34 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-26 16:30:34 +0000 |
commit | 541e88571b34a58d4a1712c81456a4cf5e3897ac (patch) | |
tree | 561b5099c37124112d1031658cacdcefede68fb3 | |
parent | 99144ea64e34b9c9cf91586cba8f3538a5f9e3af (diff) | |
download | gitlab-ce-541e88571b34a58d4a1712c81456a4cf5e3897ac.tar.gz |
Add latest changes from gitlab-org/security/gitlab@15-3-stable-ee
-rw-r--r-- | config/initializers/sawyer_patch.rb | 44 | ||||
-rw-r--r-- | spec/initializers/sawyer_patch_spec.rb | 69 |
2 files changed, 113 insertions, 0 deletions
diff --git a/config/initializers/sawyer_patch.rb b/config/initializers/sawyer_patch.rb new file mode 100644 index 00000000000..08d249645cc --- /dev/null +++ b/config/initializers/sawyer_patch.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true +# +# This patch updates SawyerResource class to not allow Ruby methods to be overridden and accessed. +# Any attempt to access a Ruby method will result in an exception. +module SawyerClassPatch + def attr_accessor(*attrs) + attrs.each do |attribute| + class_eval do + # rubocop:disable Gitlab/ModuleWithInstanceVariables + if method_defined?(attribute) || method_defined?("#{attribute}=") || method_defined?("#{attribute}?") + define_method attribute do + raise Sawyer::Error, + "Sawyer method \"#{attribute}\" overlaps Ruby method. Convert to a hash to access the attribute." + end + + define_method "#{attribute}=" do |value| + raise Sawyer::Error, + "Sawyer method \"#{attribute}\" overlaps Ruby method. Convert to a hash to access the attribute." + end + + define_method "#{attribute}?" do + raise Sawyer::Error, + "Sawyer method \"#{attribute}\" overlaps Ruby method. Convert to a hash to access the attribute." + end + else + define_method attribute do + @attrs[attribute.to_sym] + end + + define_method "#{attribute}=" do |value| + @attrs[attribute.to_sym] = value + end + + define_method "#{attribute}?" do + !!@attrs[attribute.to_sym] + end + end + end + # rubocop:enable Gitlab/ModuleWithInstanceVariables + end + end +end + +Sawyer::Resource.singleton_class.prepend(SawyerClassPatch) diff --git a/spec/initializers/sawyer_patch_spec.rb b/spec/initializers/sawyer_patch_spec.rb new file mode 100644 index 00000000000..dc922654d7d --- /dev/null +++ b/spec/initializers/sawyer_patch_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true +require 'fast_spec_helper' +require 'sawyer' + +require_relative '../../config/initializers/sawyer_patch' + +RSpec.describe 'sawyer_patch' do + it 'raises error when acessing a method that overlaps a Ruby method' do + sawyer_resource = Sawyer::Resource.new( + Sawyer::Agent.new(''), + { + to_s: 'Overriding method', + user: { to_s: 'Overriding method', name: 'User name' } + } + ) + + error_message = 'Sawyer method "to_s" overlaps Ruby method. Convert to a hash to access the attribute.' + expect { sawyer_resource.to_s }.to raise_error(Sawyer::Error, error_message) + expect { sawyer_resource.to_s? }.to raise_error(Sawyer::Error, error_message) + expect { sawyer_resource.to_s = 'new value' }.to raise_error(Sawyer::Error, error_message) + expect { sawyer_resource.user.to_s }.to raise_error(Sawyer::Error, error_message) + expect(sawyer_resource.user.name).to eq('User name') + end + + it 'raises error when acessing a boolean method that overlaps a Ruby method' do + sawyer_resource = Sawyer::Resource.new( + Sawyer::Agent.new(''), + { + nil?: 'value' + } + ) + + expect { sawyer_resource.nil? }.to raise_error(Sawyer::Error) + end + + it 'raises error when acessing a method that expects an argument' do + sawyer_resource = Sawyer::Resource.new( + Sawyer::Agent.new(''), + { + 'user': 'value', + 'user=': 'value', + '==': 'value', + '!=': 'value', + '+': 'value' + } + ) + + expect(sawyer_resource.user).to eq('value') + expect { sawyer_resource.user = 'New user' }.to raise_error(ArgumentError) + expect { sawyer_resource == true }.to raise_error(ArgumentError) + expect { sawyer_resource != true }.to raise_error(ArgumentError) + expect { sawyer_resource + 1 }.to raise_error(ArgumentError) + end + + it 'does not raise error if is not an overlapping method' do + sawyer_resource = Sawyer::Resource.new( + Sawyer::Agent.new(''), + { + count_total: 1, + user: { name: 'User name' } + } + ) + + expect(sawyer_resource.count_total).to eq(1) + expect(sawyer_resource.count_total?).to eq(true) + expect(sawyer_resource.count_total + 1).to eq(2) + expect(sawyer_resource.user.name).to eq('User name') + end +end |