From 96617ad1d57a13e9a282fb663ea73e4801519389 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 15 Oct 2019 01:25:05 -0300 Subject: [PATCH] IRB colorize: take into account recursive arrays and hashes (#2555) [Bug #16250] --- lib/irb/color.rb | 22 ++++++++++++++++++---- test/irb/test_color.rb | 2 ++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/irb/color.rb b/lib/irb/color.rb index 6b489646b5..32de6cdbea 100644 --- a/lib/irb/color.rb +++ b/lib/irb/color.rb @@ -70,16 +70,30 @@ module IRB # :nodoc: $stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb')) end - def inspect_colorable?(obj) + def inspect_colorable?(obj, seen = {}) case obj when String, Symbol, Regexp, Integer, Float, FalseClass, TrueClass, NilClass true when Hash - obj.all? { |k, v| inspect_colorable?(k) && inspect_colorable?(v) } + if seen.has_key?(obj.object_id) + false + else + seen[obj.object_id] = true + colorable = obj.all? { |k, v| inspect_colorable?(k, seen) && inspect_colorable?(v, seen) } + seen.delete(obj.object_id) + colorable + end when Array - obj.all? { |o| inspect_colorable?(o) } + if seen.has_key?(obj.object_id) + false + else + seen[obj.object_id] = true + colorable = obj.all? { |o| inspect_colorable?(o, seen) } + seen.delete(obj.object_id) + colorable + end when Range - inspect_colorable?(obj.begin) && inspect_colorable?(obj.end) + inspect_colorable?(obj.begin, seen) && inspect_colorable?(obj.end, seen) when Module !obj.name.nil? else diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb index 3ecbee8cd6..ba76164314 100644 --- a/test/irb/test_color.rb +++ b/test/irb/test_color.rb @@ -125,6 +125,8 @@ module TestIRB 1 => true, 2.3 => true, ['foo', :bar] => true, + (a = []; a << a; a) => false, + (h = {}; h[h] = h; h) => false, { a: 4 } => true, /reg/ => true, (1..3) => true,