diff options
-rw-r--r-- | ext/date/date.gemspec | 7 | ||||
-rw-r--r-- | ext/date/date_core.c | 411 | ||||
-rw-r--r-- | ext/date/date_parse.c | 51 | ||||
-rw-r--r-- | ext/date/date_strptime.c | 6 | ||||
-rw-r--r-- | ext/date/lib/date.rb | 1 | ||||
-rw-r--r-- | test/date/test_date_parse.rb | 164 | ||||
-rw-r--r-- | test/date/test_date_strftime.rb | 7 | ||||
-rw-r--r-- | version.h | 10 |
8 files changed, 426 insertions, 231 deletions
diff --git a/ext/date/date.gemspec b/ext/date/date.gemspec index ddb9608f4e..b30a055746 100644 --- a/ext/date/date.gemspec +++ b/ext/date/date.gemspec @@ -1,7 +1,12 @@ # frozen_string_literal: true + +version = File.foreach(File.expand_path("../lib/date.rb", __FILE__)).find do |line| + /^\s*VERSION\s*=\s*["'](.*)["']/ =~ line and break $1 +end + Gem::Specification.new do |s| s.name = "date" - s.version = '2.0.0' + s.version = version s.summary = "A subclass of Object includes Comparable module for handling dates." s.description = "A subclass of Object includes Comparable module for handling dates." diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 67ed6171a7..918e61234c 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -3692,7 +3692,7 @@ rt_rewrite_frags(VALUE hash) { VALUE seconds; - seconds = del_hash("seconds"); + seconds = ref_hash("seconds"); if (!NIL_P(seconds)) { VALUE offset, d, h, min, s, fr; @@ -3717,6 +3717,7 @@ rt_rewrite_frags(VALUE hash) set_hash("min", min); set_hash("sec", s); set_hash("sec_fraction", fr); + del_hash("seconds"); } return hash; } @@ -4291,12 +4292,40 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass) VALUE date__parse(VALUE str, VALUE comp); +static size_t +get_limit(VALUE opt) +{ + if (!NIL_P(opt)) { + VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit"))); + if (NIL_P(limit)) return SIZE_MAX; + return NUM2SIZET(limit); + } + return 128; +} + +static void +check_limit(VALUE str, VALUE opt) +{ + if (NIL_P(str)) return; + if (SYMBOL_P(str)) str = rb_sym2str(str); + + StringValue(str); + size_t slen = RSTRING_LEN(str); + size_t limit = get_limit(opt); + if (slen > limit) { + rb_raise(rb_eArgError, + "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit); + } +} + static VALUE date_s__parse_internal(int argc, VALUE *argv, VALUE klass) { - VALUE vstr, vcomp, hash; + VALUE vstr, vcomp, hash, opt; - rb_scan_args(argc, argv, "11", &vstr, &vcomp); + rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt); + if (!NIL_P(opt)) argc--; + check_limit(vstr, opt); StringValue(vstr); if (!rb_enc_str_asciicompat_p(vstr)) rb_raise(rb_eArgError, @@ -4306,12 +4335,22 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) hash = date__parse(vstr, vcomp); + { + VALUE zone = ref_hash("zone"); + + if (!NIL_P(zone)) { + rb_enc_copy(zone, vstr); + OBJ_INFECT(zone, vstr); + set_hash("zone", zone); + } + } + return hash; } /* * call-seq: - * Date._parse(string[, comp=true]) -> hash + * Date._parse(string[, comp=true], limit: 128) -> hash * * Parses the given representation of date and time, and returns a * hash of parsed elements. This method does not function as a @@ -4322,6 +4361,10 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) * it full. * * Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3} + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s__parse(int argc, VALUE *argv, VALUE klass) @@ -4331,7 +4374,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]]) -> date + * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]], limit: 128) -> date * * Parses the given representation of date and time, and creates a * date object. This method does not function as a validator. @@ -4343,13 +4386,18 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) * Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...> * Date.parse('20010203') #=> #<Date: 2001-02-03 ...> * Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s_parse(int argc, VALUE *argv, VALUE klass) { - VALUE str, comp, sg; + VALUE str, comp, sg, opt; - rb_scan_args(argc, argv, "03", &str, &comp, &sg); + rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -4361,11 +4409,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass) } { - VALUE argv2[2], hash; - - argv2[0] = str; - argv2[1] = comp; - hash = date_s__parse(2, argv2, klass); + int argc2 = 2; + VALUE argv2[3]; + argv2[0] = str; + argv2[1] = comp; + if (!NIL_P(opt)) argv2[argc2++] = opt; + VALUE hash = date_s__parse(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } @@ -4379,19 +4428,28 @@ VALUE date__jisx0301(VALUE); /* * call-seq: - * Date._iso8601(string) -> hash + * Date._iso8601(string, limit: 128) -> hash * * Returns a hash of parsed elements. + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE -date_s__iso8601(VALUE klass, VALUE str) +date_s__iso8601(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + return date__iso8601(str); } /* * call-seq: - * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY]) -> date + * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date * * Creates a new Date object by parsing from a string according to * some typical ISO 8601 formats. @@ -4399,13 +4457,18 @@ date_s__iso8601(VALUE klass, VALUE str) * Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...> * Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...> * Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s_iso8601(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -4415,38 +4478,56 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__iso8601(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + VALUE hash = date_s__iso8601(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._rfc3339(string) -> hash + * Date._rfc3339(string, limit: 128) -> hash * * Returns a hash of parsed elements. + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE -date_s__rfc3339(VALUE klass, VALUE str) +date_s__rfc3339(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + return date__rfc3339(str); } /* * call-seq: - * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> date + * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> date * * Creates a new Date object by parsing from a string according to * some typical RFC 3339 formats. * * Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s_rfc3339(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -4456,38 +4537,56 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__rfc3339(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + VALUE hash = date_s__rfc3339(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._xmlschema(string) -> hash + * Date._xmlschema(string, limit: 128) -> hash * * Returns a hash of parsed elements. + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE -date_s__xmlschema(VALUE klass, VALUE str) +date_s__xmlschema(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + return date__xmlschema(str); } /* * call-seq: - * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY]) -> date + * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date * * Creates a new Date object by parsing from a string according to * some typical XML Schema formats. * * Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s_xmlschema(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -4497,41 +4596,58 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__xmlschema(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + VALUE hash = date_s__xmlschema(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._rfc2822(string) -> hash - * Date._rfc822(string) -> hash + * Date._rfc2822(string, limit: 128) -> hash + * Date._rfc822(string, limit: 128) -> hash * * Returns a hash of parsed elements. + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE -date_s__rfc2822(VALUE klass, VALUE str) +date_s__rfc2822(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + return date__rfc2822(str); } /* * call-seq: - * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date - * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date + * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date + * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date * * Creates a new Date object by parsing from a string according to * some typical RFC 2822 formats. * * Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000') * #=> #<Date: 2001-02-03 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s_rfc2822(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: @@ -4541,39 +4657,56 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__rfc2822(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + VALUE hash = date_s__rfc2822(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._httpdate(string) -> hash + * Date._httpdate(string, limit: 128) -> hash * * Returns a hash of parsed elements. + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE -date_s__httpdate(VALUE klass, VALUE str) +date_s__httpdate(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + return date__httpdate(str); } /* * call-seq: - * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) -> date + * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY], limit: 128) -> date * * Creates a new Date object by parsing from a string according to * some RFC 2616 format. * * Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT') * #=> #<Date: 2001-02-03 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s_httpdate(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); switch (argc) { case 0: @@ -4583,42 +4716,56 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__httpdate(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + VALUE hash = date_s__httpdate(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } /* * call-seq: - * Date._jisx0301(string) -> hash + * Date._jisx0301(string, limit: 128) -> hash * * Returns a hash of parsed elements. + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE -date_s__jisx0301(VALUE klass, VALUE str) +date_s__jisx0301(int argc, VALUE *argv, VALUE klass) { + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + return date__jisx0301(str); } /* * call-seq: - * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY]) -> date + * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date * * Creates a new Date object by parsing from a string according to * some typical JIS X 0301 formats. * * Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...> * - * For no-era year, legacy format, Heisei is assumed. - * - * Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...> + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE date_s_jisx0301(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -4628,7 +4775,11 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__jisx0301(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + VALUE hash = date_s__jisx0301(argc2, argv2, klass); return d_new_by_frags(klass, hash, sg); } } @@ -7039,14 +7190,10 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y) c = 'S'; s = 1925; } - else if (d < 2458605) { + else { c = 'H'; s = 1988; } - else { - c = 'R'; - s = 2018; - } snprintf(fmt, size, "%c%02ld" ".%%m.%%d", c, FIX2INT(y) - s); return fmt; } @@ -7948,7 +8095,7 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]]) -> datetime + * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) -> datetime * * Parses the given representation of date and time, and creates a * DateTime object. This method does not function as a validator. @@ -7962,13 +8109,18 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass) * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> * DateTime.parse('3rd Feb 2001 04:05:06 PM') * #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE datetime_s_parse(int argc, VALUE *argv, VALUE klass) { - VALUE str, comp, sg; + VALUE str, comp, sg, opt; - rb_scan_args(argc, argv, "03", &str, &comp, &sg); + rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -7980,18 +8132,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass) } { - VALUE argv2[2], hash; - - argv2[0] = str; - argv2[1] = comp; - hash = date_s__parse(2, argv2, klass); + int argc2 = 2; + VALUE argv2[3]; + argv2[0] = str; + argv2[1] = comp; + argv2[2] = opt; + if (!NIL_P(opt)) argc2++; + VALUE hash = date_s__parse(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical ISO 8601 formats. @@ -8002,13 +8156,18 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass) * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> * DateTime.iso8601('2001-W05-6T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE datetime_s_iso8601(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -8018,27 +8177,37 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__iso8601(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2--; + VALUE hash = date_s__iso8601(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical RFC 3339 formats. * * DateTime.rfc3339('2001-02-03T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -8048,27 +8217,37 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__rfc3339(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + VALUE hash = date_s__rfc3339(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical XML Schema formats. * * DateTime.xmlschema('2001-02-03T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -8078,28 +8257,38 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__xmlschema(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + VALUE hash = date_s__xmlschema(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime - * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime + * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime + * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical RFC 2822 formats. * * DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -8109,7 +8298,12 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__rfc2822(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + VALUE hash = date_s__rfc2822(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } @@ -8123,13 +8317,18 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) * * DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT') * #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...> + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -8139,14 +8338,19 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__httpdate(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + VALUE hash = date_s__httpdate(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } /* * call-seq: - * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime + * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime * * Creates a new DateTime object by parsing from a string according to * some typical JIS X 0301 formats. @@ -8154,17 +8358,17 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) * DateTime.jisx0301('H13.02.03T04:05:06+07:00') * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> * - * For no-era year, legacy format, Heisei is assumed. - * - * DateTime.jisx0301('13.02.03T04:05:06+07:00') - * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing `limit: nil`, but note that + * it may take a long time to parse. */ static VALUE datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass) { - VALUE str, sg; + VALUE str, sg, opt; - rb_scan_args(argc, argv, "02", &str, &sg); + rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + if (!NIL_P(opt)) argc--; switch (argc) { case 0: @@ -8174,7 +8378,12 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass) } { - VALUE hash = date_s__jisx0301(klass, str); + int argc2 = 1; + VALUE argv2[2]; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + VALUE hash = date_s__jisx0301(argc2, argv2, klass); return dt_new_by_frags(klass, hash, sg); } } @@ -9325,19 +9534,19 @@ Init_date_core(void) rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1); rb_define_singleton_method(cDate, "_parse", date_s__parse, -1); rb_define_singleton_method(cDate, "parse", date_s_parse, -1); - rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1); + rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1); rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1); - rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1); + rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1); rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1); - rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1); + rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1); rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1); - rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1); - rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1); + rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1); + rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1); rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1); rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1); - rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1); + rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1); rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1); - rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1); + rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1); rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1); rb_define_method(cDate, "initialize", date_initialize, -1); diff --git a/ext/date/date_parse.c b/ext/date/date_parse.c index e0634c39f1..69ac37f0a3 100644 --- a/ext/date/date_parse.c +++ b/ext/date/date_parse.c @@ -1212,9 +1212,6 @@ parse_iso2(VALUE str, VALUE hash) return 1; } -#define JISX0301_ERA_INITIALS "mtshr" -#define JISX0301_DEFAULT_ERA 'H' /* obsolete */ - static int gengo(int c) { @@ -1225,7 +1222,6 @@ gengo(int c) case 'T': case 't': e = 1911; break; case 'S': case 's': e = 1925; break; case 'H': case 'h': e = 1988; break; - case 'R': case 'r': e = 2018; break; default: e = 0; break; } return e; @@ -1256,11 +1252,11 @@ parse_jis(VALUE str, VALUE hash) { static const char pat_source[] = #ifndef TIGHT_PARSER - "\\b([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)" + "\\b([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)" #else BOS FPW_COM FPT_COM - "([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)" + "([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)" TEE_FPT COM_FPW EOS #endif @@ -1863,26 +1859,30 @@ parse_ddd_cb(VALUE m, VALUE hash) set_hash("zone", s5); if (*cs5 == '[') { - const char *s1, *s2; + VALUE vbuf = 0; + char *buf = ALLOCV_N(char, vbuf, l5 + 1); + char *s1, *s2, *s3; VALUE zone; - l5 -= 2; - s1 = cs5 + 1; - s2 = memchr(s1, ':', l5); + memcpy(buf, cs5, l5); + buf[l5 - 1] = '\0'; + + s1 = buf + 1; + s2 = strchr(buf, ':'); if (s2) { + *s2 = '\0'; s2++; - zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1)); - s5 = rb_str_subseq(s5, 1, s2 - s1); } - else { - zone = rb_str_subseq(s5, 1, l5); - if (isdigit((unsigned char)*s1)) - s5 = rb_str_append(rb_str_new_cstr("+"), zone); - else - s5 = zone; - } + if (s2) + s3 = s2; + else + s3 = s1; + zone = rb_str_new2(s3); set_hash("zone", zone); - set_hash("offset", date_zone_to_diff(s5)); + if (isdigit((unsigned char)*s1)) + *--s1 = '+'; + set_hash("offset", date_zone_to_diff(rb_str_new2(s1))); + ALLOCV_END(vbuf); } RB_GC_GUARD(s5); } @@ -2175,7 +2175,7 @@ date__parse(VALUE str, VALUE comp) #endif { - if (RTEST(del_hash("_bc"))) { + if (RTEST(ref_hash("_bc"))) { VALUE y; y = ref_hash("cwyear"); @@ -2190,7 +2190,7 @@ date__parse(VALUE str, VALUE comp) } } - if (RTEST(del_hash("_comp"))) { + if (RTEST(ref_hash("_comp"))) { VALUE y; y = ref_hash("cwyear"); @@ -2213,6 +2213,9 @@ date__parse(VALUE str, VALUE comp) } + del_hash("_bc"); + del_hash("_comp"); + { VALUE zone = ref_hash("zone"); if (!NIL_P(zone) && NIL_P(ref_hash("offset"))) @@ -2951,7 +2954,7 @@ jisx0301_cb(VALUE m, VALUE hash) s[i] = rb_reg_nth_match(i, m); } - ep = gengo(NIL_P(s[1]) ? JISX0301_DEFAULT_ERA : *RSTRING_PTR(s[1])); + ep = gengo(NIL_P(s[1]) ? 'h' : *RSTRING_PTR(s[1])); set_hash("year", f_add(str2num(s[2]), INT2FIX(ep))); set_hash("mon", str2num(s[3])); set_hash("mday", str2num(s[4])); @@ -2976,7 +2979,7 @@ static int jisx0301(VALUE str, VALUE hash) { static const char pat_source[] = - "\\A\\s*([" JISX0301_ERA_INITIALS "])?(\\d{2})\\.(\\d{2})\\.(\\d{2})" + "\\A\\s*([mtsh])?(\\d{2})\\.(\\d{2})\\.(\\d{2})" "(?:t" "(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?" "(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z"; diff --git a/ext/date/date_strptime.c b/ext/date/date_strptime.c index 26d9fd11bf..4383eb6fa1 100644 --- a/ext/date/date_strptime.c +++ b/ext/date/date_strptime.c @@ -669,7 +669,7 @@ date__strptime(const char *str, size_t slen, if (fail_p()) return Qnil; - cent = del_hash("_cent"); + cent = ref_hash("_cent"); if (!NIL_P(cent)) { VALUE year; @@ -679,9 +679,10 @@ date__strptime(const char *str, size_t slen, year = ref_hash("year"); if (!NIL_P(year)) set_hash("year", f_add(year, f_mul(cent, INT2FIX(100)))); + del_hash("_cent"); } - merid = del_hash("_merid"); + merid = ref_hash("_merid"); if (!NIL_P(merid)) { VALUE hour; @@ -690,6 +691,7 @@ date__strptime(const char *str, size_t slen, hour = f_mod(hour, INT2FIX(12)); set_hash("hour", f_add(hour, merid)); } + del_hash("_merid"); } return hash; diff --git a/ext/date/lib/date.rb b/ext/date/lib/date.rb index 9170a99ae9..3556b9295f 100644 --- a/ext/date/lib/date.rb +++ b/ext/date/lib/date.rb @@ -4,6 +4,7 @@ require 'date_core' class Date + VERSION = '2.0.2' # :nodoc: class Infinity < Numeric # :nodoc: diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb index e17fd3eb25..5bc2cebf82 100644 --- a/test/date/test_date_parse.rb +++ b/test/date/test_date_parse.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'test/unit' require 'date' +require 'timeout' class TestDateParse < Test::Unit::TestCase @@ -121,8 +122,6 @@ class TestDateParse < Test::Unit::TestCase [['S40.05.23T23:55:21-09:00',false],[1965,5,23,23,55,21,'-09:00',-9*3600,nil], __LINE__], [['H11.05.23 23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil], __LINE__], [['H11.05.23T23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil], __LINE__], - [['H31.04.30 23:55:21Z',false],[2019,4,30,23,55,21,'Z',0,nil], __LINE__], - [['H31.04.30T23:55:21Z',false],[2019,4,30,23,55,21,'Z',0,nil], __LINE__], # ofx date [['19990523235521',false],[1999,5,23,23,55,21,nil,nil,nil], __LINE__], @@ -418,14 +417,7 @@ class TestDateParse < Test::Unit::TestCase a[1] = -1 a[2] = h[:yday] end - l = format('<failed at line %d>', l) - assert_equal(y, a, l) - if y[6] - h = Date._parse(x[0].dup.taint, *x[1..-1]) - assert_equal(y[6], h[:zone], l) - assert_equal(y[6].encoding, h[:zone].encoding, l) - assert_predicate(h[:zone], :tainted?, l) - end + assert_equal(y, a, format('<failed at line %d>', l)) end end @@ -832,6 +824,13 @@ class TestDateParse < Test::Unit::TestCase h = Date._iso8601('') assert_equal({}, h) + + h = Date._iso8601(nil) + assert_equal({}, h) + + h = Date._iso8601('01-02-03T04:05:06Z'.to_sym) + assert_equal([2001, 2, 3, 4, 5, 6, 0], + h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) end def test__rfc3339 @@ -847,6 +846,13 @@ class TestDateParse < Test::Unit::TestCase h = Date._rfc3339('') assert_equal({}, h) + + h = Date._rfc3339(nil) + assert_equal({}, h) + + h = Date._rfc3339('2001-02-03T04:05:06Z'.to_sym) + assert_equal([2001, 2, 3, 4, 5, 6, 0], + h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) end def test__xmlschema @@ -929,6 +935,13 @@ class TestDateParse < Test::Unit::TestCase h = Date._xmlschema('') assert_equal({}, h) + + h = Date._xmlschema(nil) + assert_equal({}, h) + + h = Date._xmlschema('2001-02-03'.to_sym) + assert_equal([2001, 2, 3, nil, nil, nil, nil], + h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) end def test__rfc2822 @@ -961,6 +974,13 @@ class TestDateParse < Test::Unit::TestCase h = Date._rfc2822('') assert_equal({}, h) + + h = Date._rfc2822(nil) + assert_equal({}, h) + + h = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 UT'.to_sym) + assert_equal([2001, 2, 3, 4, 5, 6, 0], + h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) end def test__httpdate @@ -981,6 +1001,13 @@ class TestDateParse < Test::Unit::TestCase h = Date._httpdate('') assert_equal({}, h) + + h = Date._httpdate(nil) + assert_equal({}, h) + + h = Date._httpdate('Sat, 03 Feb 2001 04:05:06 GMT'.to_sym) + assert_equal([2001, 2, 3, 4, 5, 6, 0], + h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) end def test__jisx0301 @@ -993,15 +1020,6 @@ class TestDateParse < Test::Unit::TestCase h = Date._jisx0301('S63.02.03') assert_equal([1988, 2, 3, nil, nil, nil, nil], h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.04.30') - assert_equal([2019, 4, 30, nil, nil, nil, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.05.01') - assert_equal([2019, 5, 1, nil, nil, nil, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('R01.05.01') - assert_equal([2019, 5, 1, nil, nil, nil, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) h = Date._jisx0301('H13.02.03T04:05:06') assert_equal([2001, 2, 3, 4, 5, 6, nil], @@ -1016,47 +1034,15 @@ class TestDateParse < Test::Unit::TestCase assert_equal([2001, 2, 3, 4, 5, 6, 3600], h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.04.30T04:05:06') - assert_equal([2019, 4, 30, 4, 5, 6, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.04.30T04:05:06,07') - assert_equal([2019, 4, 30, 4, 5, 6, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.04.30T04:05:06Z') - assert_equal([2019, 4, 30, 4, 5, 6, 0], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.04.30T04:05:06.07+0100') - assert_equal([2019, 4, 30, 4, 5, 6, 3600], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - - h = Date._jisx0301('H31.05.01T04:05:06') - assert_equal([2019, 5, 1, 4, 5, 6, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.05.01T04:05:06,07') - assert_equal([2019, 5, 1, 4, 5, 6, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.05.01T04:05:06Z') - assert_equal([2019, 5, 1, 4, 5, 6, 0], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('H31.05.01T04:05:06.07+0100') - assert_equal([2019, 5, 1, 4, 5, 6, 3600], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - - h = Date._jisx0301('R01.05.01T04:05:06') - assert_equal([2019, 5, 1, 4, 5, 6, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('R01.05.01T04:05:06,07') - assert_equal([2019, 5, 1, 4, 5, 6, nil], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('R01.05.01T04:05:06Z') - assert_equal([2019, 5, 1, 4, 5, 6, 0], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('R01.05.01T04:05:06.07+0100') - assert_equal([2019, 5, 1, 4, 5, 6, 3600], - h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) - h = Date._jisx0301('') assert_equal({}, h) + + h = Date._jisx0301(nil) + assert_equal({}, h) + + h = Date._jisx0301('H13.02.03T04:05:06.07+0100'.to_sym) + assert_equal([2001, 2, 3, 4, 5, 6, 3600], + h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset)) end def test_iso8601 @@ -1140,33 +1126,9 @@ class TestDateParse < Test::Unit::TestCase assert_equal(Date.new(2001,2,3), d) assert_equal(Date::ITALY + 10, d.start) - d = Date.jisx0301('H31.04.30', Date::ITALY + 10) - assert_equal(Date.new(2019,4,30), d) - assert_equal(Date::ITALY + 10, d.start) - - d = Date.jisx0301('H31.05.01', Date::ITALY + 10) - assert_equal(Date.new(2019,5,1), d) - assert_equal(Date::ITALY + 10, d.start) - - d = Date.jisx0301('R01.05.01', Date::ITALY + 10) - assert_equal(Date.new(2019,5,1), d) - assert_equal(Date::ITALY + 10, d.start) - d = DateTime.jisx0301('H13.02.03T04:05:06+07:00', Date::ITALY + 10) assert_equal(DateTime.new(2001,2,3,4,5,6,'+07:00'), d) assert_equal(Date::ITALY + 10, d.start) - - d = DateTime.jisx0301('H31.04.30T04:05:06+07:00', Date::ITALY + 10) - assert_equal(DateTime.new(2019,4,30,4,5,6,'+07:00'), d) - assert_equal(Date::ITALY + 10, d.start) - - d = DateTime.jisx0301('H31.05.01T04:05:06+07:00', Date::ITALY + 10) - assert_equal(DateTime.new(2019,5,1,4,5,6,'+07:00'), d) - assert_equal(Date::ITALY + 10, d.start) - - d = DateTime.jisx0301('R01.05.01T04:05:06+07:00', Date::ITALY + 10) - assert_equal(DateTime.new(2019,5,1,4,5,6,'+07:00'), d) - assert_equal(Date::ITALY + 10, d.start) end def test_given_string @@ -1201,16 +1163,34 @@ class TestDateParse < Test::Unit::TestCase s0 = s.dup assert_not_equal({}, Date._jisx0301(s)) assert_equal(s0, s) - - s = 'H31.04.30T04:05:06,07Z' - s0 = s.dup - assert_not_equal({}, Date._jisx0301(s)) - assert_equal(s0, s) - - s = 'H31.05.01T04:05:06,07Z' - s0 = s.dup - assert_not_equal({}, Date._jisx0301(s)) - assert_equal(s0, s) end + def test_length_limit + assert_raise(ArgumentError) { Date._parse("1" * 1000) } + assert_raise(ArgumentError) { Date._iso8601("1" * 1000) } + assert_raise(ArgumentError) { Date._rfc3339("1" * 1000) } + assert_raise(ArgumentError) { Date._xmlschema("1" * 1000) } + assert_raise(ArgumentError) { Date._rfc2822("1" * 1000) } + assert_raise(ArgumentError) { Date._rfc822("1" * 1000) } + assert_raise(ArgumentError) { Date._jisx0301("1" * 1000) } + + assert_raise(ArgumentError) { Date.parse("1" * 1000) } + assert_raise(ArgumentError) { Date.iso8601("1" * 1000) } + assert_raise(ArgumentError) { Date.rfc3339("1" * 1000) } + assert_raise(ArgumentError) { Date.xmlschema("1" * 1000) } + assert_raise(ArgumentError) { Date.rfc2822("1" * 1000) } + assert_raise(ArgumentError) { Date.rfc822("1" * 1000) } + assert_raise(ArgumentError) { Date.jisx0301("1" * 1000) } + + assert_raise(ArgumentError) { DateTime.parse("1" * 1000) } + assert_raise(ArgumentError) { DateTime.iso8601("1" * 1000) } + assert_raise(ArgumentError) { DateTime.rfc3339("1" * 1000) } + assert_raise(ArgumentError) { DateTime.xmlschema("1" * 1000) } + assert_raise(ArgumentError) { DateTime.rfc2822("1" * 1000) } + assert_raise(ArgumentError) { DateTime.rfc822("1" * 1000) } + assert_raise(ArgumentError) { DateTime.jisx0301("1" * 1000) } + + assert_raise(ArgumentError) { Date._parse("Jan " + "9" * 1000000) } + assert_raise(Timeout::Error) { Timeout.timeout(1) { Date._parse("Jan " + "9" * 1000000, limit: nil) } } + end end diff --git a/test/date/test_date_strftime.rb b/test/date/test_date_strftime.rb index dc237a909d..a33eaa340f 100644 --- a/test/date/test_date_strftime.rb +++ b/test/date/test_date_strftime.rb @@ -406,8 +406,6 @@ class TestDateStrftime < Test::Unit::TestCase assert_equal('S64.01.07', Date.parse('1989-01-07').jisx0301) assert_equal('H01.01.08', Date.parse('1989-01-08').jisx0301) assert_equal('H18.09.01', Date.parse('2006-09-01').jisx0301) - assert_equal('H31.04.30', Date.parse('2019-04-30').jisx0301) - assert_equal('R01.05.01', Date.parse('2019-05-01').jisx0301) %w(M06.01.01 M45.07.29 @@ -416,10 +414,7 @@ class TestDateStrftime < Test::Unit::TestCase S01.12.25 S64.01.07 H01.01.08 - H18.09.01 - H31.04.30 - R01.05.01 - ).each do |s| + H18.09.01).each do |s| assert_equal(s, Date.parse(s).jisx0301) end @@ -1,10 +1,10 @@ -#define RUBY_VERSION "2.6.8" -#define RUBY_RELEASE_DATE "2021-07-07" -#define RUBY_PATCHLEVEL 205 +#define RUBY_VERSION "2.6.9" +#define RUBY_RELEASE_DATE "2021-11-24" +#define RUBY_PATCHLEVEL 206 #define RUBY_RELEASE_YEAR 2021 -#define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 7 +#define RUBY_RELEASE_MONTH 11 +#define RUBY_RELEASE_DAY 24 #include "ruby/version.h" |