diff options
-rw-r--r-- | test/ruby/test_time.rb | 15 | ||||
-rw-r--r-- | time.c | 14 |
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() @@ -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); |