Skip to content

Commit f50d27a

Browse files
authored
fix(logs): don't choke on malformed attributes (#2780)
* fix(logs): don't choke on malformed attributes * Replace malformed strings instead of dropping logs * Add another test scenario
1 parent 9eea7de commit f50d27a

File tree

4 files changed

+57
-9
lines changed

4 files changed

+57
-9
lines changed

.devcontainer/run

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ cd /workspace/sentry
77
sudo mkdir -p vendor/gems
88
sudo chown -R sentry:sentry vendor/gems
99

10-
git config --global --replace-all safe.directory /workspace/sentry
11-
git config --global --replace-all safe.directory /workspace/sentry/vendor/gems/*
10+
# git config --global --replace-all safe.directory /workspace/sentry
11+
# git config --global --replace-all safe.directory /workspace/sentry/vendor/gems/*
1212

1313
sudo chown -R sentry:sentry .
1414

sentry-ruby/lib/sentry/client.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,15 @@ def event_from_log(message, level:, **options)
197197
origin = options[:origin]
198198
body = Utils::EncodingHelper.safe_utf_8_string(message)
199199

200-
return unless body
200+
sanitized_attributes = attributes.transform_values do |value|
201+
if value.is_a?(String)
202+
Utils::EncodingHelper.safe_utf_8_string(value)
203+
else
204+
value
205+
end
206+
end
201207

202-
LogEvent.new(level: level, body: body, attributes: attributes, origin: origin)
208+
LogEvent.new(level: level, body: body, attributes: sanitized_attributes, origin: origin)
203209
end
204210

205211
# Initializes an Event object with the given Transaction object.

sentry-ruby/lib/sentry/utils/encoding_helper.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Sentry
44
module Utils
55
module EncodingHelper
66
EMPTY_STRING = ""
7+
MALFORMED_STRING = "<malformed-string>"
78

89
def self.encode_to_utf_8(value)
910
if value.encoding != Encoding::UTF_8 && value.respond_to?(:force_encoding)
@@ -21,7 +22,7 @@ def self.valid_utf_8?(value)
2122
end
2223

2324
def self.safe_utf_8_string(value)
24-
valid_utf_8?(value) && value
25+
valid_utf_8?(value) ? value : MALFORMED_STRING
2526
end
2627
end
2728
end

sentry-ruby/spec/sentry/structured_logger_spec.rb

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,52 @@
9696
expect(log_event[:attributes]["sentry.message.parameter.day"]).to eql({ value: "Monday", type: "string" })
9797
end
9898

99-
it "doesn't choke on malformed UTF-8 strings" do
100-
malformed_string = "Hello World\x92".dup.force_encoding("UTF-8")
101-
Sentry.logger.public_send(level, malformed_string, user_id: 123)
99+
context "handling of malformed strings" do
100+
let(:malformed_string_default) do
101+
Sentry::Utils::EncodingHelper::MALFORMED_STRING
102+
end
103+
104+
it "doesn't choke on malformed UTF-8 strings" do
105+
malformed_string = "Hello World\x92".dup.force_encoding("UTF-8")
106+
Sentry.logger.public_send(level, malformed_string, user_id: 123)
107+
108+
expect(sentry_logs).to_not be_empty
109+
110+
log_event = sentry_logs.last
111+
112+
expect(log_event[:level]).to eql(level)
113+
expect(log_event[:body]).to eql(malformed_string_default)
114+
end
115+
116+
it "doesn't choke on malformed UTF-8 in body and attributes" do
117+
malformed_string = "Hello World %{user_agent} \x92".dup.force_encoding("UTF-8")
118+
malformed_user_agent = "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp\xA1\xB1)".dup.force_encoding("UTF-8")
119+
Sentry.logger.public_send(level, malformed_string, user_agent: malformed_user_agent, user_id: 312)
120+
121+
expect(sentry_logs).to_not be_empty
102122

103-
expect(sentry_logs).to be_empty
123+
log_event = sentry_logs.last
124+
125+
expect(log_event[:level]).to eql(level)
126+
expect(log_event[:body]).to eql(malformed_string_default)
127+
128+
expect(log_event[:attributes]["sentry.message.parameter.user_id"]).to be_nil
129+
expect(log_event[:attributes]["sentry.message.parameter.user_agent"]).to be_nil
130+
end
131+
132+
it "doesn't choke on malformed UTF-8 in attributes" do
133+
malformed_user_agent = "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp\xA1\xB1)".dup.force_encoding("UTF-8")
134+
Sentry.logger.public_send(level, "Valid message %{user_agent}", user_agent: malformed_user_agent)
135+
136+
expect(sentry_logs).to_not be_empty
137+
138+
log_event = sentry_logs.last
139+
140+
expect(log_event[:level]).to eql(level)
141+
expect(log_event[:body]).to include("Valid message")
142+
expect(log_event[:attributes]["sentry.message.parameter.user_agent"])
143+
.to eql({ value: malformed_string_default, type: "string" })
144+
end
104145
end
105146
end
106147
end

0 commit comments

Comments
 (0)