summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-28 05:54:08 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-28 05:54:08 +0000
commit58cfb0653e8f05760a419feb4291d0e2d6847f8e (patch)
tree13b141c3a2f2b3159edcd5000faedd3a112b5197
parentaaf1f031be253f2f24ed19c322398b7694c88a50 (diff)
merge revision(s) 62572: [Backport #14549]
date_core.c: defensive code * ext/date/date_core.c (f_cmp): check comparison failure. * ext/date/date_core.c (d_lite_step): deal with the comparison result more defensively. [ruby-core:85796] [Bug #14549] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@62947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog9
-rw-r--r--ext/date/date_core.c30
-rw-r--r--test/date/test_date_arith.rb13
-rw-r--r--version.h2
4 files changed, 37 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index f10e10c58b..e37690f168 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Thu Mar 28 14:53:57 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ date_core.c: defensive code
+
+ * ext/date/date_core.c (f_cmp): check comparison failure.
+
+ * ext/date/date_core.c (d_lite_step): deal with the comparison
+ result more defensively. [Bug #14549]
+
Thu Mar 28 14:50:52 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
string.c: clear substring code range
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
index 154c559976..fed8160fd8 100644
--- a/ext/date/date_core.c
+++ b/ext/date/date_core.c
@@ -50,18 +50,18 @@ static double positive_inf, negative_inf;
#define f_add3(x,y,z) f_add(f_add(x, y), z)
#define f_sub3(x,y,z) f_sub(f_sub(x, y), z)
-inline static VALUE
+inline static int
f_cmp(VALUE x, VALUE y)
{
if (FIXNUM_P(x) && FIXNUM_P(y)) {
long c = FIX2LONG(x) - FIX2LONG(y);
if (c > 0)
- c = 1;
+ return 1;
else if (c < 0)
- c = -1;
- return INT2FIX(c);
+ return -1;
+ return 0;
}
- return rb_funcall(x, id_cmp, 1, y);
+ return rb_cmpint(rb_funcallv(x, id_cmp, 1, &y), x, y);
}
inline static VALUE
@@ -6115,6 +6115,7 @@ static VALUE
d_lite_step(int argc, VALUE *argv, VALUE self)
{
VALUE limit, step, date;
+ int c;
rb_scan_args(argc, argv, "11", &limit, &step);
@@ -6129,25 +6130,22 @@ d_lite_step(int argc, VALUE *argv, VALUE self)
RETURN_ENUMERATOR(self, argc, argv);
date = self;
- switch (FIX2INT(f_cmp(step, INT2FIX(0)))) {
- case -1:
+ c = f_cmp(step, INT2FIX(0));
+ if (c < 0) {
while (FIX2INT(d_lite_cmp(date, limit)) >= 0) {
rb_yield(date);
date = d_lite_plus(date, step);
}
- break;
- case 0:
+ }
+ else if (c == 0) {
while (1)
rb_yield(date);
- break;
- case 1:
+ }
+ else /* if (c > 0) */ {
while (FIX2INT(d_lite_cmp(date, limit)) <= 0) {
rb_yield(date);
date = d_lite_plus(date, step);
}
- break;
- default:
- abort();
}
return self;
}
@@ -6202,9 +6200,9 @@ cmp_gen(VALUE self, VALUE other)
get_d1(self);
if (k_numeric_p(other))
- return f_cmp(m_ajd(dat), other);
+ return INT2FIX(f_cmp(m_ajd(dat), other));
else if (k_date_p(other))
- return f_cmp(m_ajd(dat), f_ajd(other));
+ return INT2FIX(f_cmp(m_ajd(dat), f_ajd(other)));
return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
}
diff --git a/test/date/test_date_arith.rb b/test/date/test_date_arith.rb
index f5ac5bf30b..5b03d6e7eb 100644
--- a/test/date/test_date_arith.rb
+++ b/test/date/test_date_arith.rb
@@ -262,4 +262,17 @@ class TestDateArith < Test::Unit::TestCase
assert_equal(8, e.to_a.size)
end
+ def test_step__compare
+ o = Object.new
+ def o.<=>(*);end
+ assert_raise(ArgumentError) {
+ Date.new(2000, 1, 1).step(3, o).to_a
+ }
+
+ o = Object.new
+ def o.<=>(*);2;end
+ a = []
+ Date.new(2000, 1, 1).step(3, o) {|d| a << d}
+ assert_empty(a)
+ end
end
diff --git a/version.h b/version.h
index 26109f907e..22a8fac4b8 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.3.7"
#define RUBY_RELEASE_DATE "2018-03-28"
-#define RUBY_PATCHLEVEL 443
+#define RUBY_PATCHLEVEL 444
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 3