From 27beed6a16c7b188f3c2db5498d0bc8542a7e32b Mon Sep 17 00:00:00 2001 From: Joe Haines Date: Mon, 11 Mar 2024 12:45:48 +0000 Subject: [PATCH 1/5] Fix Unicode encoding issues with detailed_message --- CHANGELOG.md | 5 +++ lib/bugsnag/report.rb | 9 ++++- spec/report_spec.rb | 92 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 90 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68d4473f..746122f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ Changelog ========= +## TBD + +* Fix Unicode encoding issues when using `Exception#detailed_message` (Ruby 3.2+) + | [#817](https://github.com/bugsnag/bugsnag-ruby/pull/817) + ## v6.26.3 (24 January 2024) * Handle mailto links in `Cleaner#clean_url` diff --git a/lib/bugsnag/report.rb b/lib/bugsnag/report.rb index c2958d39..92d1b56c 100644 --- a/lib/bugsnag/report.rb +++ b/lib/bugsnag/report.rb @@ -466,8 +466,15 @@ def error_message(exception, class_name) exception.detailed_message end + # the string returned by 'detailed_message' defaults to 'ASCII_8BIT' but + # is actually UTF-8 encoded; we can't convert the encoding normally as its + # internal encoding doesn't match its actual encoding + message.force_encoding(::Encoding::UTF_8) if message.encoding == ::Encoding::ASCII_8BIT + # remove the class name to be consistent with Exception#message - message.sub(" (#{class_name})", '') + message.sub!(" (#{class_name})".encode(message.encoding), "") rescue nil + + message end def generate_raw_exceptions(exception) diff --git a/spec/report_spec.rb b/spec/report_spec.rb index 3756a741..a6c3bd5a 100644 --- a/spec/report_spec.rb +++ b/spec/report_spec.rb @@ -40,6 +40,17 @@ def detailed_message end end +class ExceptionWithDetailedMessageReturningEncodedString < Exception + def initialize(message, encoding) + super(message) + @encoding = encoding + end + + def detailed_message + "abc #{self} xyz".encode(@encoding) + end +end + shared_examples "Report or Event tests" do |class_to_test| context "metadata" do include_examples( @@ -1465,24 +1476,75 @@ def detailed_message } end - it "uses Exception#detailed_message if available" do - Bugsnag.notify(ExceptionWithDetailedMessage.new("some message")) + context "#detailed_message" do + it "uses Exception#detailed_message if available" do + Bugsnag.notify(ExceptionWithDetailedMessage.new("some message")) - expect(Bugsnag).to have_sent_notification{ |payload, headers| - exception = get_exception_from_payload(payload) - expect(exception["errorClass"]).to eq("ExceptionWithDetailedMessage") - expect(exception["message"]).to eq("some message with some extra detail") - } - end + expect(Bugsnag).to have_sent_notification{ |payload, headers| + exception = get_exception_from_payload(payload) + expect(exception["errorClass"]).to eq("ExceptionWithDetailedMessage") + expect(exception["message"]).to eq("some message with some extra detail") + } + end - it "handles implementations of Exception#detailed_message with no 'highlight' parameter" do - Bugsnag.notify(ExceptionWithDetailedMessageButNoHighlight.new("some message")) + it "handles implementations of Exception#detailed_message with no 'highlight' parameter" do + Bugsnag.notify(ExceptionWithDetailedMessageButNoHighlight.new("some message")) - expect(Bugsnag).to have_sent_notification{ |payload, headers| - exception = get_exception_from_payload(payload) - expect(exception["errorClass"]).to eq("ExceptionWithDetailedMessageButNoHighlight") - expect(exception["message"]).to eq("detail about 'some message'") - } + expect(Bugsnag).to have_sent_notification{ |payload, headers| + exception = get_exception_from_payload(payload) + expect(exception["errorClass"]).to eq("ExceptionWithDetailedMessageButNoHighlight") + expect(exception["message"]).to eq("detail about 'some message'") + } + end + + it "converts ASCII_8BIT encoding to UTF-8" do + Bugsnag.notify(Exception.new("大好き\n大好き")) + + expect(Bugsnag).to have_sent_notification{ |payload, headers| + exception = get_exception_from_payload(payload) + expect(exception["message"]).to eq("大好き\n大好き") + } + end + + it "leaves UTF-8 strings as-is" do + exception = ExceptionWithDetailedMessageButNoHighlight.new("Обичам те\n大好き") + expect(exception.detailed_message.encoding).to be(Encoding::UTF_8) + + Bugsnag.notify(exception) + + expect(Bugsnag).to have_sent_notification{ |payload, headers| + exception = get_exception_from_payload(payload) + expect(exception["message"]).to eq("detail about 'Обичам те\n大好き'") + } + end + + it "handles UTF-16 strings" do + exception = ExceptionWithDetailedMessageReturningEncodedString.new("Обичам те\n大好き", Encoding::UTF_16) + expect(exception.detailed_message.encoding).to be(Encoding::UTF_16) + + Bugsnag.notify(exception) + + expect(Bugsnag).to have_sent_notification{ |payload, headers| + exception = get_exception_from_payload(payload) + + # the exception message is converted to UTF-8 by the Cleaner + expect(exception["message"]).to eq("abc Обичам те\n大好き xyz") + } + end + + it "handles Shift JIS strings" do + exception = ExceptionWithDetailedMessageReturningEncodedString.new("大好き\n大好き", Encoding::Shift_JIS) + expect(exception.detailed_message.encoding).to be(Encoding::Shift_JIS) + + Bugsnag.notify(exception) + + expect(Bugsnag).to have_sent_notification{ |payload, headers| + exception = get_exception_from_payload(payload) + + # the exception message is converted to UTF-8 by the Cleaner + expect(exception["message"]).to eq("abc 大好き\n大好き xyz") + } + end end it "supports unix-style paths in backtraces" do From 9eff89659984991e0e6b0ab4206ef8b6e18f23cb Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 26 Feb 2024 23:02:20 -0800 Subject: [PATCH 2/5] Fix compatibility with Ruby 3.4-dev --- lib/bugsnag/stacktrace.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bugsnag/stacktrace.rb b/lib/bugsnag/stacktrace.rb index fd932a04..4d24d95f 100644 --- a/lib/bugsnag/stacktrace.rb +++ b/lib/bugsnag/stacktrace.rb @@ -3,7 +3,7 @@ module Bugsnag module Stacktrace # e.g. "org/jruby/RubyKernel.java:1264:in `catch'" - BACKTRACE_LINE_REGEX = /^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$/ + BACKTRACE_LINE_REGEX = /^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in [`']([^']+)')?$/ # e.g. "org.jruby.Ruby.runScript(Ruby.java:807)" JAVA_BACKTRACE_REGEX = /^(.*)\((.*)(?::([0-9]+))?\)$/ From 0ca1b1045741652417394fa2ef3cfe2c8934a158 Mon Sep 17 00:00:00 2001 From: Joe Haines Date: Fri, 15 Mar 2024 13:39:00 +0000 Subject: [PATCH 3/5] Add #815 to changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 746122f7..b9489cb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Changelog * Fix Unicode encoding issues when using `Exception#detailed_message` (Ruby 3.2+) | [#817](https://github.com/bugsnag/bugsnag-ruby/pull/817) +* Fix compatibility with Ruby 3.4-dev + | [#815](https://github.com/bugsnag/bugsnag-ruby/pull/815) + | [k0kubun](https://github.com/k0kubun) ## v6.26.3 (24 January 2024) From a5f723f1016a22c410e30ec57bd8bd962f1b2c6b Mon Sep 17 00:00:00 2001 From: Joe Haines Date: Mon, 25 Mar 2024 09:52:34 +0000 Subject: [PATCH 4/5] Update changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9489cb8..111dc799 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ Changelog ========= -## TBD +## v6.26.4 (25 March 2024) + +### Fixes * Fix Unicode encoding issues when using `Exception#detailed_message` (Ruby 3.2+) | [#817](https://github.com/bugsnag/bugsnag-ruby/pull/817) @@ -11,6 +13,8 @@ Changelog ## v6.26.3 (24 January 2024) +### Fixes + * Handle mailto links in `Cleaner#clean_url` | [#813](https://github.com/bugsnag/bugsnag-ruby/pull/813) From 50282e3b08780c09644d45f7f979815cb74a7df6 Mon Sep 17 00:00:00 2001 From: Joe Haines Date: Mon, 25 Mar 2024 09:52:46 +0000 Subject: [PATCH 5/5] Bump version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 7eeb87d9..30bfaeb1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.26.3 +6.26.4