diff --git a/lib/rollbar.rb b/lib/rollbar.rb index 4f09c2c3..a0985783 100644 --- a/lib/rollbar.rb +++ b/lib/rollbar.rb @@ -423,7 +423,14 @@ def enforce_valid_utf8(payload) value = object.to_s if value.respond_to? :encode - encoded_value = value.encode('UTF-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '') + options = { :invalid => :replace, :undef => :replace, :replace => '' } + ascii_encodings = [Encoding.find('US-ASCII'), Encoding.find('ASCII-8BIT')] + + args = ['UTF-8'] + args << 'binary' if ascii_encodings.include?(value.encoding) + args << options + + encoded_value = value.encode(*args) else encoded_value = ::Iconv.conv('UTF-8//IGNORE', 'UTF-8', value) end diff --git a/spec/rollbar_spec.rb b/spec/rollbar_spec.rb index 9bfd61be..e76e6b97 100644 --- a/spec/rollbar_spec.rb +++ b/spec/rollbar_spec.rb @@ -943,7 +943,7 @@ def backtrace context 'with invalid utf8 encoding' do let(:extra) do - { :extra => "bad value 1\255" } + { :extra => force_to_ascii("bad value 1\255") } end it 'removes te invalid characteres' do @@ -1336,27 +1336,40 @@ def backtrace end context 'enforce_valid_utf8' do + context 'with utf8 string and ruby > 1.8' do + next unless String.instance_methods.include?(:force_encoding) + + let(:payload) { { :foo => 'Изменение' } } + + it 'just returns the same string' do + payload_copy = payload.clone + notifier.send(:enforce_valid_utf8, payload_copy) + + expect(payload_copy[:foo]).to be_eql('Изменение') + end + end + it 'should replace invalid utf8 values' do - bad_key = "inner \x92bad key" - bad_key.force_encoding('ASCII-8BIT') if bad_key.respond_to?('force_encoding') + bad_key = force_to_ascii("inner \x92bad key") payload = { - :bad_value => "bad value 1\255", - :bad_value_2 => "bad\255 value 2", - "bad\255 key" => "good value", + :bad_value => force_to_ascii("bad value 1\255"), + :bad_value_2 => force_to_ascii("bad\255 value 2"), + force_to_ascii("bad\255 key") => "good value", :hash => { - :inner_bad_value => "\255\255bad value 3", + :inner_bad_value => force_to_ascii("\255\255bad value 3"), bad_key.to_sym => 'inner good value', - "bad array key\255" => [ + force_to_ascii("bad array key\255") => [ 'good array value 1', - "bad\255 array value 1\255", + force_to_ascii("bad\255 array value 1\255"), { - :inner_inner_bad => "bad inner \255inner value" + :inner_inner_bad => force_to_ascii("bad inner \255inner value") } ] } } + payload_copy = payload.clone notifier.send(:enforce_valid_utf8, payload_copy) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bf69293c..748cd9de 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,6 +17,7 @@ RSpec.configure do |config| config.include(NotifierHelpers) config.include(FixtureHelpers) + config.include(EncodingHelpers) config.color_enabled = true config.formatter = 'documentation' diff --git a/spec/support/encoding_helpers.rb b/spec/support/encoding_helpers.rb new file mode 100644 index 00000000..03942f1d --- /dev/null +++ b/spec/support/encoding_helpers.rb @@ -0,0 +1,8 @@ +module EncodingHelpers + def force_to_ascii(string) + return string unless string.respond_to?('force_encoding') + + string.force_encoding('ASCII-8BIT') + string + end +end