Skip to content

Commit

Permalink
- Fixed exception sanitization by removing TypeError restriction on r…
Browse files Browse the repository at this point in the history
…escue.

Fixes #921

[git-p4: depot-paths = "//src/minitest/dev/": change = 13507]
  • Loading branch information
zenspider committed Aug 17, 2022
1 parent 9c5f100 commit d24fba6
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/minitest/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def capture_exceptions # :nodoc:
def sanitize_exception e # :nodoc:
Marshal.dump e
e # good: use as-is
rescue TypeError
rescue
neuter_exception e
end

Expand All @@ -213,7 +213,7 @@ def neuter_exception e
msg = e.message.dup

new_exception e.class, msg, bt # e.class can be a problem...
rescue TypeError
rescue
msg.prepend "Neutered Exception #{e.class}: "

new_exception RuntimeError, msg, bt, true # but if this raises, we die
Expand Down
43 changes: 43 additions & 0 deletions test/minitest/test_minitest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,49 @@ def test_spec_marshal_with_exception__better_error_typeerror
assert_equal @tc.failures, over_the_wire.failures
assert_equal @tc.klass, over_the_wire.klass
end

def test_spec_marshal_with_exception__worse_error_typeerror
worse_error_klass = Class.new(StandardError) do
# problem #1: anonymous subclass can'tmarshal, fails sanitize_exception
def initialize(record = nil)

super(record.first)
end
end

klass = describe("whatever") {
it("raises with NoMethodError") {
# problem #2: instantiated with a NON-string argument
#
# problem #3: arg responds to #first, but it becomes message
# which gets passed back in via new_exception
# that passes a string to worse_error_klass#initialize
# which calls first on it, which raises NoMethodError
raise worse_error_klass.new(["boom"])
}
}

rm = klass.runnable_methods.first

# Run the test
@tc = klass.new(rm).run

assert_kind_of Minitest::Result, @tc
assert_instance_of Minitest::UnexpectedError, @tc.failure

msg = @tc.failure.error.message.gsub(/0x[A-Fa-f0-9]+/, "0xXXX")

assert_equal "Neutered Exception #<Class:0xXXX>: boom", msg

# Pass it over the wire
over_the_wire = Marshal.load Marshal.dump @tc

assert_equal @tc.time, over_the_wire.time
assert_equal @tc.name, over_the_wire.name
assert_equal @tc.assertions, over_the_wire.assertions
assert_equal @tc.failures, over_the_wire.failures
assert_equal @tc.klass, over_the_wire.klass
end
end

class TestMinitestTest < TestMinitestRunnable
Expand Down

0 comments on commit d24fba6

Please sign in to comment.