summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-01-29 05:05:04 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-01-29 05:05:04 +0000
commit0b494041de37c9b7261ac5643b1b93147d3c6653 (patch)
tree592a4b7499e3d8e69662325ac459183bdf21686b
parent54bd3c23fb8d218b3c551da89d040bf9544eae9a (diff)
merge revision(s) 43208: [Backport #9003]
* compar.c (cmp_eq): fail if recursion. [ruby-core:57736] [Bug #9003] * thread.c (rb_exec_recursive_paired_outer): new function which is combinnation of paired and outer variants. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@44742 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog7
-rw-r--r--compar.c9
-rw-r--r--include/ruby/intern.h1
-rw-r--r--test/ruby/test_comparable.rb7
-rw-r--r--thread.c12
-rw-r--r--version.h2
6 files changed, 36 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 53b487e67a..e2a81f4942 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Jan 29 14:00:15 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * compar.c (cmp_eq): fail if recursion. [ruby-core:57736] [Bug #9003]
+
+ * thread.c (rb_exec_recursive_paired_outer): new function which is
+ combinnation of paired and outer variants.
+
Wed Jan 29 13:40:48 2014 Eric Hodel <drbrain@segment7.net>
* lib/net/smtp.rb (Net::SMTP#critical): Always return a
diff --git a/compar.c b/compar.c
index 65def78484..b7d4f9c937 100644
--- a/compar.c
+++ b/compar.c
@@ -32,9 +32,16 @@ rb_cmperr(VALUE x, VALUE y)
}
static VALUE
+cmp_eq_recursive(VALUE arg1, VALUE arg2, int recursive)
+{
+ if (recursive) return Qfalse;
+ return rb_funcall2(arg1, cmp, 1, &arg2);
+}
+
+static VALUE
cmp_eq(VALUE *a)
{
- VALUE c = rb_funcall(a[0], cmp, 1, a[1]);
+ VALUE c = rb_exec_recursive_paired_outer(cmp_eq_recursive, a[0], a[1], a[1]);
if (NIL_P(c)) return Qfalse;
if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue;
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 032f9af097..7f1b078136 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -399,6 +399,7 @@ void rb_thread_atfork_before_exec(void);
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE);
VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
+VALUE rb_exec_recursive_paired_outer(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE,VALUE);
/* dir.c */
VALUE rb_dir_getwd(void);
/* file.c */
diff --git a/test/ruby/test_comparable.rb b/test/ruby/test_comparable.rb
index 00ce6b485a..3526c73add 100644
--- a/test/ruby/test_comparable.rb
+++ b/test/ruby/test_comparable.rb
@@ -69,4 +69,11 @@ class TestComparable < Test::Unit::TestCase
assert_raise(ArgumentError) { 1.0 < nil }
assert_raise(ArgumentError) { 1.0 < Object.new }
end
+
+ def test_no_cmp
+ bug9003 = '[ruby-core:57736] [Bug #9003]'
+ assert_nothing_raised(SystemStackError, bug9003) {
+ @o <=> @o.dup
+ }
+ end
end
diff --git a/thread.c b/thread.c
index 387bf1ff72..ca94cbea25 100644
--- a/thread.c
+++ b/thread.c
@@ -4376,6 +4376,18 @@ rb_clear_trace_func(void)
static void call_trace_func(rb_event_flag_t, VALUE data, VALUE self, ID id, VALUE klass);
/*
+ * If recursion is detected on the current method, obj and paired_obj,
+ * the outermost func will be called with (obj, arg, Qtrue). All inner
+ * func will be short-circuited using throw.
+ */
+
+VALUE
+rb_exec_recursive_paired_outer(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE paired_obj, VALUE arg)
+{
+ return exec_recursive(func, obj, rb_obj_id(paired_obj), arg, 1);
+}
+
+/*
* call-seq:
* set_trace_func(proc) -> proc
* set_trace_func(nil) -> nil
diff --git a/version.h b/version.h
index 32eb0bcfc5..641659c242 100644
--- a/version.h
+++ b/version.h
@@ -1,5 +1,5 @@
#define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 496
+#define RUBY_PATCHLEVEL 497
#define RUBY_RELEASE_DATE "2014-01-29"
#define RUBY_RELEASE_YEAR 2014