Skip to content

Commit 30964f4

Browse files
authored
fix: handle request URLs that include non-ASCII characters (#1021)
1 parent 5617733 commit 30964f4

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

lib/rollbar/scrubbers/url.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def self.call(*args)
1313
end
1414

1515
def call(options = {})
16-
url = options[:url]
16+
url = ascii_encode(options[:url])
1717

1818
filter(url,
1919
build_regex(options[:scrub_fields]),
@@ -29,6 +29,20 @@ def call(options = {})
2929

3030
private
3131

32+
def ascii_encode(url)
33+
# In some cases non-ascii characters won't be properly encoded, so we do it here.
34+
#
35+
# The standard encoders (the CGI and URI methods) are not reliable when the query string
36+
# is already embedded in the full URL, but the inconsistencies are limited to issues
37+
# with characters in the ascii range. (For example, the '#' if it appears in an unexpected place.)
38+
# For escaping non-ascii, they are all OK, so we'll take care to skip the ascii chars.
39+
40+
return url if url.ascii_only?
41+
42+
# Iterate each char and only escape non-ascii characters.
43+
url.each_char.map { |c| c.ascii_only? ? c : CGI.escape(c) }.join
44+
end
45+
3246
def build_whitelist_regex(whitelist)
3347
fields = whitelist.find_all { |f| f.is_a?(String) || f.is_a?(Symbol) }
3448
return unless fields.any?

spec/rollbar/scrubbers/url_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@
112112
end
113113
end
114114

115+
context 'with non-ASCII UTF-8 encoded URL' do
116+
let(:url) { 'http://foo.com/some-path?foo=あああ'.force_encoding(Encoding::UTF_8) }
117+
before { reconfigure_notifier }
118+
119+
it 'returns the URI encoded url' do
120+
expected_url = 'http://foo.com/some-path?foo=%E3%81%82%E3%81%82%E3%81%82'
121+
expect(subject.call(options)).to match(expected_url)
122+
end
123+
end
124+
125+
context 'with non-ASCII ASCII-8BIT encoded URL' do
126+
let(:url) { 'http://foo.com/some-path?foo=あああ'.force_encoding(Encoding::ASCII_8BIT) }
127+
before { reconfigure_notifier }
128+
129+
it 'returns the URI encoded url' do
130+
expected_url = 'http://foo.com/some-path?foo=%E3%81%82%E3%81%82%E3%81%82'
131+
expect(subject.call(options)).to match(expected_url)
132+
end
133+
end
134+
115135
context 'with URL with spaces and arrays' do
116136
let(:url) do
117137
'https://server.com/api/v1/assignments/4430038?user_id=1&assignable_id=2&starts_at=Wed%20Jul%2013%202016%2000%3A00%3A00%20GMT-0700%20(PDT)&ends_at=Fri%20Jul%2029%202016%2000%3A00%3A00%20GMT-0700%20(PDT)&allocation_mode=hours_per_day&percent=&fixed_hours=&hours_per_day=0&auth=REMOVED&___uidh=2228207862&password[]=mypassword'

0 commit comments

Comments
 (0)