summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_time.rb15
-rw-r--r--time.c14
2 files changed, 23 insertions, 6 deletions
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index d85e1f89d1..38c1af6901 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -99,30 +99,45 @@ class TestTime < Test::Unit::TestCase
assert_raise_with_message(ArgumentError, /two digits sec.*:9\b/) {
Time.new("2020-12-25 00:56:9 +0900")
}
+ assert_raise_with_message(ArgumentError, /sec out of range/) {
+ Time.new("2020-12-25 00:56:64 +0900")
+ }
assert_raise_with_message(ArgumentError, /two digits min.*:056\b/) {
Time.new("2020-12-25 00:056:17 +0900")
}
assert_raise_with_message(ArgumentError, /two digits min.*:5\b/) {
Time.new("2020-12-25 00:5:17 +0900")
}
+ assert_raise_with_message(ArgumentError, /min out of range/) {
+ Time.new("2020-12-25 00:64:17 +0900")
+ }
assert_raise_with_message(ArgumentError, /two digits hour.*\b000\b/) {
Time.new("2020-12-25 000:56:17 +0900")
}
assert_raise_with_message(ArgumentError, /two digits hour.*\b0\b/) {
Time.new("2020-12-25 0:56:17 +0900")
}
+ assert_raise_with_message(ArgumentError, /hour out of range/) {
+ Time.new("2020-12-25 33:56:17 +0900")
+ }
assert_raise_with_message(ArgumentError, /two digits mday.*\b025\b/) {
Time.new("2020-12-025 00:56:17 +0900")
}
assert_raise_with_message(ArgumentError, /two digits mday.*\b5\b/) {
Time.new("2020-12-5 00:56:17 +0900")
}
+ assert_raise_with_message(ArgumentError, /mday out of range/) {
+ Time.new("2020-12-33 00:56:17 +0900")
+ }
assert_raise_with_message(ArgumentError, /two digits mon.*\b012\b/) {
Time.new("2020-012-25 00:56:17 +0900")
}
assert_raise_with_message(ArgumentError, /two digits mon.*\b1\b/) {
Time.new("2020-1-25 00:56:17 +0900")
}
+ assert_raise_with_message(ArgumentError, /mon out of range/) {
+ Time.new("2020-17-25 00:56:17 +0900")
+ }
end
def test_time_add()
diff --git a/time.c b/time.c
index 02e88c140e..9c4c93939e 100644
--- a/time.c
+++ b/time.c
@@ -2541,11 +2541,13 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
#define peek(c) peek_n(c, 0)
#define peekc_n(n) (peekable_p(n) ? (int)(unsigned char)ptr[n] : -1)
#define peekc() peekc_n(0)
-#define expect_two_digits(x) (x = two_digits(ptr + 1, end, &ptr, #x))
+#define expect_two_digits(x, bits) \
+ (((unsigned int)(x = two_digits(ptr + 1, end, &ptr, #x)) > (1U << bits) - 1) ? \
+ rb_raise(rb_eArgError, #x" out of range") : (void)0)
if (!peek('-')) break;
- expect_two_digits(mon);
+ expect_two_digits(mon, 4);
if (!peek('-')) break;
- expect_two_digits(mday);
+ expect_two_digits(mday, 5);
if (!peek(' ') && !peek('T')) break;
const char *const time_part = ptr + 1;
if (!ISDIGIT(peekc_n(1))) break;
@@ -2559,13 +2561,13 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
rb_raise(rb_eArgError, "missing " #x " part: %.*s", \
(int)(ptr + 1 - time_part), time_part); \
}
- expect_two_digits(hour);
+ expect_two_digits(hour, 5);
nofraction(hour);
need_colon(min);
- expect_two_digits(min);
+ expect_two_digits(min, 6);
nofraction(min);
need_colon(sec);
- expect_two_digits(sec);
+ expect_two_digits(sec, 6);
if (peek('.')) {
ptr++;
for (ndigits = 0; ndigits < prec && ISDIGIT(peekc_n(ndigits)); ++ndigits);