Skip to content

Commit

Permalink
Prevent infinite recursion via Exception#cause
Browse files Browse the repository at this point in the history
It is possible the causes of two exceptions to refer to each other.
When displaying the causes to the user rake would raise a
SystemStackError trying to show the causes repeatedly.

Now rake looks for seen causes and stops when it sees the same cause a
second time.

Fixes #272
  • Loading branch information
drbrain committed May 13, 2014
1 parent 3a8f06f commit 57c932c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
7 changes: 7 additions & 0 deletions History.rdoc
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
=== 10.3.2

Bug fixes:

* Rake no longer infinitely loops when showing exception causes that refer to
each other. Bug #272 by Chris Bandy.

=== 10.3.1 / 2014-04-17

Bug fixes:
Expand Down
4 changes: 4 additions & 0 deletions lib/rake/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ def display_error_message(ex) # :nodoc:
end

def display_exception_details(ex) # :nodoc:
seen = Thread.current[:rake_display_exception_details_seen] ||= []
return if seen.include? ex
seen << ex

display_exception_message_details(ex)
display_exception_backtrace(ex)
display_exception_details(ex.cause) if has_cause?(ex)
Expand Down
27 changes: 27 additions & 0 deletions test/test_rake_application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,33 @@ def test_display_exception_details_cause
assert_match 'cause b', err
end

def test_display_exception_details_cause_loop
skip 'Exception#cause not implemented' unless
Exception.method_defined? :cause

begin
begin
raise 'cause a'
rescue => a
begin
raise 'cause b'
rescue
raise a
end
end
rescue => ex
end

out, err = capture_io do
@app.display_error_message ex
end

assert_empty out

assert_match 'cause a', err
assert_match 'cause b', err
end

def test_display_tasks
@app.options.show_tasks = :tasks
@app.options.show_task_pattern = //
Expand Down

0 comments on commit 57c932c

Please sign in to comment.