summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2023-07-17 16:07:39 +0900
committernagachika <nagachika@ruby-lang.org>2023-07-17 16:07:39 +0900
commit5328c58c7d00540f4f56749aaeefb68761bd7eba (patch)
tree4f1d555b1327d198166f0832f4b552d087fb0128
parent8165db0f4666f90fe0df5cdd466f73c6de1f6cea (diff)
merge revision(s) 1a149aab776aa6741628eb35482eff1ded197fd2,fb17c833f542222afdf482924877d43aa577782d,60f22ebf86248388b41b4ec751d16700f2b4b621: [Backport #19533]
Extract range type check functions --- range.c | 55 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 19 deletions(-) [Bug #19533] Fix infinite range inclusion with numeric value --- range.c | 10 +++++++--- test/ruby/test_range.rb | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) [Bug #19533] Add spec of infinite range inclusion --- spec/ruby/core/range/case_compare_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+)
-rw-r--r--range.c59
-rw-r--r--spec/ruby/core/range/case_compare_spec.rb6
-rw-r--r--test/ruby/test_range.rb2
-rw-r--r--version.h2
4 files changed, 49 insertions, 20 deletions
diff --git a/range.c b/range.c
index 6d90ecf4f3..0176e82ca3 100644
--- a/range.c
+++ b/range.c
@@ -1768,6 +1768,39 @@ range_include(VALUE range, VALUE val)
return rb_call_super(1, &val);
}
+static inline bool
+range_integer_edge_p(VALUE beg, VALUE end)
+{
+ return (!NIL_P(rb_check_to_integer(beg, "to_int")) ||
+ !NIL_P(rb_check_to_integer(end, "to_int")));
+}
+
+static inline bool
+range_string_edge_p(VALUE beg, VALUE end)
+{
+ return RB_TYPE_P(beg, T_STRING) || RB_TYPE_P(end, T_STRING);
+}
+
+static inline bool
+range_string_range_p(VALUE beg, VALUE end)
+{
+ return RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING);
+}
+
+static inline VALUE
+range_include_fallback(VALUE beg, VALUE end, VALUE val)
+{
+ if (NIL_P(beg) && NIL_P(end)) {
+ if (linear_object_p(val)) return Qtrue;
+ }
+
+ if (NIL_P(beg) || NIL_P(end)) {
+ rb_raise(rb_eTypeError, "cannot determine inclusion in beginless/endless ranges");
+ }
+
+ return Qundef;
+}
+
static VALUE
range_string_cover_internal(VALUE range, VALUE val)
{
@@ -1776,13 +1809,11 @@ range_string_cover_internal(VALUE range, VALUE val)
int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
linear_object_p(beg) || linear_object_p(end);
- if (nv ||
- !NIL_P(rb_check_to_integer(beg, "to_int")) ||
- !NIL_P(rb_check_to_integer(end, "to_int"))) {
+ if (nv || range_integer_edge_p(beg, end)) {
return r_cover_p(range, beg, end, val);
}
- else if (RB_TYPE_P(beg, T_STRING) || RB_TYPE_P(end, T_STRING)) {
- if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
+ else if (range_string_edge_p(beg, end)) {
+ if (range_string_range_p(beg, end)) {
return r_cover_p(range, beg, end, val);
}
if (NIL_P(beg)) {
@@ -1800,11 +1831,7 @@ range_string_cover_internal(VALUE range, VALUE val)
}
}
- if (NIL_P(beg) || NIL_P(end)) {
- rb_raise(rb_eTypeError, "cannot determine inclusion in beginless/endless ranges");
- }
-
- return Qundef;
+ return range_include_fallback(beg, end, val);
}
static VALUE
@@ -1815,20 +1842,14 @@ range_include_internal(VALUE range, VALUE val)
int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
linear_object_p(beg) || linear_object_p(end);
- if (nv ||
- !NIL_P(rb_check_to_integer(beg, "to_int")) ||
- !NIL_P(rb_check_to_integer(end, "to_int"))) {
+ if (nv || range_integer_edge_p(beg, end)) {
return r_cover_p(range, beg, end, val);
}
- else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
+ else if (range_string_range_p(beg, end)) {
return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
}
- if (NIL_P(beg) || NIL_P(end)) {
- rb_raise(rb_eTypeError, "cannot determine inclusion in beginless/endless ranges");
- }
-
- return Qundef;
+ return range_include_fallback(beg, end, val);
}
static int r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val);
diff --git a/spec/ruby/core/range/case_compare_spec.rb b/spec/ruby/core/range/case_compare_spec.rb
index 4a3faa3163..65878aaabe 100644
--- a/spec/ruby/core/range/case_compare_spec.rb
+++ b/spec/ruby/core/range/case_compare_spec.rb
@@ -10,4 +10,10 @@ describe "Range#===" do
it_behaves_like :range_cover_and_include, :===
it_behaves_like :range_cover, :===
+
+ ruby_bug "#19533", "3.2"..."3.3" do
+ it "returns true on any value if begin and end are both nil" do
+ (nil..nil).should === 1
+ end
+ end
end
diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb
index bb5ef6df8f..54365f1277 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -539,6 +539,8 @@ class TestRange < Test::Unit::TestCase
assert_not_operator(0..10, :===, 11)
assert_operator(5..nil, :===, 11)
assert_not_operator(5..nil, :===, 0)
+ assert_operator(nil..10, :===, 0)
+ assert_operator(nil..nil, :===, 0)
end
def test_eqq_string
diff --git a/version.h b/version.h
index d250f33336..9b392f9c64 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 2
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 87
+#define RUBY_PATCHLEVEL 88
#include "ruby/version.h"
#include "ruby/internal/abi.h"