diff --git a/lib/device_detector.rb b/lib/device_detector.rb index 9e9d37b..a0b4be8 100644 --- a/lib/device_detector.rb +++ b/lib/device_detector.rb @@ -21,7 +21,8 @@ class DeviceDetector def initialize(user_agent, headers = nil) @client_hint = ClientHint.new(headers) - @user_agent = set_user_agent(user_agent) + utf8_user_agent = encode_user_agent_if_needed(user_agent) + @user_agent = set_user_agent(utf8_user_agent) end # https://github.com/matomo-org/device-detector/blob/c235832dba13961ab0f71b681616baf1aa48de23/Parser/Device/AbstractDeviceParser.php#L1873 @@ -36,6 +37,13 @@ def set_user_agent(user_agent) user_agent.gsub(regex, "Android #{version}, #{client_hint.model}") end + def encode_user_agent_if_needed(user_agent) + return if user_agent.nil? + return user_agent if user_agent.encoding.name == 'UTF-8' + + user_agent.encode('utf-8', 'binary', undef: :replace) + end + def name return client.name if mobile_fix? diff --git a/spec/device_detector_spec.rb b/spec/device_detector_spec.rb index 5967aa2..8164409 100644 --- a/spec/device_detector_spec.rb +++ b/spec/device_detector_spec.rb @@ -9,7 +9,9 @@ describe 'known user agent' do describe 'desktop chrome browser' do - let(:user_agent) { 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69' } + let(:user_agent) do + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69' + end describe '#name' do it 'returns the name' do @@ -141,6 +143,52 @@ end end + describe 'wrongly encoded user agent' do + let(:user_agent) { 'Mon User-Agent personnalisé'.dup.force_encoding('ASCII-8BIT') } + + describe '#name' do + it 'returns nil' do + value(client.name).must_be_nil + end + end + + describe '#full_version' do + it 'returns nil' do + value(client.full_version).must_be_nil + end + end + + describe '#os_name' do + it 'returns nil' do + value(client.os_name).must_be_nil + end + end + + describe '#os_full_version' do + it 'returns nil' do + value(client.os_full_version).must_be_nil + end + end + + describe '#known?' do + it 'returns false' do + value(client.known?).must_equal false + end + end + + describe '#bot?' do + it 'returns false' do + value(client.bot?).must_equal false + end + end + + describe '#bot_name' do + it 'returns nil' do + value(client.bot_name).must_be_nil + end + end + end + describe 'bot' do let(:user_agent) { 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' }