Tighten Time.new(string) parsing
Disallow: * Only year-month * Only year-month-day * Preceding whitespace * Trailing whitespace Fixes [Bug #19293]
This commit is contained in:
parent
d814722fb8
commit
5d4fff8456
Notes:
git
2023-07-13 23:49:59 +00:00
@ -75,6 +75,7 @@ class TestTime < Test::Unit::TestCase
|
|||||||
Time.new("2020-12-25 00 +09:00")
|
Time.new("2020-12-25 00 +09:00")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_equal(Time.new(2021), Time.new("2021"))
|
||||||
assert_equal(Time.new(2021, 12, 25, in: "+09:00"), Time.new("2021-12-25+09:00"))
|
assert_equal(Time.new(2021, 12, 25, in: "+09:00"), Time.new("2021-12-25+09:00"))
|
||||||
|
|
||||||
assert_equal(0.123456r, Time.new("2021-12-25 00:00:00.123456 +09:00").subsec)
|
assert_equal(0.123456r, Time.new("2021-12-25 00:00:00.123456 +09:00").subsec)
|
||||||
@ -138,6 +139,18 @@ class TestTime < Test::Unit::TestCase
|
|||||||
assert_raise_with_message(ArgumentError, /mon out of range/) {
|
assert_raise_with_message(ArgumentError, /mon out of range/) {
|
||||||
Time.new("2020-17-25 00:56:17 +0900")
|
Time.new("2020-17-25 00:56:17 +0900")
|
||||||
}
|
}
|
||||||
|
assert_raise_with_message(ArgumentError, /no time information/) {
|
||||||
|
Time.new("2020-12")
|
||||||
|
}
|
||||||
|
assert_raise_with_message(ArgumentError, /no time information/) {
|
||||||
|
Time.new("2020-12-02")
|
||||||
|
}
|
||||||
|
assert_raise_with_message(ArgumentError, /can't parse/) {
|
||||||
|
Time.new(" 2020-12-02 00:00:00")
|
||||||
|
}
|
||||||
|
assert_raise_with_message(ArgumentError, /can't parse/) {
|
||||||
|
Time.new("2020-12-02 00:00:00 ")
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_time_add()
|
def test_time_add()
|
||||||
|
13
time.c
13
time.c
@ -2545,7 +2545,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
|
|||||||
size_t ndigits;
|
size_t ndigits;
|
||||||
size_t prec = NIL_P(precision) ? SIZE_MAX : NUM2SIZET(precision);
|
size_t prec = NIL_P(precision) ? SIZE_MAX : NUM2SIZET(precision);
|
||||||
|
|
||||||
while ((ptr < end) && ISSPACE(*ptr)) ptr++;
|
if ((ptr < end) && (ISSPACE(*ptr) || ISSPACE(*(end-1)))) {
|
||||||
|
rb_raise(rb_eArgError, "can't parse: %+"PRIsVALUE, str);
|
||||||
|
}
|
||||||
year = parse_int(ptr, end, &ptr, &ndigits, true);
|
year = parse_int(ptr, end, &ptr, &ndigits, true);
|
||||||
if (NIL_P(year)) {
|
if (NIL_P(year)) {
|
||||||
rb_raise(rb_eArgError, "can't parse: %+"PRIsVALUE, str);
|
rb_raise(rb_eArgError, "can't parse: %+"PRIsVALUE, str);
|
||||||
@ -2553,6 +2555,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
|
|||||||
else if (ndigits < 4) {
|
else if (ndigits < 4) {
|
||||||
rb_raise(rb_eArgError, "year must be 4 or more digits: %.*s", (int)ndigits, ptr - ndigits);
|
rb_raise(rb_eArgError, "year must be 4 or more digits: %.*s", (int)ndigits, ptr - ndigits);
|
||||||
}
|
}
|
||||||
|
else if (ptr == end) {
|
||||||
|
goto only_year;
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
#define peekable_p(n) ((ptrdiff_t)(n) < (end - ptr))
|
#define peekable_p(n) ((ptrdiff_t)(n) < (end - ptr))
|
||||||
#define peek_n(c, n) (peekable_p(n) && ((unsigned char)ptr[n] == (c)))
|
#define peek_n(c, n) (peekable_p(n) && ((unsigned char)ptr[n] == (c)))
|
||||||
@ -2613,6 +2618,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
|
|||||||
if (zend > zstr) {
|
if (zend > zstr) {
|
||||||
zone = rb_str_subseq(str, zstr - begin, zend - zstr);
|
zone = rb_str_subseq(str, zstr - begin, zend - zstr);
|
||||||
}
|
}
|
||||||
|
else if (hour == -1) {
|
||||||
|
rb_raise(rb_eArgError, "no time information");
|
||||||
|
}
|
||||||
if (!NIL_P(subsec)) {
|
if (!NIL_P(subsec)) {
|
||||||
/* subseconds is the last using ndigits */
|
/* subseconds is the last using ndigits */
|
||||||
static const size_t TIME_SCALE_NUMDIGITS =
|
static const size_t TIME_SCALE_NUMDIGITS =
|
||||||
@ -2629,6 +2637,9 @@ time_init_parse(rb_execution_context_t *ec, VALUE klass, VALUE str, VALUE zone,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
only_year:
|
||||||
|
;
|
||||||
|
|
||||||
struct vtm vtm = {
|
struct vtm vtm = {
|
||||||
.wday = VTM_WDAY_INITVAL,
|
.wday = VTM_WDAY_INITVAL,
|
||||||
.yday = 0,
|
.yday = 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user